diff --git a/src/api/hooks/accounts/useAccount.ts b/src/api/hooks/accounts/useAccount.ts index 907337b8b..9db7ec217 100644 --- a/src/api/hooks/accounts/useAccount.ts +++ b/src/api/hooks/accounts/useAccount.ts @@ -30,7 +30,7 @@ function useAccount(accountId?: string, opts: UseAccountOpts = {}) { isLoading: isRelationshipLoading, } = useRelationship(accountId, { enabled: withRelationship }); - const isBlocked = entity?.relationship?.blocked_by === true; + const isBlocked = relationship?.blocked_by === true; const isUnavailable = (me === entity?.id) ? false : (isBlocked && !features.blockersVisible); const account = useMemo( diff --git a/src/api/hooks/accounts/useAccountLookup.ts b/src/api/hooks/accounts/useAccountLookup.ts index 321c8dcc1..ef9306a7d 100644 --- a/src/api/hooks/accounts/useAccountLookup.ts +++ b/src/api/hooks/accounts/useAccountLookup.ts @@ -31,7 +31,7 @@ function useAccountLookup(acct: string | undefined, opts: UseAccountLookupOpts = isLoading: isRelationshipLoading, } = useRelationship(account?.id, { enabled: withRelationship }); - const isBlocked = account?.relationship?.blocked_by === true; + const isBlocked = relationship?.blocked_by === true; const isUnavailable = (me === account?.id) ? false : (isBlocked && !features.blockersVisible); useEffect(() => { diff --git a/src/normalizers/admin-account.ts b/src/normalizers/admin-account.ts index 4e040dfb1..5f3b7d8cb 100644 --- a/src/normalizers/admin-account.ts +++ b/src/normalizers/admin-account.ts @@ -9,11 +9,10 @@ import { fromJS, } from 'immutable'; -import type { ReducerAccount } from 'soapbox/reducers/accounts'; import type { Account, EmbeddedEntity } from 'soapbox/types/entities'; export const AdminAccountRecord = ImmutableRecord({ - account: null as EmbeddedEntity, + account: null as EmbeddedEntity, approved: false, confirmed: false, created_at: new Date(), diff --git a/src/normalizers/admin-report.ts b/src/normalizers/admin-report.ts index acf6786b1..71e616e8d 100644 --- a/src/normalizers/admin-report.ts +++ b/src/normalizers/admin-report.ts @@ -9,21 +9,20 @@ import { fromJS, } from 'immutable'; -import type { ReducerAccount } from 'soapbox/reducers/accounts'; import type { Account, EmbeddedEntity, Status } from 'soapbox/types/entities'; export const AdminReportRecord = ImmutableRecord({ - account: null as EmbeddedEntity, + account: null as EmbeddedEntity, action_taken: false, - action_taken_by_account: null as EmbeddedEntity | null, - assigned_account: null as EmbeddedEntity | null, + action_taken_by_account: null as EmbeddedEntity | null, + assigned_account: null as EmbeddedEntity | null, category: '', comment: '', created_at: new Date(), id: '', rules: ImmutableList(), statuses: ImmutableList>(), - target_account: null as EmbeddedEntity, + target_account: null as EmbeddedEntity, updated_at: new Date(), }); diff --git a/src/normalizers/status-edit.ts b/src/normalizers/status-edit.ts index 26619c174..859eb3a95 100644 --- a/src/normalizers/status-edit.ts +++ b/src/normalizers/status-edit.ts @@ -17,11 +17,10 @@ import { pollSchema } from 'soapbox/schemas'; import { stripCompatibilityFeatures } from 'soapbox/utils/html'; import { makeEmojiMap } from 'soapbox/utils/normalizers'; -import type { ReducerAccount } from 'soapbox/reducers/accounts'; import type { Account, Attachment, Emoji, EmbeddedEntity, Poll } from 'soapbox/types/entities'; export const StatusEditRecord = ImmutableRecord({ - account: null as EmbeddedEntity, + account: null as EmbeddedEntity, content: '', created_at: new Date(), emojis: ImmutableList(), diff --git a/src/reducers/accounts.ts b/src/reducers/accounts.ts deleted file mode 100644 index 83b610c95..000000000 --- a/src/reducers/accounts.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { produce } from 'immer'; - -import { - ADMIN_USERS_TAG_REQUEST, - ADMIN_USERS_TAG_SUCCESS, - ADMIN_USERS_TAG_FAIL, - ADMIN_USERS_UNTAG_REQUEST, - ADMIN_USERS_UNTAG_SUCCESS, - ADMIN_USERS_UNTAG_FAIL, - ADMIN_ADD_PERMISSION_GROUP_REQUEST, - ADMIN_ADD_PERMISSION_GROUP_SUCCESS, - ADMIN_ADD_PERMISSION_GROUP_FAIL, - ADMIN_REMOVE_PERMISSION_GROUP_REQUEST, - ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS, - ADMIN_REMOVE_PERMISSION_GROUP_FAIL, - ADMIN_USERS_DELETE_REQUEST, - ADMIN_USERS_DELETE_FAIL, - ADMIN_USERS_DEACTIVATE_REQUEST, - ADMIN_USERS_DEACTIVATE_FAIL, -} from 'soapbox/actions/admin'; -import { CHATS_FETCH_SUCCESS, CHATS_EXPAND_SUCCESS, CHAT_FETCH_SUCCESS } from 'soapbox/actions/chats'; -import { - ACCOUNT_IMPORT, - ACCOUNTS_IMPORT, - ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP, -} from 'soapbox/actions/importer'; -import { STREAMING_CHAT_UPDATE } from 'soapbox/actions/streaming'; -import { Account, accountSchema } from 'soapbox/schemas'; - -import type { AnyAction } from 'redux'; - -export interface ReducerAccount extends Omit { - moved: string | null; -} - -type State = Record; - -const initialState: State = {}; - -/** Convert sub-entities into string IDs (or null). */ -function minifyAccount(account: Account): ReducerAccount { - return { ...account, moved: account.moved?.id ?? null }; -} - -/** Parse account data, and import valid accounts into the state. */ -function fixAccount(state: State, data: unknown): State { - const result = accountSchema.safeParse(data); - - if (!result.success) { - return state; - } - - const account = result.data; - const normalized = minifyAccount(account); - - return { ...state, [normalized.id]: normalized }; -} - -/** Import valid accounts into the state. */ -function normalizeAccounts(state: State, data: unknown[]): State { - return produce(state, draft => { - data.forEach((item) => fixAccount(draft, item)); - }); -} - -function importAccountFromChat(state: State, chat: any): State { - return fixAccount(state, chat.account); -} - -function importAccountsFromChats(state: State, chats: unknown[]): State { - return produce(state, draft => { - chats.forEach(chat => importAccountFromChat(draft, chat)); - }); -} - -function addTags(state: State, accountIds: string[], tags: string[]): State { - return produce(state, draft => { - for (const id of accountIds) { - const account = draft[id]; - if (!account) continue; - - const tagSet = new Set([...account.pleroma.tags, ...tags]); - account.pleroma.tags = [...tagSet]; - - if (tagSet.has('verified')) { - account.verified = true; - } - } - }); -} - -function removeTags (state: State, accountIds: string[], tags: string[]): State { - return produce(state, draft => { - for (const id of accountIds) { - const account = draft[id]; - if (!account) continue; - - const tagSet = new Set(account.pleroma.tags).difference(new Set(tags)); - account.pleroma.tags = [...tagSet]; - - if (tagSet.has('verified')) { - account.verified = false; - } - } - }); -} - -function setActive(state: State, accountIds: Array, active: boolean): State { - return produce(state, draft => { - for (const id of accountIds) { - const account = draft[id]; - if (!account) continue; - - account.pleroma.deactivated = !active; - } - }); -} - -function setPermission(state: State, accountIds: string[], permissionGroup: string, value: boolean): State { - return produce(state, draft => { - for (const id of accountIds) { - const account = draft[id]; - if (!account) continue; - - switch (permissionGroup) { - case 'admin': - account.pleroma.is_admin = value; - break; - case 'moderator': - account.pleroma.is_moderator = value; - break; - } - } - }); -} - -export default function accounts(state: State = initialState, action: AnyAction): State { - switch (action.type) { - case ACCOUNT_IMPORT: - return fixAccount(state, action.account); - case ACCOUNTS_IMPORT: - return normalizeAccounts(state, action.accounts); - case ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP: - return fixAccount(state, { id: -1, username: action.username }); - case CHATS_FETCH_SUCCESS: - case CHATS_EXPAND_SUCCESS: - return importAccountsFromChats(state, action.chats); - case CHAT_FETCH_SUCCESS: - case STREAMING_CHAT_UPDATE: - return importAccountsFromChats(state, [action.chat]); - case ADMIN_USERS_TAG_REQUEST: - case ADMIN_USERS_TAG_SUCCESS: - case ADMIN_USERS_UNTAG_FAIL: - return addTags(state, action.accountIds, action.tags); - case ADMIN_USERS_UNTAG_REQUEST: - case ADMIN_USERS_UNTAG_SUCCESS: - case ADMIN_USERS_TAG_FAIL: - return removeTags(state, action.accountIds, action.tags); - case ADMIN_ADD_PERMISSION_GROUP_REQUEST: - case ADMIN_ADD_PERMISSION_GROUP_SUCCESS: - case ADMIN_REMOVE_PERMISSION_GROUP_FAIL: - return setPermission(state, action.accountIds, action.permissionGroup, true); - case ADMIN_REMOVE_PERMISSION_GROUP_REQUEST: - case ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS: - case ADMIN_ADD_PERMISSION_GROUP_FAIL: - return setPermission(state, action.accountIds, action.permissionGroup, false); - case ADMIN_USERS_DELETE_REQUEST: - case ADMIN_USERS_DEACTIVATE_REQUEST: - return setActive(state, action.accountIds, false); - case ADMIN_USERS_DELETE_FAIL: - case ADMIN_USERS_DEACTIVATE_FAIL: - return setActive(state, action.accountIds, true); - default: - return state; - } -} diff --git a/src/schemas/account.ts b/src/schemas/account.ts index 10e51fa32..dc3605b17 100644 --- a/src/schemas/account.ts +++ b/src/schemas/account.ts @@ -7,6 +7,7 @@ import emojify from 'soapbox/features/emoji'; import { unescapeHTML } from 'soapbox/utils/html'; import { customEmojiSchema } from './custom-emoji'; +import { Relationship } from './relationship'; import { coerceObject, contentSchema, filteredArray, makeCustomEmojiMap } from './utils'; import type { Resolve } from 'soapbox/utils/types'; @@ -180,6 +181,9 @@ const accountSchema = baseAccountSchema.extend({ moved: baseAccountSchema.transform(transformAccount).nullable().catch(null), }).transform(transformAccount); -type Account = Resolve>; +type Account = Resolve> & { + // FIXME: decouple these in components. + relationship?: Relationship; +} export { accountSchema, type Account }; diff --git a/src/utils/accounts.test.ts b/src/utils/accounts.test.ts deleted file mode 100644 index f884729f3..000000000 --- a/src/utils/accounts.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { AccountRecord } from 'soapbox/normalizers'; - -import { - getDomain, -} from './accounts'; - -import type { ReducerAccount } from 'soapbox/reducers/accounts'; - -describe('getDomain', () => { - const account = AccountRecord({ - acct: 'alice', - url: 'https://party.com/users/alice', - }) as ReducerAccount; - it('returns the domain', () => { - expect(getDomain(account)).toEqual('party.com'); - }); -});