diff --git a/app/soapbox/entity-store/actions.ts b/app/soapbox/entity-store/actions.ts index 59a1afee84..e09191f87d 100644 --- a/app/soapbox/entity-store/actions.ts +++ b/app/soapbox/entity-store/actions.ts @@ -1,6 +1,9 @@ import type { Entity } from './types'; -const ENTITIES_IMPORT = 'ENTITIES_IMPORT'; +const ENTITIES_IMPORT = 'ENTITIES_IMPORT' as const; +const ENTITIES_FETCH_REQUEST = 'ENTITIES_FETCH_REQUEST' as const; +const ENTITIES_FETCH_SUCCESS = 'ENTITIES_FETCH_SUCCESS' as const; +const ENTITIES_FETCH_FAIL = 'ENTITIES_FETCH_FAIL' as const; /** Action to import entities into the cache. */ function importEntities(entities: Entity[], entityType: string, listKey?: string) { @@ -12,11 +15,46 @@ function importEntities(entities: Entity[], entityType: string, listKey?: string }; } +function entitiesFetchRequest(entityType: string, listKey?: string) { + return { + type: ENTITIES_FETCH_REQUEST, + entityType, + listKey, + }; +} + +function entitiesFetchSuccess(entities: Entity[], entityType: string, listKey?: string) { + return { + type: ENTITIES_FETCH_SUCCESS, + entityType, + entities, + listKey, + }; +} + +function entitiesFetchFail(entityType: string, listKey?: string) { + return { + type: ENTITIES_FETCH_FAIL, + entityType, + listKey, + }; +} + /** Any action pertaining to entities. */ -type EntityAction = ReturnType; +type EntityAction = + ReturnType + | ReturnType + | ReturnType + | ReturnType; export { ENTITIES_IMPORT, + ENTITIES_FETCH_REQUEST, + ENTITIES_FETCH_SUCCESS, + ENTITIES_FETCH_FAIL, importEntities, + entitiesFetchRequest, + entitiesFetchSuccess, + entitiesFetchFail, EntityAction, }; \ No newline at end of file diff --git a/app/soapbox/entity-store/reducer.ts b/app/soapbox/entity-store/reducer.ts index a9b01b84be..c588fd3ea1 100644 --- a/app/soapbox/entity-store/reducer.ts +++ b/app/soapbox/entity-store/reducer.ts @@ -1,6 +1,12 @@ import produce, { enableMapSet } from 'immer'; -import { EntityAction, ENTITIES_IMPORT } from './actions'; +import { + ENTITIES_IMPORT, + ENTITIES_FETCH_REQUEST, + ENTITIES_FETCH_SUCCESS, + ENTITIES_FETCH_FAIL, + EntityAction, +} from './actions'; import { createCache, createList, updateStore, updateList } from './utils'; import type { Entity, EntityCache } from './types'; @@ -30,11 +36,35 @@ const importEntities = ( }); }; +const setFetching = ( + state: State, + entityType: string, + listKey: string | undefined, + isFetching: boolean, +) => { + return produce(state, draft => { + const cache = draft.get(entityType) ?? createCache(); + + if (listKey) { + const list = cache.lists.get(listKey) ?? createList(); + list.state.fetching = isFetching; + cache.lists.set(listKey, list); + } + + return draft.set(entityType, cache); + }); +}; + /** Stores various entity data and lists in a one reducer. */ function reducer(state: Readonly = new Map(), action: EntityAction): State { switch (action.type) { case ENTITIES_IMPORT: + case ENTITIES_FETCH_SUCCESS: return importEntities(state, action.entityType, action.entities, action.listKey); + case ENTITIES_FETCH_REQUEST: + return setFetching(state, action.entityType, action.listKey, true); + case ENTITIES_FETCH_FAIL: + return setFetching(state, action.entityType, action.listKey, false); default: return state; }