import type { RecordOf } from 'immutable'; import { List, Record as ImmutableRecord } from 'immutable'; import escapeTextContentForBrowser from 'escape-html'; import type { ApiAccountFieldJSON, ApiAccountRoleJSON, ApiAccountJSON, } from 'mastodon/api_types/accounts'; import type { ApiCustomEmojiJSON } from 'mastodon/api_types/custom_emoji'; import emojify from 'mastodon/features/emoji/emoji'; import { unescapeHTML } from 'mastodon/utils/html'; import { CustomEmojiFactory } from './custom_emoji'; import type { CustomEmoji } from './custom_emoji'; // AccountField interface AccountFieldShape extends Required { name_emojified: string; value_emojified: string; value_plain: string | null; } type AccountField = RecordOf; const AccountFieldFactory = ImmutableRecord({ name: '', value: '', verified_at: null, name_emojified: '', value_emojified: '', value_plain: null, }); // AccountRole export type AccountRoleShape = ApiAccountRoleJSON; export type AccountRole = RecordOf; const AccountRoleFactory = ImmutableRecord({ color: '', id: '', name: '', }); // Account export interface AccountShape extends Required< Omit > { emojis: List; fields: List; roles: List; display_name_html: string; note_emojified: string; note_plain: string | null; hidden: boolean; moved: string | null; } export type Account = RecordOf; export const accountDefaultValues: AccountShape = { acct: '', avatar: '', avatar_static: '', bot: false, created_at: '', discoverable: false, display_name: '', display_name_html: '', emojis: List(), fields: List(), group: false, header: '', header_static: '', id: '', last_status_at: '', locked: false, noindex: false, note: '', note_emojified: '', note_plain: 'string', roles: List(), uri: '', url: '', username: '', followers_count: 0, following_count: 0, statuses_count: 0, hidden: false, suspended: false, memorial: false, limited: false, moved: null, hide_collections: false, }; const AccountFactory = ImmutableRecord(accountDefaultValues); type EmojiMap = Record; function makeEmojiMap(emojis: ApiCustomEmojiJSON[]) { return emojis.reduce((obj, emoji) => { obj[`:${emoji.shortcode}:`] = emoji; return obj; }, {}); } function createAccountField( jsonField: ApiAccountFieldJSON, emojiMap: EmojiMap, ) { return AccountFieldFactory({ ...jsonField, name_emojified: emojify( escapeTextContentForBrowser(jsonField.name), emojiMap, ), value_emojified: emojify(jsonField.value, emojiMap), value_plain: unescapeHTML(jsonField.value), }); } export function createAccountFromServerJSON(serverJSON: ApiAccountJSON) { const { moved, ...accountJSON } = serverJSON; const emojiMap = makeEmojiMap(accountJSON.emojis); const displayName = accountJSON.display_name.trim().length === 0 ? accountJSON.username : accountJSON.display_name; return AccountFactory({ ...accountJSON, moved: moved?.id, fields: List( serverJSON.fields.map((field) => createAccountField(field, emojiMap)), ), emojis: List(serverJSON.emojis.map((emoji) => CustomEmojiFactory(emoji))), roles: List(serverJSON.roles?.map((role) => AccountRoleFactory(role))), display_name_html: emojify( escapeTextContentForBrowser(displayName), emojiMap, ), note_emojified: emojify(accountJSON.note, emojiMap), note_plain: unescapeHTML(accountJSON.note), }); }