mirror of
https://github.com/Qortal/qapp-core.git
synced 2025-06-14 17:41:20 +00:00
fix scrollto
This commit is contained in:
parent
6105a36ea2
commit
d0c871d22b
@ -19,7 +19,7 @@ interface PropsVirtualizedList {
|
||||
}
|
||||
export const VirtualizedList = ({ list, children, onSeenLastItem, listName }: PropsVirtualizedList) => {
|
||||
const parentRef = useRef(null);
|
||||
useScrollTrackerRef(listName, parentRef)
|
||||
useScrollTrackerRef(listName, list?.length > 0, parentRef)
|
||||
|
||||
const rowVirtualizer = useVirtualizer({
|
||||
count: list.length,
|
||||
|
@ -26,10 +26,11 @@ export const useScrollTracker = (listName: string, hasList: boolean, disableScro
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => {
|
||||
if(!disableScrollTracker){
|
||||
sessionStorage.setItem(SCROLL_KEY, scrollPositionRef.current.toString());
|
||||
window.removeEventListener("scroll", handleScroll);
|
||||
}
|
||||
};
|
||||
}, [listName, hasList, disableScrollTracker]);
|
||||
|
||||
|
@ -1,30 +1,49 @@
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
export const useScrollTrackerRef = (listName: string, ref: React.RefObject<HTMLElement | null>) => {
|
||||
export const useScrollTrackerRef = (listName: string, hasList: boolean, scrollerRef: React.RefObject<HTMLElement | null> | undefined) => {
|
||||
const [hasMounted, setHasMounted] = useState(false)
|
||||
const hasScrollRef = useRef(false)
|
||||
useEffect(() => {
|
||||
if (!listName || !ref.current) return;
|
||||
if (!listName || !scrollerRef?.current || !hasMounted) return;
|
||||
|
||||
const SCROLL_KEY = `scroll-position-${listName}`;
|
||||
const handleScroll = () => {
|
||||
if(!scrollerRef.current) return
|
||||
sessionStorage.setItem(SCROLL_KEY, scrollerRef.current.scrollTop.toString());
|
||||
};
|
||||
|
||||
scrollerRef.current.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => {
|
||||
if (scrollerRef.current) {
|
||||
scrollerRef.current.removeEventListener("scroll", handleScroll);
|
||||
}
|
||||
};
|
||||
}, [listName, hasMounted]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!listName || !hasList || hasScrollRef.current || !scrollerRef?.current) return;
|
||||
const SCROLL_KEY = `scroll-position-${listName}`;
|
||||
const savedPosition = sessionStorage.getItem(SCROLL_KEY);
|
||||
|
||||
const attemptScrollRestore = () => {
|
||||
const el = scrollerRef.current;
|
||||
const saved = parseInt(savedPosition || '0', 10);
|
||||
if (!el) return;
|
||||
if (el.scrollHeight > el.clientHeight && saved <= el.scrollHeight - el.clientHeight) {
|
||||
|
||||
if (savedPosition && ref.current) {
|
||||
ref.current.scrollTop = parseInt(savedPosition, 10);
|
||||
setTimeout(() => {
|
||||
el.scrollTop = saved;
|
||||
}, 200);
|
||||
setHasMounted(true)
|
||||
hasScrollRef.current = true;
|
||||
} else {
|
||||
requestAnimationFrame(attemptScrollRestore);
|
||||
}
|
||||
|
||||
|
||||
const handleScroll = () => {
|
||||
if (ref.current) {
|
||||
sessionStorage.setItem(SCROLL_KEY, ref.current.scrollTop.toString());
|
||||
}
|
||||
};
|
||||
|
||||
ref.current.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => {
|
||||
if (ref.current) {
|
||||
ref.current.removeEventListener("scroll", handleScroll);
|
||||
}
|
||||
};
|
||||
}, [listName, ref]);
|
||||
requestAnimationFrame(attemptScrollRestore);
|
||||
}, [listName, hasList]);
|
||||
};
|
@ -24,6 +24,7 @@ import { HorizontalPaginatedList } from "./HorizontalPaginationList";
|
||||
import { VerticalPaginatedList } from "./VerticalPaginationList";
|
||||
import { useIdentifiers } from "../../hooks/useIdentifiers";
|
||||
import { useGlobal } from "../../context/GlobalProvider";
|
||||
import { useScrollTrackerRef } from "../../common/useScrollTrackerRef";
|
||||
type Direction = "VERTICAL" | "HORIZONTAL";
|
||||
|
||||
interface ResourceListStyles {
|
||||
@ -82,6 +83,7 @@ interface BaseProps {
|
||||
}
|
||||
onNewData?: (hasNewData: boolean) => void;
|
||||
ref?: any
|
||||
scrollerRef?: React.RefObject<HTMLElement | null>
|
||||
}
|
||||
|
||||
// ✅ Restrict `direction` only when `disableVirtualization = false`
|
||||
@ -121,7 +123,8 @@ export const MemorizedComponent = ({
|
||||
onResults,
|
||||
searchNewData,
|
||||
onNewData,
|
||||
ref
|
||||
ref,
|
||||
scrollerRef
|
||||
}: PropsResourceListDisplay) => {
|
||||
const {identifierOperations, lists} = useGlobal()
|
||||
const memoizedParams = useMemo(() => JSON.stringify(search), [search]);
|
||||
@ -271,22 +274,19 @@ const addItems = useListStore((s) => s.addItems);
|
||||
const parsedParams = {...(JSON.parse(memoizedParamsRef.current))};
|
||||
parsedParams.identifier = generatedIdentifier
|
||||
const stringedParams = JSON.stringify(parsedParams)
|
||||
|
||||
if(stringedParams === isListExpiredRef.current && !initialized.current){
|
||||
if(stringedParams === isListExpiredRef.current){
|
||||
setIsLoading(false)
|
||||
initialized.current = true
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sessionStorage.removeItem(`scroll-position-${listName}`);
|
||||
prevGeneratedIdentifierRef.current = generatedIdentifier
|
||||
getResourceList();
|
||||
}, [getResourceList, generatedIdentifier]); // Runs when dependencies change
|
||||
|
||||
const {elementRef} = useScrollTracker(listName, list?.length > 0, disableScrollTracker);
|
||||
|
||||
const {elementRef} = useScrollTracker(listName, list?.length > 0, scrollerRef ? true : !disableVirtualization ? true : disableScrollTracker);
|
||||
useScrollTrackerRef(listName, list?.length > 0, scrollerRef)
|
||||
const setSearchCacheExpiryDuration = useCacheStore((s) => s.setSearchCacheExpiryDuration);
|
||||
const setResourceCacheExpiryDuration = useCacheStore((s) => s.setResourceCacheExpiryDuration);
|
||||
|
||||
|
@ -240,7 +240,7 @@ export const useResources = (retryAttempts: number = 2) => {
|
||||
if (!lastCreated) break;
|
||||
}
|
||||
|
||||
setSearchCache(listName, cacheKey, filteredResults, JSON.stringify(params));
|
||||
setSearchCache(listName, cacheKey, filteredResults, cancelRequests ? JSON.stringify(params) : null);
|
||||
fetchDataFromResults(filteredResults, returnType);
|
||||
|
||||
return filteredResults;
|
||||
|
@ -56,7 +56,7 @@ interface CacheState {
|
||||
// Search cache actions
|
||||
setResourceCache: (id: string, data: ListItem | false | null, customExpiry?: number) => void;
|
||||
|
||||
setSearchCache: (listName: string, searchTerm: string, data: QortalMetadata[], searchParamsStringified: string, customExpiry?: number) => void;
|
||||
setSearchCache: (listName: string, searchTerm: string, data: QortalMetadata[], searchParamsStringified: string | null, customExpiry?: number) => void;
|
||||
getSearchCache: (listName: string, searchTerm: string) => QortalMetadata[] | null;
|
||||
clearExpiredCache: () => void;
|
||||
getResourceCache: (id: string, ignoreExpire?: boolean) => ListItem | false | null;
|
||||
@ -122,7 +122,7 @@ export const useCacheStore = create<CacheState>
|
||||
},
|
||||
temporaryNewResources: state.searchCache[listName]?.temporaryNewResources || [],
|
||||
expiry,
|
||||
searchParamsStringified
|
||||
searchParamsStringified: searchParamsStringified === null ? state.searchCache[listName]?.searchParamsStringified : searchParamsStringified
|
||||
},
|
||||
},
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user