mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-02-04 05:53:07 -05:00
37070a7881
Port ded799f91302c1ea2ac0b463ef50e309e154466c to glitch-soc Signed-off-by: Claire <claire.github-309c@sitedethib.com>
113 lines
2.8 KiB
TypeScript
113 lines
2.8 KiB
TypeScript
import type { RecordOf } from 'immutable';
|
|
import { Record, List } from 'immutable';
|
|
|
|
import escapeTextContentForBrowser from 'escape-html';
|
|
|
|
import type {
|
|
ApiPollJSON,
|
|
ApiPollOptionJSON,
|
|
} from 'flavours/glitch/api_types/polls';
|
|
import emojify from 'flavours/glitch/features/emoji/emoji';
|
|
|
|
import { CustomEmojiFactory, makeEmojiMap } from './custom_emoji';
|
|
import type { CustomEmoji, EmojiMap } from './custom_emoji';
|
|
|
|
interface PollOptionTranslationShape {
|
|
title: string;
|
|
titleHtml: string;
|
|
}
|
|
|
|
export type PollOptionTranslation = RecordOf<PollOptionTranslationShape>;
|
|
|
|
export const PollOptionTranslationFactory = Record<PollOptionTranslationShape>({
|
|
title: '',
|
|
titleHtml: '',
|
|
});
|
|
|
|
interface PollOptionShape extends Required<ApiPollOptionJSON> {
|
|
voted: boolean;
|
|
titleHtml: string;
|
|
translation: PollOptionTranslation | null;
|
|
}
|
|
|
|
export function createPollOptionTranslationFromServerJSON(
|
|
translation: { title: string },
|
|
emojiMap: EmojiMap,
|
|
) {
|
|
return PollOptionTranslationFactory({
|
|
...translation,
|
|
titleHtml: emojify(
|
|
escapeTextContentForBrowser(translation.title),
|
|
emojiMap,
|
|
),
|
|
});
|
|
}
|
|
|
|
export type PollOption = RecordOf<PollOptionShape>;
|
|
|
|
export const PollOptionFactory = Record<PollOptionShape>({
|
|
title: '',
|
|
votes_count: 0,
|
|
voted: false,
|
|
titleHtml: '',
|
|
translation: null,
|
|
});
|
|
|
|
interface PollShape
|
|
extends Omit<ApiPollJSON, 'emojis' | 'options' | 'own_votes'> {
|
|
emojis: List<CustomEmoji>;
|
|
options: List<PollOption>;
|
|
own_votes?: List<number>;
|
|
}
|
|
export type Poll = RecordOf<PollShape>;
|
|
|
|
export const PollFactory = Record<PollShape>({
|
|
id: '',
|
|
expires_at: '',
|
|
expired: false,
|
|
multiple: false,
|
|
voters_count: 0,
|
|
votes_count: 0,
|
|
voted: false,
|
|
emojis: List<CustomEmoji>(),
|
|
options: List<PollOption>(),
|
|
own_votes: List(),
|
|
});
|
|
|
|
export function createPollFromServerJSON(
|
|
serverJSON: ApiPollJSON,
|
|
previousPoll?: Poll,
|
|
) {
|
|
const emojiMap = makeEmojiMap(serverJSON.emojis);
|
|
|
|
return PollFactory({
|
|
...serverJSON,
|
|
emojis: List(serverJSON.emojis.map((emoji) => CustomEmojiFactory(emoji))),
|
|
own_votes: serverJSON.own_votes ? List(serverJSON.own_votes) : undefined,
|
|
options: List(
|
|
serverJSON.options.map((optionJSON, index) => {
|
|
const option = PollOptionFactory({
|
|
...optionJSON,
|
|
voted: serverJSON.own_votes?.includes(index) || false,
|
|
titleHtml: emojify(
|
|
escapeTextContentForBrowser(optionJSON.title),
|
|
emojiMap,
|
|
),
|
|
});
|
|
|
|
const prevOption = previousPoll?.options.get(index);
|
|
if (prevOption?.translation && prevOption.title === option.title) {
|
|
const { translation } = prevOption;
|
|
|
|
option.set(
|
|
'translation',
|
|
createPollOptionTranslationFromServerJSON(translation, emojiMap),
|
|
);
|
|
}
|
|
|
|
return option;
|
|
}),
|
|
),
|
|
});
|
|
}
|