catstodon/app/javascript/flavours/glitch/reducers/accounts.ts
Renaud Chaput 7fe5623a27 [Glitch] Use Immutable Record for accounts in Redux state
Port 3bf2a7296e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2023-12-20 19:49:44 +01:00

82 lines
2.2 KiB
TypeScript

import { Map as ImmutableMap } from 'immutable';
import type { Reducer } from 'redux';
import {
followAccountSuccess,
unfollowAccountSuccess,
importAccounts,
revealAccount,
} from 'flavours/glitch/actions/accounts_typed';
import type { ApiAccountJSON } from 'flavours/glitch/api_types/accounts';
import { me } from 'flavours/glitch/initial_state';
import type { Account } from 'flavours/glitch/models/account';
import { createAccountFromServerJSON } from 'flavours/glitch/models/account';
const initialState = ImmutableMap<string, Account>();
const normalizeAccount = (
state: typeof initialState,
account: ApiAccountJSON,
) => {
return state.set(
account.id,
createAccountFromServerJSON(account).set(
'hidden',
state.get(account.id)?.hidden === false
? false
: account.limited || false,
),
);
};
const normalizeAccounts = (
state: typeof initialState,
accounts: ApiAccountJSON[],
) => {
accounts.forEach((account) => {
state = normalizeAccount(state, account);
});
return state;
};
export const accountsReducer: Reducer<typeof initialState> = (
state = initialState,
action,
) => {
const currentUserId = me;
if (!currentUserId)
throw new Error(
'No current user (me) defined when calling `accountsReducer`',
);
if (revealAccount.match(action))
return state.setIn([action.payload.id, 'hidden'], false);
else if (importAccounts.match(action))
return normalizeAccounts(state, action.payload.accounts);
else if (followAccountSuccess.match(action))
return state
.update(
action.payload.relationship.id,
(account) => account?.update('followers_count', (n) => n + 1),
)
.update(
currentUserId,
(account) => account?.update('following_count', (n) => n + 1),
);
else if (unfollowAccountSuccess.match(action))
return state
.update(
action.payload.relationship.id,
(account) =>
account?.update('followers_count', (n) => Math.max(0, n - 1)),
)
.update(
currentUserId,
(account) =>
account?.update('following_count', (n) => Math.max(0, n - 1)),
);
else return state;
};