accounts.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import type { Reducer } from '@reduxjs/toolkit';
  2. import { Map as ImmutableMap } from 'immutable';
  3. import {
  4. followAccountSuccess,
  5. unfollowAccountSuccess,
  6. importAccounts,
  7. revealAccount,
  8. } from 'mastodon/actions/accounts_typed';
  9. import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
  10. import { me } from 'mastodon/initial_state';
  11. import type { Account } from 'mastodon/models/account';
  12. import { createAccountFromServerJSON } from 'mastodon/models/account';
  13. const initialState = ImmutableMap<string, Account>();
  14. const normalizeAccount = (
  15. state: typeof initialState,
  16. account: ApiAccountJSON,
  17. ) => {
  18. return state.set(
  19. account.id,
  20. createAccountFromServerJSON(account).set(
  21. 'hidden',
  22. state.get(account.id)?.hidden === false
  23. ? false
  24. : account.limited || false,
  25. ),
  26. );
  27. };
  28. const normalizeAccounts = (
  29. state: typeof initialState,
  30. accounts: ApiAccountJSON[],
  31. ) => {
  32. accounts.forEach((account) => {
  33. state = normalizeAccount(state, account);
  34. });
  35. return state;
  36. };
  37. function getCurrentUser() {
  38. if (!me)
  39. throw new Error(
  40. 'No current user (me) defined when calling `accountsReducer`',
  41. );
  42. return me;
  43. }
  44. export const accountsReducer: Reducer<typeof initialState> = (
  45. state = initialState,
  46. action,
  47. ) => {
  48. if (revealAccount.match(action))
  49. return state.setIn([action.payload.id, 'hidden'], false);
  50. else if (importAccounts.match(action))
  51. return normalizeAccounts(state, action.payload.accounts);
  52. else if (followAccountSuccess.match(action)) {
  53. return state
  54. .update(action.payload.relationship.id, (account) =>
  55. account?.update('followers_count', (n) => n + 1),
  56. )
  57. .update(getCurrentUser(), (account) =>
  58. account?.update('following_count', (n) => n + 1),
  59. );
  60. } else if (unfollowAccountSuccess.match(action))
  61. return state
  62. .update(action.payload.relationship.id, (account) =>
  63. account?.update('followers_count', (n) => Math.max(0, n - 1)),
  64. )
  65. .update(getCurrentUser(), (account) =>
  66. account?.update('following_count', (n) => Math.max(0, n - 1)),
  67. );
  68. else return state;
  69. };