diff --git a/packages/pl-fe/src/api/hooks/accounts/use-account.ts b/packages/pl-fe/src/api/hooks/accounts/use-account.ts index 7110f7ed3..2a5a75199 100644 --- a/packages/pl-fe/src/api/hooks/accounts/use-account.ts +++ b/packages/pl-fe/src/api/hooks/accounts/use-account.ts @@ -2,10 +2,10 @@ import { useMemo } from 'react'; import { Entities } from '@/entity-store/entities'; import { useEntity } from '@/entity-store/hooks/use-entity'; -import { useAppSelector } from '@/hooks/use-app-selector'; import { useClient } from '@/hooks/use-client'; import { useFeatures } from '@/hooks/use-features'; import { useLoggedIn } from '@/hooks/use-logged-in'; +import { useCredentialAccount } from '@/queries/accounts/use-account-credentials'; import { useRelationshipQuery } from '@/queries/accounts/use-relationship'; import type { Account } from 'pl-api'; @@ -14,6 +14,18 @@ interface UseAccountOpts { withRelationship?: boolean; } +const ADMIN_PERMISSION = 0x1n; + +const hasAdminPermission = (permissions?: string): boolean | undefined => { + if (!permissions) return undefined; + + try { + return (BigInt(permissions) & ADMIN_PERMISSION) === ADMIN_PERMISSION; + } catch { + return undefined; + } +}; + const useAccount = (accountId?: string, opts: UseAccountOpts = {}) => { const client = useClient(); const features = useFeatures(); @@ -26,7 +38,7 @@ const useAccount = (accountId?: string, opts: UseAccountOpts = {}) => { { enabled: !!accountId }, ); - const meta = useAppSelector((state) => (accountId ? state.accounts_meta[accountId] : undefined)); + const { data: credentialAccount } = useCredentialAccount(me === accountId); const { data: relationship, isLoading: isRelationshipLoading } = useRelationshipQuery( withRelationship ? entity?.id : undefined, @@ -35,20 +47,28 @@ const useAccount = (accountId?: string, opts: UseAccountOpts = {}) => { const isBlocked = entity?.relationship?.blocked_by === true; const isUnavailable = me === entity?.id ? false : isBlocked && !features.blockersVisible; - const account = useMemo( - () => - entity - ? { - ...entity, - relationship, - __meta: { meta, ...entity.__meta }, - // @ts-ignore - is_admin: meta?.role ? (meta.role.permissions & 0x1) === 0x1 : entity.is_admin, - } - : undefined, - [entity, relationship], + const credentialIsAdmin = useMemo( + () => hasAdminPermission(credentialAccount?.role?.permissions), + [credentialAccount?.role?.permissions], ); + const account = useMemo(() => { + if (!entity) return undefined; + + const mergedRelationship = relationship ?? entity.relationship; + const mergedIsAdmin = credentialIsAdmin ?? entity.is_admin; + + if (mergedRelationship === entity.relationship && mergedIsAdmin === entity.is_admin) { + return entity; + } + + return { + ...entity, + relationship: mergedRelationship, + is_admin: mergedIsAdmin, + }; + }, [entity, relationship, credentialIsAdmin]); + return { ...result, isRelationshipLoading, diff --git a/packages/pl-fe/src/queries/accounts/use-account-credentials.ts b/packages/pl-fe/src/queries/accounts/use-account-credentials.ts index 03f1ec5bf..97675c457 100644 --- a/packages/pl-fe/src/queries/accounts/use-account-credentials.ts +++ b/packages/pl-fe/src/queries/accounts/use-account-credentials.ts @@ -7,14 +7,14 @@ import { useClient } from '@/hooks/use-client'; import type { UpdateCredentialsParams } from 'pl-api'; -const useCredentialAccount = () => { +const useCredentialAccount = (enabled = true) => { const client = useClient(); const currentAccount = useCurrentAccount(); return useQuery({ queryKey: [currentAccount, 'credentialAccount'], queryFn: () => client.settings.verifyCredentials(), - enabled: currentAccount !== 'unauthenticated', + enabled: currentAccount !== 'unauthenticated' && enabled, }); }; diff --git a/packages/pl-fe/src/reducers/accounts-meta.ts b/packages/pl-fe/src/reducers/accounts-meta.ts deleted file mode 100644 index f7a841c60..000000000 --- a/packages/pl-fe/src/reducers/accounts-meta.ts +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Accounts Meta: private user data only the owner should see. - * @module pl-fe/reducers/accounts_meta - */ -import { create, type Immutable } from 'mutative'; - -import { - VERIFY_CREDENTIALS_SUCCESS, - AUTH_ACCOUNT_REMEMBER_SUCCESS, - type AuthAction, -} from '@/actions/auth'; -import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS, type MeAction } from '@/actions/me'; - -import type { Account, CredentialAccount } from 'pl-api'; - -interface AccountMeta { - pleroma: Account['__meta']['pleroma']; - source?: CredentialAccount['source']; -} - -type State = Immutable>; - -const importAccount = (state: State, account: CredentialAccount): State => - create( - state, - (draft) => { - const existing = draft[account.id]; - - draft[account.id] = { - pleroma: account.__meta.pleroma ?? existing?.pleroma, - source: account.source ?? existing?.source, - }; - }, - { enableAutoFreeze: true }, - ); - -const accounts_meta = (state: Readonly = {}, action: AuthAction | MeAction): State => { - switch (action.type) { - case ME_FETCH_SUCCESS: - case ME_PATCH_SUCCESS: - return importAccount(state, action.me); - case VERIFY_CREDENTIALS_SUCCESS: - case AUTH_ACCOUNT_REMEMBER_SUCCESS: - return importAccount(state, action.account); - default: - return state; - } -}; - -export { accounts_meta as default }; diff --git a/packages/pl-fe/src/reducers/index.ts b/packages/pl-fe/src/reducers/index.ts index 538a1e534..3ba8d9eb8 100644 --- a/packages/pl-fe/src/reducers/index.ts +++ b/packages/pl-fe/src/reducers/index.ts @@ -4,7 +4,6 @@ import { AUTH_LOGGED_OUT } from '@/actions/auth'; import * as BuildConfig from '@/build-config'; import entities from '@/entity-store/reducer'; -import accounts_meta from './accounts-meta'; import admin from './admin'; import auth from './auth'; import compose from './compose'; @@ -22,7 +21,6 @@ import statuses from './statuses'; import timelines from './timelines'; const reducers = { - accounts_meta, admin, auth, compose,