Merge branch 'suggest-hook' into 'develop'

Add useSuggest hook

Closes #1483

See merge request soapbox-pub/soapbox!2623
environments/review-develop-3zknud/deployments/3665
Alex Gleason 1 year ago
commit e1338dce14

@ -2,7 +2,7 @@ import { defineMessages } from 'react-intl';
import { fetchRelationships } from 'soapbox/actions/accounts'; import { fetchRelationships } from 'soapbox/actions/accounts';
import { importFetchedAccount, importFetchedAccounts, importFetchedStatuses } from 'soapbox/actions/importer'; import { importFetchedAccount, importFetchedAccounts, importFetchedStatuses } from 'soapbox/actions/importer';
import { selectAccount } from 'soapbox/selectors'; import { accountIdsToAccts } from 'soapbox/selectors';
import toast from 'soapbox/toast'; import toast from 'soapbox/toast';
import { filterBadges, getTagDiff } from 'soapbox/utils/badges'; import { filterBadges, getTagDiff } from 'soapbox/utils/badges';
import { getFeatures } from 'soapbox/utils/features'; import { getFeatures } from 'soapbox/utils/features';
@ -75,14 +75,6 @@ const ADMIN_REMOVE_PERMISSION_GROUP_REQUEST = 'ADMIN_REMOVE_PERMISSION_GROUP_REQ
const ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS = 'ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS'; const ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS = 'ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS';
const ADMIN_REMOVE_PERMISSION_GROUP_FAIL = 'ADMIN_REMOVE_PERMISSION_GROUP_FAIL'; const ADMIN_REMOVE_PERMISSION_GROUP_FAIL = 'ADMIN_REMOVE_PERMISSION_GROUP_FAIL';
const ADMIN_USERS_SUGGEST_REQUEST = 'ADMIN_USERS_SUGGEST_REQUEST';
const ADMIN_USERS_SUGGEST_SUCCESS = 'ADMIN_USERS_SUGGEST_SUCCESS';
const ADMIN_USERS_SUGGEST_FAIL = 'ADMIN_USERS_SUGGEST_FAIL';
const ADMIN_USERS_UNSUGGEST_REQUEST = 'ADMIN_USERS_UNSUGGEST_REQUEST';
const ADMIN_USERS_UNSUGGEST_SUCCESS = 'ADMIN_USERS_UNSUGGEST_SUCCESS';
const ADMIN_USERS_UNSUGGEST_FAIL = 'ADMIN_USERS_UNSUGGEST_FAIL';
const ADMIN_USER_INDEX_EXPAND_FAIL = 'ADMIN_USER_INDEX_EXPAND_FAIL'; const ADMIN_USER_INDEX_EXPAND_FAIL = 'ADMIN_USER_INDEX_EXPAND_FAIL';
const ADMIN_USER_INDEX_EXPAND_REQUEST = 'ADMIN_USER_INDEX_EXPAND_REQUEST'; const ADMIN_USER_INDEX_EXPAND_REQUEST = 'ADMIN_USER_INDEX_EXPAND_REQUEST';
const ADMIN_USER_INDEX_EXPAND_SUCCESS = 'ADMIN_USER_INDEX_EXPAND_SUCCESS'; const ADMIN_USER_INDEX_EXPAND_SUCCESS = 'ADMIN_USER_INDEX_EXPAND_SUCCESS';
@ -122,8 +114,6 @@ const messages = defineMessages({
announcementUpdateSuccess: { id: 'admin.edit_announcement.updated', defaultMessage: 'Announcement edited' }, announcementUpdateSuccess: { id: 'admin.edit_announcement.updated', defaultMessage: 'Announcement edited' },
}); });
const nicknamesFromIds = (getState: () => RootState, ids: string[]) => ids.map((id) => selectAccount(getState(), id)!.acct);
const fetchConfig = () => const fetchConfig = () =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_CONFIG_FETCH_REQUEST }); dispatch({ type: ADMIN_CONFIG_FETCH_REQUEST });
@ -330,7 +320,7 @@ const deactivateMastodonUsers = (accountIds: string[], reportId?: string) =>
const deactivatePleromaUsers = (accountIds: string[]) => const deactivatePleromaUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds); const nicknames = accountIdsToAccts(getState(), accountIds);
return api(getState) return api(getState)
.patch('/api/v1/pleroma/admin/users/deactivate', { nicknames }) .patch('/api/v1/pleroma/admin/users/deactivate', { nicknames })
.then(({ data: { users } }) => { .then(({ data: { users } }) => {
@ -358,7 +348,7 @@ const deactivateUsers = (accountIds: string[], reportId?: string) =>
const deleteUsers = (accountIds: string[]) => const deleteUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds); const nicknames = accountIdsToAccts(getState(), accountIds);
dispatch({ type: ADMIN_USERS_DELETE_REQUEST, accountIds }); dispatch({ type: ADMIN_USERS_DELETE_REQUEST, accountIds });
return api(getState) return api(getState)
.delete('/api/v1/pleroma/admin/users', { data: { nicknames } }) .delete('/api/v1/pleroma/admin/users', { data: { nicknames } })
@ -383,7 +373,7 @@ const approveMastodonUsers = (accountIds: string[]) =>
const approvePleromaUsers = (accountIds: string[]) => const approvePleromaUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds); const nicknames = accountIdsToAccts(getState(), accountIds);
return api(getState) return api(getState)
.patch('/api/v1/pleroma/admin/users/approve', { nicknames }) .patch('/api/v1/pleroma/admin/users/approve', { nicknames })
.then(({ data: { users } }) => { .then(({ data: { users } }) => {
@ -448,7 +438,7 @@ const fetchModerationLog = (params?: Record<string, any>) =>
const tagUsers = (accountIds: string[], tags: string[]) => const tagUsers = (accountIds: string[], tags: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds); const nicknames = accountIdsToAccts(getState(), accountIds);
dispatch({ type: ADMIN_USERS_TAG_REQUEST, accountIds, tags }); dispatch({ type: ADMIN_USERS_TAG_REQUEST, accountIds, tags });
return api(getState) return api(getState)
.put('/api/v1/pleroma/admin/users/tag', { nicknames, tags }) .put('/api/v1/pleroma/admin/users/tag', { nicknames, tags })
@ -461,7 +451,7 @@ const tagUsers = (accountIds: string[], tags: string[]) =>
const untagUsers = (accountIds: string[], tags: string[]) => const untagUsers = (accountIds: string[], tags: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds); const nicknames = accountIdsToAccts(getState(), accountIds);
// Legacy: allow removing legacy 'donor' tags. // Legacy: allow removing legacy 'donor' tags.
if (tags.includes('badge:donor')) { if (tags.includes('badge:donor')) {
@ -496,17 +486,9 @@ const setBadges = (accountId: string, oldTags: string[], newTags: string[]) =>
return dispatch(setTags(accountId, oldBadges, newBadges)); return dispatch(setTags(accountId, oldBadges, newBadges));
}; };
const verifyUser = (accountId: string) =>
(dispatch: AppDispatch) =>
dispatch(tagUsers([accountId], ['verified']));
const unverifyUser = (accountId: string) =>
(dispatch: AppDispatch) =>
dispatch(untagUsers([accountId], ['verified']));
const addPermission = (accountIds: string[], permissionGroup: string) => const addPermission = (accountIds: string[], permissionGroup: string) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds); const nicknames = accountIdsToAccts(getState(), accountIds);
dispatch({ type: ADMIN_ADD_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup }); dispatch({ type: ADMIN_ADD_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup });
return api(getState) return api(getState)
.post(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { nicknames }) .post(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { nicknames })
@ -519,7 +501,7 @@ const addPermission = (accountIds: string[], permissionGroup: string) =>
const removePermission = (accountIds: string[], permissionGroup: string) => const removePermission = (accountIds: string[], permissionGroup: string) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds); const nicknames = accountIdsToAccts(getState(), accountIds);
dispatch({ type: ADMIN_REMOVE_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup }); dispatch({ type: ADMIN_REMOVE_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup });
return api(getState) return api(getState)
.delete(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { data: { nicknames } }) .delete(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { data: { nicknames } })
@ -563,32 +545,6 @@ const setRole = (accountId: string, role: 'user' | 'moderator' | 'admin') =>
} }
}; };
const suggestUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
dispatch({ type: ADMIN_USERS_SUGGEST_REQUEST, accountIds });
return api(getState)
.patch('/api/v1/pleroma/admin/users/suggest', { nicknames })
.then(({ data: { users } }) => {
dispatch({ type: ADMIN_USERS_SUGGEST_SUCCESS, users, accountIds });
}).catch(error => {
dispatch({ type: ADMIN_USERS_SUGGEST_FAIL, error, accountIds });
});
};
const unsuggestUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
dispatch({ type: ADMIN_USERS_UNSUGGEST_REQUEST, accountIds });
return api(getState)
.patch('/api/v1/pleroma/admin/users/unsuggest', { nicknames })
.then(({ data: { users } }) => {
dispatch({ type: ADMIN_USERS_UNSUGGEST_SUCCESS, users, accountIds });
}).catch(error => {
dispatch({ type: ADMIN_USERS_UNSUGGEST_FAIL, error, accountIds });
});
};
const setUserIndexQuery = (query: string) => ({ type: ADMIN_USER_INDEX_QUERY_SET, query }); const setUserIndexQuery = (query: string) => ({ type: ADMIN_USER_INDEX_QUERY_SET, query });
const fetchUserIndex = () => const fetchUserIndex = () =>
@ -766,12 +722,6 @@ export {
ADMIN_REMOVE_PERMISSION_GROUP_REQUEST, ADMIN_REMOVE_PERMISSION_GROUP_REQUEST,
ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS, ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS,
ADMIN_REMOVE_PERMISSION_GROUP_FAIL, ADMIN_REMOVE_PERMISSION_GROUP_FAIL,
ADMIN_USERS_SUGGEST_REQUEST,
ADMIN_USERS_SUGGEST_SUCCESS,
ADMIN_USERS_SUGGEST_FAIL,
ADMIN_USERS_UNSUGGEST_REQUEST,
ADMIN_USERS_UNSUGGEST_SUCCESS,
ADMIN_USERS_UNSUGGEST_FAIL,
ADMIN_USER_INDEX_EXPAND_FAIL, ADMIN_USER_INDEX_EXPAND_FAIL,
ADMIN_USER_INDEX_EXPAND_REQUEST, ADMIN_USER_INDEX_EXPAND_REQUEST,
ADMIN_USER_INDEX_EXPAND_SUCCESS, ADMIN_USER_INDEX_EXPAND_SUCCESS,
@ -812,16 +762,12 @@ export {
untagUsers, untagUsers,
setTags, setTags,
setBadges, setBadges,
verifyUser,
unverifyUser,
addPermission, addPermission,
removePermission, removePermission,
promoteToAdmin, promoteToAdmin,
promoteToModerator, promoteToModerator,
demoteToUser, demoteToUser,
setRole, setRole,
suggestUsers,
unsuggestUsers,
setUserIndexQuery, setUserIndexQuery,
fetchUserIndex, fetchUserIndex,
expandUserIndex, expandUserIndex,

@ -0,0 +1,2 @@
export { useSuggest } from './useSuggest';
export { useVerify } from './useVerify';

@ -0,0 +1,58 @@
import { useTransaction } from 'soapbox/entity-store/hooks';
import { EntityCallbacks } from 'soapbox/entity-store/hooks/types';
import { useApi, useGetState } from 'soapbox/hooks';
import { accountIdsToAccts } from 'soapbox/selectors';
import type { Account } from 'soapbox/schemas';
function useSuggest() {
const api = useApi();
const getState = useGetState();
const { transaction } = useTransaction();
function suggestEffect(accountIds: string[], suggested: boolean) {
const updater = (account: Account): Account => {
if (account.pleroma) {
account.pleroma.is_suggested = suggested;
}
return account;
};
transaction({
Accounts: accountIds.reduce<Record<string, (account: Account) => Account>>(
(result, id) => ({ ...result, [id]: updater }),
{}),
});
}
async function suggest(accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) {
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(accountIds, false);
}
}
async function unsuggest(accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) {
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(accountIds, true);
}
}
return {
suggest,
unsuggest,
};
}
export { useSuggest };

@ -0,0 +1,63 @@
import { useTransaction } from 'soapbox/entity-store/hooks';
import { EntityCallbacks } from 'soapbox/entity-store/hooks/types';
import { useApi, useGetState } from 'soapbox/hooks';
import { accountIdsToAccts } from 'soapbox/selectors';
import type { Account } from 'soapbox/schemas';
function useVerify() {
const api = useApi();
const getState = useGetState();
const { transaction } = useTransaction();
function verifyEffect(accountIds: string[], verified: boolean) {
const updater = (account: Account): Account => {
if (account.pleroma) {
const tags = account.pleroma.tags.filter((tag) => tag !== 'verified');
if (verified) {
tags.push('verified');
}
account.pleroma.tags = tags;
}
account.verified = verified;
return account;
};
transaction({
Accounts: accountIds.reduce<Record<string, (account: Account) => Account>>(
(result, id) => ({ ...result, [id]: updater }),
{}),
});
}
async function verify(accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) {
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(accountIds, false);
}
}
async function unverify(accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) {
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(accountIds, true);
}
}
return {
verify,
unverify,
};
}
export { useVerify };

@ -3,9 +3,9 @@ import { useEffect, useState } from 'react';
import { z } from 'zod'; import { z } from 'zod';
import { useAppDispatch, useAppSelector, useLoading } from 'soapbox/hooks'; import { useAppDispatch, useAppSelector, useLoading } from 'soapbox/hooks';
import { type RootState } from 'soapbox/store';
import { importEntities } from '../actions'; import { importEntities } from '../actions';
import { findEntity } from '../selectors';
import { Entity } from '../types'; import { Entity } from '../types';
import { EntityFn } from './types'; import { EntityFn } from './types';
@ -58,16 +58,4 @@ function useEntityLookup<TEntity extends Entity>(
}; };
} }
function findEntity<TEntity extends Entity>(
state: RootState,
entityType: string,
lookupFn: LookupFn<TEntity>,
) {
const cache = state.entities[entityType];
if (cache) {
return (Object.values(cache.store) as TEntity[]).find(lookupFn);
}
}
export { useEntityLookup }; export { useEntityLookup };

@ -44,10 +44,24 @@ function selectEntities<TEntity extends Entity>(state: RootState, path: Entities
) : []; ) : [];
} }
/** Find an entity using a finder function. */
function findEntity<TEntity extends Entity>(
state: RootState,
entityType: string,
lookupFn: (entity: TEntity) => boolean,
) {
const cache = state.entities[entityType];
if (cache) {
return (Object.values(cache.store) as TEntity[]).find(lookupFn);
}
}
export { export {
selectCache, selectCache,
selectList, selectList,
selectListState, selectListState,
useListState, useListState,
selectEntities, selectEntities,
findEntity,
}; };

@ -1,15 +1,10 @@
import React, { ChangeEventHandler, useState } from 'react'; import React, { ChangeEventHandler, useState } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { import { setBadges as saveBadges } from 'soapbox/actions/admin';
verifyUser,
unverifyUser,
suggestUsers,
unsuggestUsers,
setBadges as saveBadges,
} from 'soapbox/actions/admin';
import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation'; import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation';
import { useAccount } from 'soapbox/api/hooks'; import { useAccount } from 'soapbox/api/hooks';
import { useSuggest, useVerify } from 'soapbox/api/hooks/admin';
import Account from 'soapbox/components/account'; import Account from 'soapbox/components/account';
import List, { ListItem } from 'soapbox/components/list'; import List, { ListItem } from 'soapbox/components/list';
import MissingIndicator from 'soapbox/components/missing-indicator'; import MissingIndicator from 'soapbox/components/missing-indicator';
@ -45,6 +40,8 @@ const AccountModerationModal: React.FC<IAccountModerationModal> = ({ onClose, ac
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { suggest, unsuggest } = useSuggest();
const { verify, unverify } = useVerify();
const { account: ownAccount } = useOwnAccount(); const { account: ownAccount } = useOwnAccount();
const features = useFeatures(); const features = useFeatures();
const { account } = useAccount(accountId); const { account } = useAccount(accountId);
@ -70,22 +67,22 @@ const AccountModerationModal: React.FC<IAccountModerationModal> = ({ onClose, ac
const { checked } = e.target; const { checked } = e.target;
const message = checked ? messages.userVerified : messages.userUnverified; const message = checked ? messages.userVerified : messages.userUnverified;
const action = checked ? verifyUser : unverifyUser; const action = checked ? verify : unverify;
dispatch(action(account.id)) action([account.id], {
.then(() => toast.success(intl.formatMessage(message, { acct: account.acct }))) onSuccess: () => toast.success(intl.formatMessage(message, { acct: account.acct })),
.catch(() => {}); });
}; };
const handleSuggestedChange: ChangeEventHandler<HTMLInputElement> = (e) => { const handleSuggestedChange: ChangeEventHandler<HTMLInputElement> = (e) => {
const { checked } = e.target; const { checked } = e.target;
const message = checked ? messages.userSuggested : messages.userUnsuggested; const message = checked ? messages.userSuggested : messages.userUnsuggested;
const action = checked ? suggestUsers : unsuggestUsers; const action = checked ? suggest : unsuggest;
dispatch(action([account.id])) action([account.id], {
.then(() => toast.success(intl.formatMessage(message, { acct: account.acct }))) onSuccess: () => toast.success(intl.formatMessage(message, { acct: account.acct })),
.catch(() => {}); });
}; };
const handleDeactivate = () => { const handleDeactivate = () => {

@ -1,4 +1,4 @@
import { Map as ImmutableMap, fromJS } from 'immutable'; import { Map as ImmutableMap } from 'immutable';
import { import {
AUTH_APP_CREATED, AUTH_APP_CREATED,
@ -300,7 +300,7 @@ describe('auth reducer', () => {
it('sets the value of `me`', () => { it('sets the value of `me`', () => {
const action = { const action = {
type: SWITCH_ACCOUNT, type: SWITCH_ACCOUNT,
account: fromJS({ url: 'https://gleasonator.com/users/benis' }), account: { url: 'https://gleasonator.com/users/benis' },
}; };
const result = reducer(undefined, action); const result = reducer(undefined, action);

@ -23,10 +23,6 @@ import {
ADMIN_USERS_DELETE_FAIL, ADMIN_USERS_DELETE_FAIL,
ADMIN_USERS_DEACTIVATE_REQUEST, ADMIN_USERS_DEACTIVATE_REQUEST,
ADMIN_USERS_DEACTIVATE_FAIL, ADMIN_USERS_DEACTIVATE_FAIL,
ADMIN_USERS_SUGGEST_REQUEST,
ADMIN_USERS_SUGGEST_FAIL,
ADMIN_USERS_UNSUGGEST_REQUEST,
ADMIN_USERS_UNSUGGEST_FAIL,
} from 'soapbox/actions/admin'; } from 'soapbox/actions/admin';
import { CHATS_FETCH_SUCCESS, CHATS_EXPAND_SUCCESS, CHAT_FETCH_SUCCESS } from 'soapbox/actions/chats'; import { CHATS_FETCH_SUCCESS, CHATS_EXPAND_SUCCESS, CHAT_FETCH_SUCCESS } from 'soapbox/actions/chats';
import { import {
@ -234,14 +230,6 @@ const importAdminUsers = (state: State, adminUsers: Array<Record<string, any>>):
}); });
}; };
const setSuggested = (state: State, accountIds: Array<string>, isSuggested: boolean): State => {
return state.withMutations(state => {
accountIds.forEach(id => {
state.setIn([id, 'pleroma', 'is_suggested'], isSuggested);
});
});
};
export default function accounts(state: State = initialState, action: AnyAction): State { export default function accounts(state: State = initialState, action: AnyAction): State {
switch (action.type) { switch (action.type) {
case ACCOUNT_IMPORT: case ACCOUNT_IMPORT:
@ -280,12 +268,6 @@ export default function accounts(state: State = initialState, action: AnyAction)
return setActive(state, action.accountIds, true); return setActive(state, action.accountIds, true);
case ADMIN_USERS_FETCH_SUCCESS: case ADMIN_USERS_FETCH_SUCCESS:
return importAdminUsers(state, action.users); return importAdminUsers(state, action.users);
case ADMIN_USERS_SUGGEST_REQUEST:
case ADMIN_USERS_UNSUGGEST_FAIL:
return setSuggested(state, action.accountIds, true);
case ADMIN_USERS_UNSUGGEST_REQUEST:
case ADMIN_USERS_SUGGEST_FAIL:
return setSuggested(state, action.accountIds, false);
default: default:
return state; return state;
} }

@ -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 getAccountBase = (state: RootState, id: string) => state.entities[Entities.ACCOUNTS]?.store[id] as Account | undefined;
const getAccountRelationship = (state: RootState, id: string) => state.relationships.get(id); const getAccountRelationship = (state: RootState, id: string) => state.relationships.get(id);

Loading…
Cancel
Save