accounts_meta: switch to immer, use the results for useOwnAccount

This commit is contained in:
Alex Gleason 2024-03-24 17:50:54 -05:00
parent 0716c5189e
commit c3ebb5c428
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
4 changed files with 46 additions and 31 deletions

View file

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

View file

@ -3,40 +3,48 @@
* @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 { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me';
import { Account, accountSchema } from 'soapbox/schemas';
import type { AnyAction } from 'redux';
const MetaRecord = ImmutableRecord({
pleroma: ImmutableMap<string, any>(),
role: null as ImmutableMap<string, any> | null,
source: ImmutableMap<string, any>(),
});
interface AccountMeta {
pleroma: Account['pleroma'];
source: Account['source'];
}
export type Meta = ReturnType<typeof MetaRecord>;
type State = ImmutableMap<string, Meta>;
type State = Record<string, AccountMeta | undefined>;
const importAccount = (state: State, account: ImmutableMap<string, any>) => {
const accountId = account.get('id');
function importAccount(state: State, data: unknown): State {
const result = accountSchema.safeParse(data);
return state.set(accountId, MetaRecord({
pleroma: account.get('pleroma', ImmutableMap()).delete('settings_store'),
role: account.get('role', null),
source: account.get('source', ImmutableMap()),
}));
};
if (!result.success) {
return state;
}
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) {
case ME_FETCH_SUCCESS:
case ME_PATCH_SUCCESS:
return importAccount(state, ImmutableMap(fromJS(action.me)));
return importAccount(state, action.me);
case VERIFY_CREDENTIALS_SUCCESS:
case AUTH_ACCOUNT_REMEMBER_SUCCESS:
return importAccount(state, ImmutableMap(fromJS(action.account)));
return importAccount(state, action.account);
default:
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 getAccountRelationship = (state: RootState, id: string) => state.relationships.get(id);
const getAccountMeta = (state: RootState, id: string) => state.accounts_meta[id];
export const makeGetAccount = () => {
return createSelector([
getAccountBase,
getAccountRelationship,
], (account, relationship) => {
getAccountMeta,
], (account, relationship, meta) => {
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
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;
};