Merge branch 'refactor-accounts-meta' into 'main'

accounts_meta: switch to immer, use the results for useOwnAccount

See merge request soapbox-pub/soapbox!2961
This commit is contained in:
Alex Gleason 2024-03-24 23:11:31 +00:00
commit 015d0ce481
4 changed files with 46 additions and 31 deletions

View file

@ -105,8 +105,8 @@ const addToAliases = (account: Account) =>
const features = getFeatures(instance); const features = getFeatures(instance);
if (!features.accountMoving) { if (!features.accountMoving) {
const me = state.me; const me = state.me as string;
const alsoKnownAs = state.accounts_meta.get(me as string)!.pleroma.get('also_known_as'); const alsoKnownAs = state.accounts_meta[me]?.pleroma?.also_known_as ?? [];
dispatch(addToAliasesRequest()); dispatch(addToAliasesRequest());
@ -156,8 +156,8 @@ const removeFromAliases = (account: string) =>
const features = getFeatures(instance); const features = getFeatures(instance);
if (!features.accountMoving) { if (!features.accountMoving) {
const me = state.me; const me = state.me as string;
const alsoKnownAs = state.accounts_meta.get(me as string)!.pleroma.get('also_known_as'); const alsoKnownAs = state.accounts_meta[me]?.pleroma?.also_known_as ?? [];
dispatch(removeFromAliasesRequest()); dispatch(removeFromAliasesRequest());

View file

@ -3,40 +3,48 @@
* @module soapbox/reducers/accounts_meta * @module soapbox/reducers/accounts_meta
*/ */
import { Map as ImmutableMap, Record as ImmutableRecord, fromJS } from 'immutable'; import { produce } from 'immer';
import { VERIFY_CREDENTIALS_SUCCESS, AUTH_ACCOUNT_REMEMBER_SUCCESS } from 'soapbox/actions/auth'; import { VERIFY_CREDENTIALS_SUCCESS, AUTH_ACCOUNT_REMEMBER_SUCCESS } from 'soapbox/actions/auth';
import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me'; import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me';
import { Account, accountSchema } from 'soapbox/schemas';
import type { AnyAction } from 'redux'; import type { AnyAction } from 'redux';
const MetaRecord = ImmutableRecord({ interface AccountMeta {
pleroma: ImmutableMap<string, any>(), pleroma: Account['pleroma'];
role: null as ImmutableMap<string, any> | null, source: Account['source'];
source: ImmutableMap<string, any>(), }
});
export type Meta = ReturnType<typeof MetaRecord>; type State = Record<string, AccountMeta | undefined>;
type State = ImmutableMap<string, Meta>;
const importAccount = (state: State, account: ImmutableMap<string, any>) => { function importAccount(state: State, data: unknown): State {
const accountId = account.get('id'); const result = accountSchema.safeParse(data);
return state.set(accountId, MetaRecord({ if (!result.success) {
pleroma: account.get('pleroma', ImmutableMap()).delete('settings_store'), return state;
role: account.get('role', null), }
source: account.get('source', ImmutableMap()),
}));
};
export default function accounts_meta(state: State = ImmutableMap<string, Meta>(), action: AnyAction) { const account = result.data;
return produce(state, draft => {
const existing = draft[account.id];
draft[account.id] = {
pleroma: account.pleroma ?? existing?.pleroma,
source: account.source ?? existing?.source,
};
});
}
export default function accounts_meta(state: Readonly<State> = {}, action: AnyAction): State {
switch (action.type) { switch (action.type) {
case ME_FETCH_SUCCESS: case ME_FETCH_SUCCESS:
case ME_PATCH_SUCCESS: case ME_PATCH_SUCCESS:
return importAccount(state, ImmutableMap(fromJS(action.me))); return importAccount(state, action.me);
case VERIFY_CREDENTIALS_SUCCESS: case VERIFY_CREDENTIALS_SUCCESS:
case AUTH_ACCOUNT_REMEMBER_SUCCESS: case AUTH_ACCOUNT_REMEMBER_SUCCESS:
return importAccount(state, ImmutableMap(fromJS(action.account))); return importAccount(state, action.account);
default: default:
return state; return state;
} }

View file

@ -38,14 +38,21 @@ export const accountIdsToAccts = (state: RootState, ids: string[]) => ids.map((i
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);
const getAccountMeta = (state: RootState, id: string) => state.accounts_meta[id];
export const makeGetAccount = () => { export const makeGetAccount = () => {
return createSelector([ return createSelector([
getAccountBase, getAccountBase,
getAccountRelationship, getAccountRelationship,
], (account, relationship) => { getAccountMeta,
], (account, relationship, meta) => {
if (!account) return null; if (!account) return null;
return { ...account, relationship }; return {
...account,
relationship,
source: meta?.source ?? account.source,
pleroma: meta?.pleroma ?? account.pleroma,
};
}); });
}; };

View file

@ -8,12 +8,12 @@ export const PERMISSION_MANAGE_REPORTS = 0x0000000000000010;
type Permission = typeof PERMISSION_CREATE_GROUPS | typeof PERMISSION_INVITE_USERS | typeof PERMISSION_MANAGE_USERS | typeof PERMISSION_MANAGE_REPORTS type Permission = typeof PERMISSION_CREATE_GROUPS | typeof PERMISSION_INVITE_USERS | typeof PERMISSION_MANAGE_USERS | typeof PERMISSION_MANAGE_REPORTS
export const hasPermission = (state: RootState, permission: Permission) => { export const hasPermission = (state: RootState, permission: Permission) => {
const account = state.accounts_meta.get(state.me as string)!; return true;
// const role = state.accounts_meta[state.me as string]?.role;
if (!account?.role) return true; // if (!role) return true;
// const { permissions } = role;
const permissions = account.getIn(['role', 'permissions']) as number; // if (!permission) return true;
// return (permissions & permission) === permission;
if (!permission) return true;
return (permissions & permission) === permission;
}; };