diff --git a/packages/pl-fe/src/actions/importer.ts b/packages/pl-fe/src/actions/importer.ts index e0a8251df..f1e922f0d 100644 --- a/packages/pl-fe/src/actions/importer.ts +++ b/packages/pl-fe/src/actions/importer.ts @@ -10,6 +10,7 @@ import type { Poll as BasePoll, Relationship as BaseRelationship, Status as BaseStatus, + GroupRelationship, } from 'pl-api'; const STATUS_IMPORT = 'STATUS_IMPORT' as const; @@ -112,7 +113,10 @@ const importEntities = for (const group of Object.values(groups)) { queryClient.setQueryData(['groups', group.id], group); if (group.relationship) { - queryClient.setQueryData(['groupRelationships', group.id], group.relationship); + queryClient.setQueryData( + ['groupRelationships', group.id], + group.relationship, + ); } } if (!isEmpty(polls)) { diff --git a/packages/pl-fe/src/components/status.tsx b/packages/pl-fe/src/components/status.tsx index 05fa45847..ce1a34b1a 100644 --- a/packages/pl-fe/src/components/status.tsx +++ b/packages/pl-fe/src/components/status.tsx @@ -14,6 +14,7 @@ import StatusTypeIcon from '@/features/status/components/status-type-icon'; import { Hotkeys } from '@/features/ui/components/hotkeys'; import { useAppDispatch } from '@/hooks/use-app-dispatch'; import { useAppSelector } from '@/hooks/use-app-selector'; +import { useGroupQuery } from '@/queries/groups/use-group'; import { useFollowedTags } from '@/queries/hashtags/use-followed-tags'; import { useFavouriteStatus, diff --git a/packages/pl-fe/src/components/thumb-navigation.tsx b/packages/pl-fe/src/components/thumb-navigation.tsx index ed0d45591..459531122 100644 --- a/packages/pl-fe/src/components/thumb-navigation.tsx +++ b/packages/pl-fe/src/components/thumb-navigation.tsx @@ -1,3 +1,4 @@ +import { useQueryClient } from '@tanstack/react-query'; import { useMatch } from '@tanstack/react-router'; import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; @@ -6,7 +7,6 @@ import { groupComposeModal } from '@/actions/compose'; import ThumbNavigationLink from '@/components/thumb-navigation-link'; import Icon from '@/components/ui/icon'; import { useStatContext } from '@/contexts/stat-context'; -import { Entities } from '@/entity-store/entities'; import { layouts } from '@/features/ui/router'; import { useAppDispatch } from '@/hooks/use-app-dispatch'; import { useAppSelector } from '@/hooks/use-app-selector'; @@ -16,6 +16,8 @@ import { useModalsActions } from '@/stores/modals'; import { useIsSidebarOpen, useUiStoreActions } from '@/stores/ui'; import { isStandalone } from '@/utils/state'; +import type { Group } from 'pl-api'; + const messages = defineMessages({ home: { id: 'column.home', defaultMessage: 'Home' }, search: { id: 'column.search', defaultMessage: 'Search' }, @@ -31,6 +33,7 @@ const ThumbNavigation: React.FC = React.memo((): JSX.Element => { const dispatch = useAppDispatch(); const { account } = useOwnAccount(); const features = useFeatures(); + const queryClient = useQueryClient(); const match = useMatch({ from: layouts.group.id, shouldThrow: false }); @@ -45,7 +48,7 @@ const ThumbNavigation: React.FC = React.memo((): JSX.Element => { const handleOpenComposeModal = () => { if (match?.params.groupId) { dispatch((_, getState) => { - const group = getState().entities[Entities.GROUPS]?.store[match.params.groupId]; + const group = queryClient.getQueryData(['groups', match.params.groupId]); if (group) dispatch(groupComposeModal(group)); }); } else { diff --git a/packages/pl-fe/src/entity-store/actions.ts b/packages/pl-fe/src/entity-store/actions.ts index 5b4f71397..6d4157b98 100644 --- a/packages/pl-fe/src/entity-store/actions.ts +++ b/packages/pl-fe/src/entity-store/actions.ts @@ -1,37 +1,14 @@ import type { Entities } from './entities'; -import type { EntitiesTransaction, Entity, ImportPosition } from './types'; +import type { EntitiesTransaction, Entity } from './types'; const ENTITIES_IMPORT = 'ENTITIES_IMPORT' as const; -const ENTITIES_DELETE = 'ENTITIES_DELETE' as const; const ENTITIES_TRANSACTION = 'ENTITIES_TRANSACTION' as const; /** Action to import entities into the cache. */ -const importEntities = ( - entities: Entity[], - entityType: Entities, - listKey?: string, - pos?: ImportPosition, -) => ({ +const importEntities = (entities: Entity[], entityType: Entities) => ({ type: ENTITIES_IMPORT, entityType, entities, - listKey, - pos, -}); - -interface DeleteEntitiesOpts { - preserveLists?: boolean; -} - -const deleteEntities = ( - ids: Iterable, - entityType: string, - opts: DeleteEntitiesOpts = {}, -) => ({ - type: ENTITIES_DELETE, - ids, - entityType, - opts, }); const entitiesTransaction = (transaction: EntitiesTransaction) => ({ @@ -40,18 +17,12 @@ const entitiesTransaction = (transaction: EntitiesTransaction) => ({ }); /** Any action pertaining to entities. */ -type EntityAction = - | ReturnType - | ReturnType - | ReturnType; +type EntityAction = ReturnType | ReturnType; export { - type DeleteEntitiesOpts, type EntityAction, ENTITIES_IMPORT, - ENTITIES_DELETE, ENTITIES_TRANSACTION, importEntities, - deleteEntities, entitiesTransaction, }; diff --git a/packages/pl-fe/src/entity-store/reducer.ts b/packages/pl-fe/src/entity-store/reducer.ts index 599af63d7..dd52dbd6c 100644 --- a/packages/pl-fe/src/entity-store/reducer.ts +++ b/packages/pl-fe/src/entity-store/reducer.ts @@ -1,12 +1,6 @@ import { create, type Immutable, type Draft } from 'mutative'; -import { - ENTITIES_IMPORT, - ENTITIES_DELETE, - ENTITIES_TRANSACTION, - type EntityAction, - type DeleteEntitiesOpts, -} from './actions'; +import { ENTITIES_IMPORT, ENTITIES_TRANSACTION, type EntityAction } from './actions'; import { Entities } from './entities'; import { createCache, createList, updateStore, updateList } from './utils'; @@ -55,33 +49,6 @@ const importEntities = ( draft[entityType] = cache; }; -const deleteEntities = ( - draft: Draft, - entityType: string, - ids: Iterable, - opts: DeleteEntitiesOpts, -) => { - const cache = draft[entityType] ?? createCache(); - - for (const id of ids) { - delete cache.store[id]; - - if (!opts?.preserveLists) { - for (const list of Object.values(cache.lists)) { - if (list) { - list.ids.delete(id); - - if (typeof list.state.totalCount === 'number') { - list.state.totalCount--; - } - } - } - } - } - - draft[entityType] = cache; -}; - const doTransaction = (draft: Draft, transaction: EntitiesTransaction) => { for (const [entityType, changes] of Object.entries(transaction)) { const cache = draft[entityType] ?? createCache(); @@ -101,14 +68,10 @@ const reducer = (state: Readonly = {}, action: EntityAction): State => { return create( state, (draft) => { - importEntities(draft, action.entityType, action.entities, action.listKey, action.pos); + importEntities(draft, action.entityType, action.entities); }, { enableAutoFreeze: true }, ); - case ENTITIES_DELETE: - return create(state, (draft) => { - deleteEntities(draft, action.entityType, action.ids, action.opts); - }); case ENTITIES_TRANSACTION: return create(state, (draft) => { doTransaction(draft, action.transaction); diff --git a/packages/pl-fe/src/entity-store/types.ts b/packages/pl-fe/src/entity-store/types.ts index 925d61c5e..7bf6c6654 100644 --- a/packages/pl-fe/src/entity-store/types.ts +++ b/packages/pl-fe/src/entity-store/types.ts @@ -25,18 +25,12 @@ interface EntityListState { next: (() => Promise>) | null; /** Previous URL for pagination, if any. */ prev: (() => Promise>) | null; - /** Total number of items according to the API. */ - totalCount: number | undefined; /** Error returned from the API, if any. */ error: unknown; /** Whether data has already been fetched */ fetched: boolean; /** Whether data for this list is currently being fetched. */ fetching: boolean; - /** Date of the last API fetch for this list. */ - lastFetchedAt: Date | undefined; - /** Whether the entities should be refetched on the next component mount. */ - invalid: boolean; } /** Cache data pertaining to a paritcular entity type.. */ diff --git a/packages/pl-fe/src/entity-store/utils.ts b/packages/pl-fe/src/entity-store/utils.ts index 73d2f087b..f536d8a99 100644 --- a/packages/pl-fe/src/entity-store/utils.ts +++ b/packages/pl-fe/src/entity-store/utils.ts @@ -27,11 +27,6 @@ const updateList = ( const oldIds = Array.from(list.ids); const ids = new Set(pos === 'start' ? [...newIds, ...oldIds] : [...oldIds, ...newIds]); - if (typeof list.state.totalCount === 'number') { - const sizeDiff = ids.size - list.ids.size; - list.state.totalCount += sizeDiff; - } - return { ...list, ids, @@ -54,12 +49,9 @@ const createList = (): EntityList => ({ const createListState = (): EntityListState => ({ next: null, prev: null, - totalCount: 0, error: null, fetched: false, fetching: false, - lastFetchedAt: undefined, - invalid: false, }); export { updateStore, updateList, createCache, createList }; diff --git a/packages/pl-fe/src/features/compose/components/reply-group-indicator.tsx b/packages/pl-fe/src/features/compose/components/reply-group-indicator.tsx index 7c0d1dd26..fec71c11a 100644 --- a/packages/pl-fe/src/features/compose/components/reply-group-indicator.tsx +++ b/packages/pl-fe/src/features/compose/components/reply-group-indicator.tsx @@ -5,6 +5,7 @@ import Link from '@/components/link'; import Text from '@/components/ui/text'; import Emojify from '@/features/emoji/emojify'; import { useAppSelector } from '@/hooks/use-app-selector'; +import { useGroupQuery } from '@/queries/groups/use-group'; import { makeGetStatus } from '@/selectors'; interface IReplyGroupIndicator { @@ -19,7 +20,8 @@ const ReplyGroupIndicator = (props: IReplyGroupIndicator) => { const status = useAppSelector((state) => getStatus(state, { id: state.compose[composeId]?.inReplyToId! }), ); - const group = status?.group; + + const { data: group } = useGroupQuery(status?.group_id ?? undefined); if (!group) { return null; diff --git a/packages/pl-fe/src/features/status/components/detailed-status.tsx b/packages/pl-fe/src/features/status/components/detailed-status.tsx index 66c74ded6..13b73e517 100644 --- a/packages/pl-fe/src/features/status/components/detailed-status.tsx +++ b/packages/pl-fe/src/features/status/components/detailed-status.tsx @@ -69,15 +69,12 @@ const DetailedStatus: React.FC = ({ group: ( - + diff --git a/packages/pl-fe/src/selectors/index.ts b/packages/pl-fe/src/selectors/index.ts index 2feaa5337..b9cb5695a 100644 --- a/packages/pl-fe/src/selectors/index.ts +++ b/packages/pl-fe/src/selectors/index.ts @@ -12,7 +12,7 @@ import type { minifyAdminReport } from '@/queries/utils/minify-list'; import type { MinifiedStatus } from '@/reducers/statuses'; import type { MRFSimple } from '@/schemas/pleroma'; import type { RootState } from '@/store'; -import type { Account, Filter, FilterResult, Group, NotificationGroup } from 'pl-api'; +import type { Account, Filter, FilterResult, NotificationGroup } from 'pl-api'; const selectAccount = (state: RootState, accountId: string) => state.entities[Entities.ACCOUNTS]?.store[accountId] as Account | undefined; @@ -120,11 +120,6 @@ const makeGetStatus = () => state.statuses[state.statuses[id]?.reblog_id ?? ''] || null, (state: RootState, { id }: APIStatus) => state.statuses[state.statuses[id]?.quote_id ?? ''] || null, - (state: RootState, { id }: APIStatus) => { - const group = state.statuses[id]?.group_id; - if (group) return state.entities[Entities.GROUPS]?.store[group] as Group; - return undefined; - }, (_state: RootState, { username }: APIStatus) => username, (state: RootState) => state.filters, (_state: RootState, { contextType }: FilterContext) => contextType, @@ -132,17 +127,7 @@ const makeGetStatus = () => (state: RootState) => state.auth.client.features, ], - ( - statusBase, - statusReblog, - statusQuote, - statusGroup, - username, - filters, - contextType, - me, - features, - ) => { + (statusBase, statusReblog, statusQuote, username, filters, contextType, me, features) => { if (!statusBase) return null; const { account } = statusBase; const accountUsername = account.acct; @@ -165,7 +150,6 @@ const makeGetStatus = () => ...statusBase, reblog: statusReblog || null, quote: statusQuote || null, - group: statusGroup ?? null, filtered, }; },