Restore virtuoso states on browser back navigation

- manga chapter list
- library duplicates
- updates
- history
- download queue
This commit is contained in:
schroda
2025-05-25 15:36:25 +02:00
parent 5f982e07e0
commit c3b22f92a9
13 changed files with 209 additions and 82 deletions

View File

@@ -6,7 +6,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { useCallback, useMemo } from 'react';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { useLocation } from 'react-router-dom';
import { useSessionStorage } from '@/modules/core/hooks/useStorage.tsx';
import { AppStorage } from '@/lib/storage/AppStorage.ts';
export class VirtuosoUtil {
static readonly GROUP = 0;
@@ -112,4 +115,46 @@ export class VirtuosoUtil {
[convertIndex, getGroupKey, getNormalKey],
);
}
static usePersistState<Snapshot>(key: string): {
key: string;
state: Snapshot | undefined;
persistState: (state: Snapshot) => void;
deleteState: () => void;
} {
const location = useLocation<{ snapshot?: Snapshot }>();
const snapshotSessionKey = `virtuoso-snapshot-${key}-${location.key}`;
const [snapshot] = useSessionStorage<Snapshot | undefined>(snapshotSessionKey, undefined);
const persistGridStateTimeout = useRef<NodeJS.Timeout | undefined>(undefined);
const persistState = useCallback(
(state: Snapshot) => {
const currentUrl = window.location.href;
clearTimeout(persistGridStateTimeout.current);
persistGridStateTimeout.current = setTimeout(() => {
const didLocationChange = currentUrl !== window.location.href;
if (didLocationChange) {
return;
}
AppStorage.session.setItem(snapshotSessionKey, state, false);
}, 250);
},
[snapshotSessionKey],
);
const deleteState = useCallback(() => {
AppStorage.session.setItem(snapshotSessionKey, undefined, false);
}, [snapshotSessionKey]);
useEffect(() => clearTimeout(persistGridStateTimeout.current), [location.key, persistGridStateTimeout.current]);
return {
key: snapshotSessionKey,
state: snapshot,
persistState,
deleteState,
};
}
}