From 40af1d91a46cd0ff7622db501b9a434edaa4756b Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 21 Jul 2023 12:59:31 -0500 Subject: [PATCH] suggest and verify by account IDs, simplify hooks --- app/soapbox/actions/admin.ts | 18 +++++----- app/soapbox/api/hooks/admin/useSuggest.ts | 35 ++++++------------- app/soapbox/api/hooks/admin/useVerify.ts | 35 ++++++------------- .../account-moderation-modal.tsx | 4 +-- app/soapbox/selectors/index.ts | 2 ++ 5 files changed, 34 insertions(+), 60 deletions(-) diff --git a/app/soapbox/actions/admin.ts b/app/soapbox/actions/admin.ts index 0ab2b827f..613615140 100644 --- a/app/soapbox/actions/admin.ts +++ b/app/soapbox/actions/admin.ts @@ -2,7 +2,7 @@ import { defineMessages } from 'react-intl'; import { fetchRelationships } from 'soapbox/actions/accounts'; import { importFetchedAccount, importFetchedAccounts, importFetchedStatuses } from 'soapbox/actions/importer'; -import { selectAccount } from 'soapbox/selectors'; +import { accountIdsToAccts } from 'soapbox/selectors'; import toast from 'soapbox/toast'; import { filterBadges, getTagDiff } from 'soapbox/utils/badges'; import { getFeatures } from 'soapbox/utils/features'; @@ -114,8 +114,6 @@ const messages = defineMessages({ announcementUpdateSuccess: { id: 'admin.edit_announcement.updated', defaultMessage: 'Announcement edited' }, }); -const nicknamesFromIds = (getState: () => RootState, ids: string[]) => ids.map((id) => selectAccount(getState(), id)!.acct); - const fetchConfig = () => (dispatch: AppDispatch, getState: () => RootState) => { dispatch({ type: ADMIN_CONFIG_FETCH_REQUEST }); @@ -322,7 +320,7 @@ const deactivateMastodonUsers = (accountIds: string[], reportId?: string) => const deactivatePleromaUsers = (accountIds: string[]) => (dispatch: AppDispatch, getState: () => RootState) => { - const nicknames = nicknamesFromIds(getState, accountIds); + const nicknames = accountIdsToAccts(getState(), accountIds); return api(getState) .patch('/api/v1/pleroma/admin/users/deactivate', { nicknames }) .then(({ data: { users } }) => { @@ -350,7 +348,7 @@ const deactivateUsers = (accountIds: string[], reportId?: string) => const deleteUsers = (accountIds: string[]) => (dispatch: AppDispatch, getState: () => RootState) => { - const nicknames = nicknamesFromIds(getState, accountIds); + const nicknames = accountIdsToAccts(getState(), accountIds); dispatch({ type: ADMIN_USERS_DELETE_REQUEST, accountIds }); return api(getState) .delete('/api/v1/pleroma/admin/users', { data: { nicknames } }) @@ -375,7 +373,7 @@ const approveMastodonUsers = (accountIds: string[]) => const approvePleromaUsers = (accountIds: string[]) => (dispatch: AppDispatch, getState: () => RootState) => { - const nicknames = nicknamesFromIds(getState, accountIds); + const nicknames = accountIdsToAccts(getState(), accountIds); return api(getState) .patch('/api/v1/pleroma/admin/users/approve', { nicknames }) .then(({ data: { users } }) => { @@ -440,7 +438,7 @@ const fetchModerationLog = (params?: Record) => const tagUsers = (accountIds: string[], tags: string[]) => (dispatch: AppDispatch, getState: () => RootState) => { - const nicknames = nicknamesFromIds(getState, accountIds); + const nicknames = accountIdsToAccts(getState(), accountIds); dispatch({ type: ADMIN_USERS_TAG_REQUEST, accountIds, tags }); return api(getState) .put('/api/v1/pleroma/admin/users/tag', { nicknames, tags }) @@ -453,7 +451,7 @@ const tagUsers = (accountIds: string[], tags: string[]) => const untagUsers = (accountIds: string[], tags: string[]) => (dispatch: AppDispatch, getState: () => RootState) => { - const nicknames = nicknamesFromIds(getState, accountIds); + const nicknames = accountIdsToAccts(getState(), accountIds); // Legacy: allow removing legacy 'donor' tags. if (tags.includes('badge:donor')) { @@ -490,7 +488,7 @@ const setBadges = (accountId: string, oldTags: string[], newTags: string[]) => const addPermission = (accountIds: string[], permissionGroup: string) => (dispatch: AppDispatch, getState: () => RootState) => { - const nicknames = nicknamesFromIds(getState, accountIds); + const nicknames = accountIdsToAccts(getState(), accountIds); dispatch({ type: ADMIN_ADD_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup }); return api(getState) .post(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { nicknames }) @@ -503,7 +501,7 @@ const addPermission = (accountIds: string[], permissionGroup: string) => const removePermission = (accountIds: string[], permissionGroup: string) => (dispatch: AppDispatch, getState: () => RootState) => { - const nicknames = nicknamesFromIds(getState, accountIds); + const nicknames = accountIdsToAccts(getState(), accountIds); dispatch({ type: ADMIN_REMOVE_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup }); return api(getState) .delete(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { data: { nicknames } }) diff --git a/app/soapbox/api/hooks/admin/useSuggest.ts b/app/soapbox/api/hooks/admin/useSuggest.ts index 2948beba7..b20bc5308 100644 --- a/app/soapbox/api/hooks/admin/useSuggest.ts +++ b/app/soapbox/api/hooks/admin/useSuggest.ts @@ -1,20 +1,16 @@ -import { Entities } from 'soapbox/entity-store/entities'; import { useTransaction } from 'soapbox/entity-store/hooks'; import { EntityCallbacks } from 'soapbox/entity-store/hooks/types'; -import { findEntity } from 'soapbox/entity-store/selectors'; import { useApi, useGetState } from 'soapbox/hooks'; +import { accountIdsToAccts } from 'soapbox/selectors'; import type { Account } from 'soapbox/schemas'; -import type { RootState } from 'soapbox/store'; function useSuggest() { const api = useApi(); const getState = useGetState(); const { transaction } = useTransaction(); - function suggestEffect(accts: string[], suggested: boolean) { - const ids = selectIdsForAccts(getState(), accts); - + function suggestEffect(accountIds: string[], suggested: boolean) { const updater = (account: Account): Account => { if (account.pleroma) { account.pleroma.is_suggested = suggested; @@ -23,31 +19,33 @@ function useSuggest() { }; transaction({ - Accounts: ids.reduce Account>>( + Accounts: accountIds.reduce Account>>( (result, id) => ({ ...result, [id]: updater }), {}), }); } - async function suggest(accts: string[], callbacks?: EntityCallbacks) { - suggestEffect(accts, true); + async function suggest(accountIds: string[], callbacks?: EntityCallbacks) { + const accts = accountIdsToAccts(getState(), accountIds); + suggestEffect(accountIds, true); try { await api.patch('/api/v1/pleroma/admin/users/suggest', { nicknames: accts }); callbacks?.onSuccess?.(); } catch (e) { callbacks?.onError?.(e); - suggestEffect(accts, false); + suggestEffect(accountIds, false); } } - async function unsuggest(accts: string[], callbacks?: EntityCallbacks) { - suggestEffect(accts, false); + async function unsuggest(accountIds: string[], callbacks?: EntityCallbacks) { + const accts = accountIdsToAccts(getState(), accountIds); + suggestEffect(accountIds, false); try { await api.patch('/api/v1/pleroma/admin/users/unsuggest', { nicknames: accts }); callbacks?.onSuccess?.(); } catch (e) { callbacks?.onError?.(e); - suggestEffect(accts, true); + suggestEffect(accountIds, true); } } @@ -57,15 +55,4 @@ function useSuggest() { }; } -function selectIdsForAccts(state: RootState, accts: string[]): string[] { - return accts.map((acct) => { - const account = findEntity( - state, - Entities.ACCOUNTS, - (account) => account.acct === acct, - ); - return account!.id; - }); -} - export { useSuggest }; \ No newline at end of file diff --git a/app/soapbox/api/hooks/admin/useVerify.ts b/app/soapbox/api/hooks/admin/useVerify.ts index adee278b6..090e1bc43 100644 --- a/app/soapbox/api/hooks/admin/useVerify.ts +++ b/app/soapbox/api/hooks/admin/useVerify.ts @@ -1,20 +1,16 @@ -import { Entities } from 'soapbox/entity-store/entities'; import { useTransaction } from 'soapbox/entity-store/hooks'; import { EntityCallbacks } from 'soapbox/entity-store/hooks/types'; -import { findEntity } from 'soapbox/entity-store/selectors'; import { useApi, useGetState } from 'soapbox/hooks'; +import { accountIdsToAccts } from 'soapbox/selectors'; import type { Account } from 'soapbox/schemas'; -import type { RootState } from 'soapbox/store'; function useVerify() { const api = useApi(); const getState = useGetState(); const { transaction } = useTransaction(); - function verifyEffect(accts: string[], verified: boolean) { - const ids = selectIdsForAccts(getState(), accts); - + function verifyEffect(accountIds: string[], verified: boolean) { const updater = (account: Account): Account => { if (account.pleroma) { const tags = account.pleroma.tags.filter((tag) => tag !== 'verified'); @@ -28,31 +24,33 @@ function useVerify() { }; transaction({ - Accounts: ids.reduce Account>>( + Accounts: accountIds.reduce Account>>( (result, id) => ({ ...result, [id]: updater }), {}), }); } - async function verify(accts: string[], callbacks?: EntityCallbacks) { - verifyEffect(accts, true); + async function verify(accountIds: string[], callbacks?: EntityCallbacks) { + const accts = accountIdsToAccts(getState(), accountIds); + verifyEffect(accountIds, true); try { await api.put('/api/v1/pleroma/admin/users/tag', { nicknames: accts, tags: ['verified'] }); callbacks?.onSuccess?.(); } catch (e) { callbacks?.onError?.(e); - verifyEffect(accts, false); + verifyEffect(accountIds, false); } } - async function unverify(accts: string[], callbacks?: EntityCallbacks) { - verifyEffect(accts, false); + async function unverify(accountIds: string[], callbacks?: EntityCallbacks) { + const accts = accountIdsToAccts(getState(), accountIds); + verifyEffect(accountIds, false); try { await api.delete('/api/v1/pleroma/admin/users/tag', { data: { nicknames: accts, tags: ['verified'] } }); callbacks?.onSuccess?.(); } catch (e) { callbacks?.onError?.(e); - verifyEffect(accts, true); + verifyEffect(accountIds, true); } } @@ -62,15 +60,4 @@ function useVerify() { }; } -function selectIdsForAccts(state: RootState, accts: string[]): string[] { - return accts.map((acct) => { - const account = findEntity( - state, - Entities.ACCOUNTS, - (account) => account.acct === acct, - ); - return account!.id; - }); -} - export { useVerify }; \ No newline at end of file diff --git a/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx b/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx index a336e2d7e..2d5958f2d 100644 --- a/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx +++ b/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx @@ -69,7 +69,7 @@ const AccountModerationModal: React.FC = ({ onClose, ac const message = checked ? messages.userVerified : messages.userUnverified; const action = checked ? verify : unverify; - action([account.acct], { + action([account.id], { onSuccess: () => toast.success(intl.formatMessage(message, { acct: account.acct })), }); }; @@ -80,7 +80,7 @@ const AccountModerationModal: React.FC = ({ onClose, ac const message = checked ? messages.userSuggested : messages.userUnsuggested; const action = checked ? suggest : unsuggest; - action([account.acct], { + action([account.id], { onSuccess: () => toast.success(intl.formatMessage(message, { acct: account.acct })), }); }; diff --git a/app/soapbox/selectors/index.ts b/app/soapbox/selectors/index.ts index 4bbf90a42..1f844bc27 100644 --- a/app/soapbox/selectors/index.ts +++ b/app/soapbox/selectors/index.ts @@ -33,6 +33,8 @@ export function selectOwnAccount(state: RootState) { } } +export const accountIdsToAccts = (state: RootState, ids: string[]) => ids.map((id) => selectAccount(state, id)!.acct); + const getAccountBase = (state: RootState, id: string) => state.entities[Entities.ACCOUNTS]?.store[id] as Account | undefined; const getAccountRelationship = (state: RootState, id: string) => state.relationships.get(id);