account.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import type { RecordOf } from 'immutable';
  2. import { List, Record as ImmutableRecord } from 'immutable';
  3. import escapeTextContentForBrowser from 'escape-html';
  4. import type {
  5. ApiAccountFieldJSON,
  6. ApiAccountRoleJSON,
  7. ApiAccountJSON,
  8. } from 'mastodon/api_types/accounts';
  9. import type { ApiCustomEmojiJSON } from 'mastodon/api_types/custom_emoji';
  10. import emojify from 'mastodon/features/emoji/emoji';
  11. import { unescapeHTML } from 'mastodon/utils/html';
  12. import { CustomEmojiFactory } from './custom_emoji';
  13. import type { CustomEmoji } from './custom_emoji';
  14. // AccountField
  15. interface AccountFieldShape extends Required<ApiAccountFieldJSON> {
  16. name_emojified: string;
  17. value_emojified: string;
  18. value_plain: string | null;
  19. }
  20. type AccountField = RecordOf<AccountFieldShape>;
  21. const AccountFieldFactory = ImmutableRecord<AccountFieldShape>({
  22. name: '',
  23. value: '',
  24. verified_at: null,
  25. name_emojified: '',
  26. value_emojified: '',
  27. value_plain: null,
  28. });
  29. // AccountRole
  30. export type AccountRoleShape = ApiAccountRoleJSON;
  31. export type AccountRole = RecordOf<AccountRoleShape>;
  32. const AccountRoleFactory = ImmutableRecord<AccountRoleShape>({
  33. color: '',
  34. id: '',
  35. name: '',
  36. });
  37. // Account
  38. export interface AccountShape
  39. extends Required<
  40. Omit<ApiAccountJSON, 'emojis' | 'fields' | 'roles' | 'moved'>
  41. > {
  42. emojis: List<CustomEmoji>;
  43. fields: List<AccountField>;
  44. roles: List<AccountRole>;
  45. display_name_html: string;
  46. note_emojified: string;
  47. note_plain: string | null;
  48. hidden: boolean;
  49. moved: string | null;
  50. }
  51. export type Account = RecordOf<AccountShape>;
  52. export const accountDefaultValues: AccountShape = {
  53. acct: '',
  54. avatar: '',
  55. avatar_static: '',
  56. bot: false,
  57. created_at: '',
  58. discoverable: false,
  59. indexable: false,
  60. display_name: '',
  61. display_name_html: '',
  62. emojis: List<CustomEmoji>(),
  63. fields: List<AccountField>(),
  64. group: false,
  65. header: '',
  66. header_static: '',
  67. id: '',
  68. last_status_at: '',
  69. locked: false,
  70. noindex: false,
  71. note: '',
  72. note_emojified: '',
  73. note_plain: 'string',
  74. roles: List<AccountRole>(),
  75. uri: '',
  76. url: '',
  77. username: '',
  78. followers_count: 0,
  79. following_count: 0,
  80. statuses_count: 0,
  81. hidden: false,
  82. suspended: false,
  83. memorial: false,
  84. limited: false,
  85. moved: null,
  86. hide_collections: false,
  87. };
  88. const AccountFactory = ImmutableRecord<AccountShape>(accountDefaultValues);
  89. type EmojiMap = Record<string, ApiCustomEmojiJSON>;
  90. function makeEmojiMap(emojis: ApiCustomEmojiJSON[]) {
  91. return emojis.reduce<EmojiMap>((obj, emoji) => {
  92. obj[`:${emoji.shortcode}:`] = emoji;
  93. return obj;
  94. }, {});
  95. }
  96. function createAccountField(
  97. jsonField: ApiAccountFieldJSON,
  98. emojiMap: EmojiMap,
  99. ) {
  100. return AccountFieldFactory({
  101. ...jsonField,
  102. name_emojified: emojify(
  103. escapeTextContentForBrowser(jsonField.name),
  104. emojiMap,
  105. ),
  106. value_emojified: emojify(jsonField.value, emojiMap),
  107. value_plain: unescapeHTML(jsonField.value),
  108. });
  109. }
  110. export function createAccountFromServerJSON(serverJSON: ApiAccountJSON) {
  111. const { moved, ...accountJSON } = serverJSON;
  112. const emojiMap = makeEmojiMap(accountJSON.emojis);
  113. const displayName =
  114. accountJSON.display_name.trim().length === 0
  115. ? accountJSON.username
  116. : accountJSON.display_name;
  117. return AccountFactory({
  118. ...accountJSON,
  119. moved: moved?.id,
  120. fields: List(
  121. serverJSON.fields.map((field) => createAccountField(field, emojiMap)),
  122. ),
  123. emojis: List(serverJSON.emojis.map((emoji) => CustomEmojiFactory(emoji))),
  124. roles: List(serverJSON.roles?.map((role) => AccountRoleFactory(role))),
  125. display_name_html: emojify(
  126. escapeTextContentForBrowser(displayName),
  127. emojiMap,
  128. ),
  129. note_emojified: emojify(accountJSON.note, emojiMap),
  130. note_plain: unescapeHTML(accountJSON.note),
  131. });
  132. }