mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
refactor list scroll persistence to use store instead of browser state
This commit is contained in:
@@ -1,26 +1,29 @@
|
|||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useSearchParams } from 'react-router';
|
import { useLocation, useNavigationType } from 'react-router';
|
||||||
|
|
||||||
import { parseIntParam, setSearchParam } from '/@/renderer/utils/query-params';
|
import { useScrollStore } from '/@/renderer/store/scroll.store';
|
||||||
|
|
||||||
interface UseItemListScrollPersistProps {
|
interface UseItemListScrollPersistProps {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useItemListScrollPersist = ({ enabled }: UseItemListScrollPersistProps) => {
|
export const useItemListScrollPersist = ({ enabled }: UseItemListScrollPersistProps) => {
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const location = useLocation();
|
||||||
|
const navigationType = useNavigationType();
|
||||||
|
const setOffset = useScrollStore((s) => s.setOffset);
|
||||||
|
const getOffset = useScrollStore((s) => s.getOffset);
|
||||||
|
|
||||||
const scrollOffset = useMemo(() => parseIntParam(searchParams, 'scrollOffset'), [searchParams]);
|
const scrollOffset = useMemo(() => {
|
||||||
|
if (navigationType !== 'POP') return undefined;
|
||||||
|
return getOffset(location.key);
|
||||||
|
}, [getOffset, location.key, navigationType]);
|
||||||
|
|
||||||
const handleOnScrollEnd = useCallback(
|
const handleOnScrollEnd = useCallback(
|
||||||
(offset: number) => {
|
(offset: number) => {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
|
setOffset(location.key, offset);
|
||||||
setSearchParams((prev) => setSearchParam(prev, 'scrollOffset', offset), {
|
|
||||||
replace: true,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
[enabled, setSearchParams],
|
[enabled, location.key, setOffset],
|
||||||
);
|
);
|
||||||
|
|
||||||
return { handleOnScrollEnd, scrollOffset };
|
return { handleOnScrollEnd, scrollOffset };
|
||||||
|
|||||||
@@ -2,5 +2,6 @@ export * from './app.store';
|
|||||||
export * from './auth.store';
|
export * from './auth.store';
|
||||||
export * from './full-screen-player.store';
|
export * from './full-screen-player.store';
|
||||||
export * from './player.store';
|
export * from './player.store';
|
||||||
|
export * from './scroll.store';
|
||||||
export * from './settings.store';
|
export * from './settings.store';
|
||||||
export * from './timestamp.store';
|
export * from './timestamp.store';
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
type ScrollState = {
|
||||||
|
getOffset: (key: string) => number | undefined;
|
||||||
|
offsets: Record<string, number>;
|
||||||
|
setOffset: (key: string, offset: number) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useScrollStore = create<ScrollState>((set, get) => ({
|
||||||
|
getOffset: (key) => get().offsets[key],
|
||||||
|
offsets: {},
|
||||||
|
setOffset: (key, offset) =>
|
||||||
|
set((s) => ({
|
||||||
|
offsets: { ...s.offsets, [key]: offset },
|
||||||
|
})),
|
||||||
|
}));
|
||||||
Reference in New Issue
Block a user