83 lines
2.1 KiB
TypeScript
83 lines
2.1 KiB
TypeScript
|
import { Map as ImmutableMap } from 'immutable';
|
||
|
|
||
|
import type { Reducer } from 'redux';
|
||
|
|
||
|
import {
|
||
|
followAccountSuccess,
|
||
|
unfollowAccountSuccess,
|
||
|
importAccounts,
|
||
|
revealAccount,
|
||
|
} from 'mastodon/actions/accounts_typed';
|
||
|
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
|
||
|
import { me } from 'mastodon/initial_state';
|
||
|
import type { Account } from 'mastodon/models/account';
|
||
|
import { createAccountFromServerJSON } from 'mastodon/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;
|
||
|
};
|