diff --git a/app/soapbox/entity-store/hooks/useEntities.ts b/app/soapbox/entity-store/hooks/useEntities.ts index c16abf69b..ee64d6437 100644 --- a/app/soapbox/entity-store/hooks/useEntities.ts +++ b/app/soapbox/entity-store/hooks/useEntities.ts @@ -1,3 +1,5 @@ +import { useEffect } from 'react'; + import { getNextLink, getPrevLink } from 'soapbox/api'; import { useApi, useAppDispatch, useAppSelector } from 'soapbox/hooks'; @@ -17,6 +19,11 @@ type EntityPath = [ interface UseEntitiesOpts { /** A parser function that returns the desired type, or undefined if validation fails. */ parser?: (entity: unknown) => TEntity | undefined + /** + * Time (milliseconds) until this query becomes stale and should be refetched. + * It is 1 minute by default, and can be set to `Infinity` to opt-out of automatic fetching. + */ + staleTime?: number } /** A hook for fetching and displaying API entities. */ @@ -65,6 +72,7 @@ function useEntities( prev: getPrevLink(response), fetching: false, error: null, + lastFetchedAt: new Date(), })); } catch (error) { dispatch(entitiesFetchFail(entityType, listKey, error)); @@ -91,6 +99,15 @@ function useEntities( } }; + const staleTime = opts.staleTime ?? 60000; + const lastFetchedAt = list?.state.lastFetchedAt; + + useEffect(() => { + if (!isFetching && (!lastFetchedAt || lastFetchedAt.getTime() + staleTime <= Date.now())) { + fetchEntities(); + } + }, [endpoint]); + return { entities, fetchEntities, diff --git a/app/soapbox/entity-store/types.ts b/app/soapbox/entity-store/types.ts index 4e7120120..efec97df1 100644 --- a/app/soapbox/entity-store/types.ts +++ b/app/soapbox/entity-store/types.ts @@ -27,6 +27,8 @@ interface EntityListState { error: any /** Whether data for this list is currently being fetched. */ fetching: boolean + /** Date of the last API fetch for this list. */ + lastFetchedAt: Date | undefined } /** Cache data pertaining to a paritcular entity type.. */ diff --git a/app/soapbox/entity-store/utils.ts b/app/soapbox/entity-store/utils.ts index fcff11a3e..22e0f0c5b 100644 --- a/app/soapbox/entity-store/utils.ts +++ b/app/soapbox/entity-store/utils.ts @@ -31,6 +31,7 @@ const createList = (): EntityList => ({ prev: undefined, fetching: false, error: null, + lastFetchedAt: undefined, }, });