151 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 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<ApiAccountFieldJSON> {
 | |
|   name_emojified: string;
 | |
|   value_emojified: string;
 | |
|   value_plain: string | null;
 | |
| }
 | |
| 
 | |
| type AccountField = RecordOf<AccountFieldShape>;
 | |
| 
 | |
| const AccountFieldFactory = ImmutableRecord<AccountFieldShape>({
 | |
|   name: '',
 | |
|   value: '',
 | |
|   verified_at: null,
 | |
|   name_emojified: '',
 | |
|   value_emojified: '',
 | |
|   value_plain: null,
 | |
| });
 | |
| 
 | |
| // AccountRole
 | |
| export type AccountRoleShape = ApiAccountRoleJSON;
 | |
| export type AccountRole = RecordOf<AccountRoleShape>;
 | |
| 
 | |
| const AccountRoleFactory = ImmutableRecord<AccountRoleShape>({
 | |
|   color: '',
 | |
|   id: '',
 | |
|   name: '',
 | |
| });
 | |
| 
 | |
| // Account
 | |
| export interface AccountShape
 | |
|   extends Required<
 | |
|     Omit<ApiAccountJSON, 'emojis' | 'fields' | 'roles' | 'moved'>
 | |
|   > {
 | |
|   emojis: List<CustomEmoji>;
 | |
|   fields: List<AccountField>;
 | |
|   roles: List<AccountRole>;
 | |
|   display_name_html: string;
 | |
|   note_emojified: string;
 | |
|   note_plain: string | null;
 | |
|   hidden: boolean;
 | |
|   moved: string | null;
 | |
| }
 | |
| 
 | |
| export type Account = RecordOf<AccountShape>;
 | |
| 
 | |
| export const accountDefaultValues: AccountShape = {
 | |
|   acct: '',
 | |
|   avatar: '',
 | |
|   avatar_static: '',
 | |
|   bot: false,
 | |
|   created_at: '',
 | |
|   discoverable: false,
 | |
|   indexable: false,
 | |
|   display_name: '',
 | |
|   display_name_html: '',
 | |
|   emojis: List<CustomEmoji>(),
 | |
|   fields: List<AccountField>(),
 | |
|   group: false,
 | |
|   header: '',
 | |
|   header_static: '',
 | |
|   id: '',
 | |
|   last_status_at: '',
 | |
|   locked: false,
 | |
|   noindex: false,
 | |
|   note: '',
 | |
|   note_emojified: '',
 | |
|   note_plain: 'string',
 | |
|   roles: List<AccountRole>(),
 | |
|   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<AccountShape>(accountDefaultValues);
 | |
| 
 | |
| type EmojiMap = Record<string, ApiCustomEmojiJSON>;
 | |
| 
 | |
| function makeEmojiMap(emojis: ApiCustomEmojiJSON[]) {
 | |
|   return emojis.reduce<EmojiMap>((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),
 | |
|   });
 | |
| }
 |