/** * Announcement normalizer: * Converts API announcements into our internal format. * @see {@link https://docs.joinmastodon.org/entities/announcement/} */ import { Map as ImmutableMap, List as ImmutableList, Record as ImmutableRecord, fromJS, } from 'immutable'; import emojify from 'soapbox/features/emoji/emoji'; import { normalizeEmoji } from 'soapbox/normalizers/emoji'; import { makeEmojiMap } from 'soapbox/utils/normalizers'; import { normalizeAnnouncementReaction } from './announcement-reaction'; import { normalizeMention } from './mention'; import type { AnnouncementReaction, Emoji, Mention } from 'soapbox/types/entities'; // https://docs.joinmastodon.org/entities/announcement/ export const AnnouncementRecord = ImmutableRecord({ id: '', content: '', starts_at: null as Date | null, ends_at: null as Date | null, all_day: false, read: false, published_at: Date, reactions: ImmutableList(), statuses: ImmutableMap(), mentions: ImmutableList(), tags: ImmutableList>(), emojis: ImmutableList(), updated_at: Date, // Internal fields contentHtml: '', }); const normalizeMentions = (announcement: ImmutableMap) => { return announcement.update('mentions', ImmutableList(), mentions => { return mentions.map(normalizeMention); }); }; // Normalize reactions const normalizeReactions = (announcement: ImmutableMap) => { return announcement.update('reactions', ImmutableList(), reactions => { return reactions.map((reaction: ImmutableMap) => normalizeAnnouncementReaction(reaction, announcement.get('id'))); }); }; // Normalize emojis const normalizeEmojis = (announcement: ImmutableMap) => { return announcement.update('emojis', ImmutableList(), emojis => { return emojis.map(normalizeEmoji); }); }; const normalizeContent = (announcement: ImmutableMap) => { const emojiMap = makeEmojiMap(announcement.get('emojis')); const contentHtml = emojify(announcement.get('content'), emojiMap); return announcement.set('contentHtml', contentHtml); }; const normalizeStatuses = (announcement: ImmutableMap) => { const statuses = announcement .get('statuses', ImmutableList()) .reduce((acc: ImmutableMap, curr: ImmutableMap) => acc.set(curr.get('url'), `/@${curr.getIn(['account', 'acct'])}/${curr.get('id')}`), ImmutableMap()); return announcement.set('statuses', statuses); }; export const normalizeAnnouncement = (announcement: Record) => { return AnnouncementRecord( ImmutableMap(fromJS(announcement)).withMutations(announcement => { normalizeMentions(announcement); normalizeReactions(announcement); normalizeEmojis(announcement); normalizeContent(announcement); normalizeStatuses(announcement); }), ); };