From 315737ce98a4e6ff376659a8aa7c76d6c8d6e2be Mon Sep 17 00:00:00 2001 From: PhilReact Date: Tue, 18 Mar 2025 22:49:47 +0200 Subject: [PATCH] fixes --- .../ResourceList/ResourceListDisplay.tsx | 66 +++++++++++++++++-- src/hooks/useIdentifiers.tsx | 7 +- src/utils/encryption.ts | 3 +- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/components/ResourceList/ResourceListDisplay.tsx b/src/components/ResourceList/ResourceListDisplay.tsx index 1baa494..866cab8 100644 --- a/src/components/ResourceList/ResourceListDisplay.tsx +++ b/src/components/ResourceList/ResourceListDisplay.tsx @@ -21,6 +21,8 @@ import { useListStore } from "../../state/lists"; import { useScrollTracker } from "../../common/useScrollTracker"; import { HorizontalPaginatedList } from "./HorizontalPaginationList"; import { VerticalPaginatedList } from "./VerticalPaginationList"; +import { useIdentifiers } from "../../hooks/useIdentifiers"; +import { useGlobal } from "../../context/GlobalProvider"; type Direction = "VERTICAL" | "HORIZONTAL"; interface ResourceListStyles { @@ -34,6 +36,13 @@ interface ResourceListStyles { } } +interface EntityParams { + entityType: string; + parentId?: string | null; +} + + + export interface DefaultLoaderParams { listLoadingText?: string; listNoResultsText?: string; @@ -43,6 +52,7 @@ export interface DefaultLoaderParams { interface BaseProps { search: QortalSearchParams; + entityParams?: EntityParams; listItem: (item: ListItem, index: number) => React.ReactNode; styles?: ResourceListStyles; loaderItem?: (status: "LOADING" | "ERROR") => React.ReactNode; @@ -71,6 +81,7 @@ interface NonVirtualizedProps extends BaseProps { type PropsResourceListDisplay = VirtualizedProps | NonVirtualizedProps; + export const MemorizedComponent = ({ search, listItem, @@ -88,9 +99,11 @@ export const MemorizedComponent = ({ resourceCacheDuration, disablePagination, disableScrollTracker, + entityParams }: PropsResourceListDisplay) => { const { fetchResources } = useResources(); const { filterOutDeletedResources } = useCacheStore(); + const {identifierOperations} = useGlobal() const deletedResources = useCacheStore().deletedResources const memoizedParams = useMemo(() => JSON.stringify(search), [search]); const addList = useListStore().addList @@ -103,16 +116,53 @@ export const MemorizedComponent = ({ const isListExpired = useCacheStore().isListExpired(listName) const [isLoadingMore, setIsLoadingMore] = useState(false) const initialized = useRef(false) + const [generatedIdentifier, setGeneratedIdentifier] = useState("") + + + + + + const stringifiedEntityParams = useMemo(()=> { + return JSON .stringify(entityParams) + }, [entityParams]) + + + useEffect(()=> { + try { + if (!search.identifier && stringifiedEntityParams) { + const parsedEntityParams = JSON.parse(stringifiedEntityParams) + const buildSearch = async ()=> { + const res = await identifierOperations.buildSearchPrefix( + parsedEntityParams.entityType, + parsedEntityParams.parentId || null, + ) + if(res){ + setGeneratedIdentifier(res) + } + } + + + buildSearch() + return + } + setGeneratedIdentifier(search?.identifier) + } catch (error) { + console.error(error) + } + }, [stringifiedEntityParams, search.identifier, identifierOperations.buildSearchPrefix]) const getResourceList = useCallback(async () => { try { + + if(!generatedIdentifier) return await new Promise((res)=> { setTimeout(() => { res(null) }, 500); }) setIsLoading(true); - const parsedParams = JSON.parse(memoizedParams); + const parsedParams = {...(JSON.parse(memoizedParams))}; + parsedParams.identifier = generatedIdentifier const responseData = await fetchResources(parsedParams, listName, true); // Awaiting the async function @@ -124,10 +174,9 @@ export const MemorizedComponent = ({ } finally { setIsLoading(false); } - }, [memoizedParams, fetchResources]); // Added dependencies for re-fetching - + }, [memoizedParams, fetchResources, generatedIdentifier]); // Added dependencies for re-fetching useEffect(() => { - if(initialized.current) return + if(initialized.current || !generatedIdentifier) return initialized.current = true if(!isListExpired) { setIsLoading(false) @@ -136,7 +185,7 @@ export const MemorizedComponent = ({ sessionStorage.removeItem(`scroll-position-${listName}`); getResourceList(); - }, [getResourceList, isListExpired]); // Runs when dependencies change + }, [getResourceList, isListExpired, generatedIdentifier]); // Runs when dependencies change const {elementRef} = useScrollTracker(listName, list?.length > 0, disableScrollTracker); @@ -161,10 +210,12 @@ export const MemorizedComponent = ({ const getResourceMoreList = useCallback(async (displayLimit?: number) => { try { + if(!generatedIdentifier) return setIsLoadingMore(true) const parsedParams = {...(JSON.parse(memoizedParams))}; parsedParams.before = list.length === 0 ? null : list[list.length - 1]?.created parsedParams.offset = null + parsedParams.identifier = generatedIdentifier if(displayLimit){ parsedParams.limit = displayLimit } @@ -178,7 +229,7 @@ export const MemorizedComponent = ({ }, 1000); } - }, [memoizedParams, listName, list]); + }, [memoizedParams, listName, list, generatedIdentifier]); @@ -292,7 +343,8 @@ function arePropsEqual( prevProps.onSeenLastItem === nextProps.onSeenLastItem && JSON.stringify(prevProps.search) === JSON.stringify(nextProps.search) && JSON.stringify(prevProps.styles) === JSON.stringify(nextProps.styles) && - prevProps.listItem === nextProps.listItem + prevProps.listItem === nextProps.listItem && + JSON.stringify(prevProps.entityParams) === JSON.stringify(nextProps.entityParams) ); } diff --git a/src/hooks/useIdentifiers.tsx b/src/hooks/useIdentifiers.tsx index 77129a8..1aca4fa 100644 --- a/src/hooks/useIdentifiers.tsx +++ b/src/hooks/useIdentifiers.tsx @@ -1,10 +1,15 @@ -import React, { useCallback, useEffect, useMemo, useRef } from "react"; +import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useAuthStore } from "../state/auth"; import { useAppStore } from "../state/app"; import { buildIdentifier, buildSearchPrefix, IdentifierBuilder } from "../utils/encryption"; export const useIdentifiers = (builder?: IdentifierBuilder, publicSalt?: string) => { + const [publicSaltVal, setPublicSaltVal] = useState(publicSalt) + + useEffect(()=> { + setPublicSaltVal(publicSalt) + }, [publicSalt]) const setIdentifierBuilder = useAppStore().setIdentifierBuilder const identifierBuilder = useAppStore().identifierBuilder const appName = useAppStore().appName diff --git a/src/utils/encryption.ts b/src/utils/encryption.ts index 7834cca..1ebe908 100644 --- a/src/utils/encryption.ts +++ b/src/utils/encryption.ts @@ -95,8 +95,7 @@ export async function buildIdentifier( parentId: string | null, identifierBuilder: IdentifierBuilder ): Promise { - console.log("Entity Type:", entityType); // Debugging - console.log("Parent ID:", parentId); // Debugging + // Hash app name (11 chars) const appHash: string = await hashWord(appName, EnumCollisionStrength.HIGH, publicSalt);