mirror of https://github.com/stashapp/stash.git
Maintain filter parameters in session (#326)
This commit is contained in:
parent
690596aa34
commit
4e5c65f90d
|
@ -1,6 +1,6 @@
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
import { ApolloError } from "apollo-client";
|
import { ApolloError } from "apollo-client";
|
||||||
import { useHistory, useLocation } from "react-router-dom";
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
|
@ -16,6 +16,7 @@ import {
|
||||||
FindStudiosQueryResult,
|
FindStudiosQueryResult,
|
||||||
FindPerformersQueryResult
|
FindPerformersQueryResult
|
||||||
} from "src/core/generated-graphql";
|
} from "src/core/generated-graphql";
|
||||||
|
import { useInterfaceLocalForage } from 'src/hooks/LocalForage';
|
||||||
import { LoadingIndicator } from "src/components/Shared";
|
import { LoadingIndicator } from "src/components/Shared";
|
||||||
import { ListFilter } from "src/components/List/ListFilter";
|
import { ListFilter } from "src/components/List/ListFilter";
|
||||||
import { Pagination } from "src/components/List/Pagination";
|
import { Pagination } from "src/components/List/Pagination";
|
||||||
|
@ -74,6 +75,8 @@ interface IQuery<T extends IQueryResult, T2 extends IDataItem> {
|
||||||
const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||||
options: IListHookOptions<QueryResult> & IQuery<QueryResult, QueryData>
|
options: IListHookOptions<QueryResult> & IQuery<QueryResult, QueryData>
|
||||||
): IListHookData => {
|
): IListHookData => {
|
||||||
|
const [interfaceForage, setInterfaceForage] = useInterfaceLocalForage();
|
||||||
|
const forageInitialised = useRef(false);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [filter, setFilter] = useState<ListFilterModel>(
|
const [filter, setFilter] = useState<ListFilterModel>(
|
||||||
|
@ -90,14 +93,56 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||||
const totalCount = options.getCount(result);
|
const totalCount = options.getCount(result);
|
||||||
const items = options.getData(result);
|
const items = options.getData(result);
|
||||||
|
|
||||||
useEffect(() => (
|
useEffect(() => {
|
||||||
setFilter(
|
if(!forageInitialised.current && !interfaceForage.loading) {
|
||||||
new ListFilterModel(
|
forageInitialised.current = true;
|
||||||
|
|
||||||
|
// Don't use query parameters for sub-components
|
||||||
|
if(options.subComponent)
|
||||||
|
return;
|
||||||
|
// Don't read localForage if page already had query parameters
|
||||||
|
if(history.location.search)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const queryData = interfaceForage.data?.queries[options.filterMode];
|
||||||
|
if(!queryData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const newFilter = new ListFilterModel(
|
||||||
options.filterMode,
|
options.filterMode,
|
||||||
options.subComponent ? "" : queryString.parse(location.search)
|
queryString.parse(queryData.filter)
|
||||||
)
|
);
|
||||||
)
|
newFilter.currentPage = queryData.currentPage;
|
||||||
), [location, options.filterMode, options.subComponent]);
|
newFilter.itemsPerPage = queryData.itemsPerPage;
|
||||||
|
|
||||||
|
const newLocation = { ...history.location };
|
||||||
|
newLocation.search = queryData.filter;
|
||||||
|
history.replace(newLocation);
|
||||||
|
}
|
||||||
|
}, [interfaceForage.data, interfaceForage.loading, history, options.subComponent, options.filterMode]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(options.subComponent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const newFilter = new ListFilterModel(
|
||||||
|
options.filterMode,
|
||||||
|
options.subComponent ? "" : queryString.parse(location.search)
|
||||||
|
);
|
||||||
|
setFilter(newFilter);
|
||||||
|
|
||||||
|
if(forageInitialised.current) {
|
||||||
|
setInterfaceForage((d) => {
|
||||||
|
const dataClone = _.cloneDeep(d);
|
||||||
|
dataClone!.queries[options.filterMode] = {
|
||||||
|
filter: location.search,
|
||||||
|
itemsPerPage: newFilter.itemsPerPage,
|
||||||
|
currentPage: newFilter.currentPage
|
||||||
|
};
|
||||||
|
return dataClone;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [location, options.filterMode, options.subComponent, setInterfaceForage]);
|
||||||
|
|
||||||
function getFilter() {
|
function getFilter() {
|
||||||
if (!options.filterHook) {
|
if (!options.filterHook) {
|
||||||
|
|
|
@ -1,22 +1,26 @@
|
||||||
import localForage from "localforage";
|
import localForage from "localforage";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React from "react";
|
import React, { Dispatch, SetStateAction } from "react";
|
||||||
|
|
||||||
interface IInterfaceWallConfig {}
|
interface IInterfaceWallConfig {}
|
||||||
export interface IInterfaceConfig {
|
export interface IInterfaceConfig {
|
||||||
wall: IInterfaceWallConfig;
|
wall: IInterfaceWallConfig;
|
||||||
|
queries: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidTypes = IInterfaceConfig | undefined;
|
type ValidTypes = IInterfaceConfig | undefined;
|
||||||
|
|
||||||
interface ILocalForage<T> {
|
interface ILocalForage<T> {
|
||||||
data: T;
|
data: T;
|
||||||
setData: React.Dispatch<React.SetStateAction<T>>;
|
setData: Dispatch<SetStateAction<T>>;
|
||||||
error: Error | null;
|
error: Error | null;
|
||||||
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function useLocalForage(item: string): ILocalForage<ValidTypes> {
|
function useLocalForage(item: string): ILocalForage<ValidTypes> {
|
||||||
const [json, setJson] = React.useState<ValidTypes>(undefined);
|
const [json, setJson] = React.useState<ValidTypes>(undefined);
|
||||||
|
const [err, setErr] = React.useState(null);
|
||||||
|
const [loaded, setLoaded] = React.useState<boolean>(false);
|
||||||
|
|
||||||
const prevJson = React.useRef<ValidTypes>(undefined);
|
const prevJson = React.useRef<ValidTypes>(undefined);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
@ -29,7 +33,6 @@ function useLocalForage(item: string): ILocalForage<ValidTypes> {
|
||||||
runAsync();
|
runAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
const [err, setErr] = React.useState(null);
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
async function runAsync() {
|
async function runAsync() {
|
||||||
try {
|
try {
|
||||||
|
@ -42,26 +45,27 @@ function useLocalForage(item: string): ILocalForage<ValidTypes> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setErr(error);
|
setErr(error);
|
||||||
}
|
}
|
||||||
|
setLoaded(true);
|
||||||
}
|
}
|
||||||
runAsync();
|
runAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
return { data: json, setData: setJson, error: err };
|
return {data: json, setData: setJson, error: err, loading: !loaded};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useInterfaceLocalForage(): ILocalForage<
|
export function useInterfaceLocalForage(): [ILocalForage<IInterfaceConfig | undefined>, Dispatch<SetStateAction<IInterfaceConfig | undefined>>] {
|
||||||
IInterfaceConfig | undefined
|
|
||||||
> {
|
|
||||||
const result = useLocalForage("interface");
|
const result = useLocalForage("interface");
|
||||||
// Set defaults
|
|
||||||
React.useEffect(() => {
|
let returnVal = result;
|
||||||
if (result.data === undefined) {
|
if(!result.data?.queries) {
|
||||||
result.setData({
|
returnVal = {
|
||||||
wall: {
|
...result,
|
||||||
// nothing here currently
|
data: {
|
||||||
}
|
wall: {},
|
||||||
});
|
queries: {}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
return result;
|
}
|
||||||
|
|
||||||
|
return [returnVal, result.setData];;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue