152 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			152 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 'flavours/glitch/api_types/accounts';
 | 
						|
import type { ApiCustomEmojiJSON } from 'flavours/glitch/api_types/custom_emoji';
 | 
						|
import emojify from 'flavours/glitch/features/emoji/emoji';
 | 
						|
import { unescapeHTML } from 'flavours/glitch/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),
 | 
						|
  });
 | 
						|
}
 |