From 69be683141cee5ef9e98839be62aa20c7a8121cb Mon Sep 17 00:00:00 2001 From: mkljczk Date: Fri, 27 Dec 2024 23:47:04 +0100 Subject: [PATCH] pl-api: embed relationship for pixelfed groups Signed-off-by: mkljczk --- packages/pl-api/lib/entities/group.ts | 9 +++ packages/pl-fe/src/entity-store/reducer.ts | 73 ++++++++++++---------- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/packages/pl-api/lib/entities/group.ts b/packages/pl-api/lib/entities/group.ts index d8bd90df9..469bfec6d 100644 --- a/packages/pl-api/lib/entities/group.ts +++ b/packages/pl-api/lib/entities/group.ts @@ -13,6 +13,15 @@ const groupSchema = v.pipe(v.any(), v.transform((group: any) => { display_name: group.name, members_count: group.member_count, note: group.short_description, + relationship: group.self ? { + ...group.self, + member: group.self.is_member, + role: { + founder: 'owner', + admin: 'admin', + }[group.self.role as string] || 'user', + id: group.id, + } : null, ...group, }; } diff --git a/packages/pl-fe/src/entity-store/reducer.ts b/packages/pl-fe/src/entity-store/reducer.ts index a5a49a818..66e16667d 100644 --- a/packages/pl-fe/src/entity-store/reducer.ts +++ b/packages/pl-fe/src/entity-store/reducer.ts @@ -1,4 +1,4 @@ -import { create, type Immutable } from 'mutative'; +import { create, type Immutable, type Draft } from 'mutative'; import { ENTITIES_IMPORT, @@ -7,14 +7,15 @@ import { ENTITIES_FETCH_REQUEST, ENTITIES_FETCH_SUCCESS, ENTITIES_FETCH_FAIL, - EntityAction, ENTITIES_INVALIDATE_LIST, ENTITIES_INCREMENT, ENTITIES_TRANSACTION, + type EntityAction, + type DeleteEntitiesOpts, } from './actions'; +import { Entities } from './entities'; import { createCache, createList, updateStore, updateList } from './utils'; -import type { DeleteEntitiesOpts } from './actions'; import type { EntitiesTransaction, Entity, EntityCache, EntityListState, ImportPosition } from './types'; /** Entity reducer state. */ @@ -24,14 +25,14 @@ type State = Immutable<{ /** Import entities into the cache. */ const importEntities = ( - state: State, + draft: Draft, entityType: string, entities: Entity[], listKey?: string, pos?: ImportPosition, newState?: EntityListState, overwrite = false, -): State => create(state, draft => { +) => { const cache = draft[entityType] ?? createCache(); cache.store = updateStore(cache.store, entities); @@ -53,15 +54,23 @@ const importEntities = ( draft[entityType] = cache; - return draft; -}, { enableAutoFreeze: true }); + if (entityType === Entities.GROUPS) { + importEntities( + draft, + Entities.GROUP_RELATIONSHIPS, + entities.map((entity: any) => entity?.relationship).filter((relationship: any) => relationship), + listKey, + pos, + ); + } +}; const deleteEntities = ( - state: State, + draft: Draft, entityType: string, ids: Iterable, opts: DeleteEntitiesOpts, -) => create(state, draft => { +) => { const cache = draft[entityType] ?? createCache(); for (const id of ids) { @@ -81,14 +90,14 @@ const deleteEntities = ( } draft[entityType] = cache; -}); +}; const dismissEntities = ( - state: State, + draft: Draft, entityType: string, ids: Iterable, listKey: string, -) => create(state, draft => { +) => { const cache = draft[entityType] ?? createCache(); const list = cache.lists[listKey]; @@ -103,14 +112,14 @@ const dismissEntities = ( draft[entityType] = cache; } -}); +}; const incrementEntities = ( - state: State, + draft: Draft, entityType: string, listKey: string, diff: number, -) => create(state, draft => { +) => { const cache = draft[entityType] ?? createCache(); const list = cache.lists[listKey]; @@ -118,15 +127,15 @@ const incrementEntities = ( list.state.totalCount += diff; draft[entityType] = cache; } -}); +}; const setFetching = ( - state: State, + draft: Draft, entityType: string, listKey: string | undefined, isFetching: boolean, error?: any, -) => create(state, draft => { +) => { const cache = draft[entityType] ?? createCache(); if (typeof listKey === 'string') { @@ -137,15 +146,15 @@ const setFetching = ( } draft[entityType] = cache; -}); +}; -const invalidateEntityList = (state: State, entityType: string, listKey: string) => create(state, draft => { +const invalidateEntityList = (draft: Draft, entityType: string, listKey: string) => { const cache = draft[entityType] ?? createCache(); const list = cache.lists[listKey] ?? createList(); list.state.invalid = true; -}); +}; -const doTransaction = (state: State, transaction: EntitiesTransaction) => create(state, draft => { +const doTransaction = (draft: Draft, transaction: EntitiesTransaction) => { for (const [entityType, changes] of Object.entries(transaction)) { const cache = draft[entityType] ?? createCache(); for (const [id, change] of Object.entries(changes)) { @@ -155,29 +164,29 @@ const doTransaction = (state: State, transaction: EntitiesTransaction) => create } } } -}); +}; /** Stores various entity data and lists in a one reducer. */ const reducer = (state: Readonly = {}, action: EntityAction): State => { switch (action.type) { case ENTITIES_IMPORT: - return importEntities(state, action.entityType, action.entities, action.listKey, action.pos); + return create(state, draft => importEntities(draft, action.entityType, action.entities, action.listKey, action.pos), { enableAutoFreeze: true }); case ENTITIES_DELETE: - return deleteEntities(state, action.entityType, action.ids, action.opts); + return create(state, draft => deleteEntities(draft, action.entityType, action.ids, action.opts)); case ENTITIES_DISMISS: - return dismissEntities(state, action.entityType, action.ids, action.listKey); + return create(state, draft => dismissEntities(draft, action.entityType, action.ids, action.listKey)); case ENTITIES_INCREMENT: - return incrementEntities(state, action.entityType, action.listKey, action.diff); + return create(state, draft => incrementEntities(draft, action.entityType, action.listKey, action.diff)); case ENTITIES_FETCH_SUCCESS: - return importEntities(state, action.entityType, action.entities, action.listKey, action.pos, action.newState, action.overwrite); + return create(state, draft => importEntities(draft, action.entityType, action.entities, action.listKey, action.pos, action.newState, action.overwrite), { enableAutoFreeze: true }); case ENTITIES_FETCH_REQUEST: - return setFetching(state, action.entityType, action.listKey, true); + return create(state, draft => setFetching(draft, action.entityType, action.listKey, true)); case ENTITIES_FETCH_FAIL: - return setFetching(state, action.entityType, action.listKey, false, action.error); + return create(state, draft => setFetching(draft, action.entityType, action.listKey, false, action.error)); case ENTITIES_INVALIDATE_LIST: - return invalidateEntityList(state, action.entityType, action.listKey); + return create(state, draft => invalidateEntityList(draft, action.entityType, action.listKey)); case ENTITIES_TRANSACTION: - return doTransaction(state, action.transaction); + return create(state, draft => doTransaction(draft, action.transaction)); default: return state; }