Convert EmojiReaction to zod
This commit is contained in:
parent
0016aeacec
commit
e3fcff55f9
|
@ -1,12 +1,10 @@
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { normalizeEmojiReaction } from 'soapbox/normalizers/emoji-reaction';
|
|
||||||
|
|
||||||
import { render, screen } from '../../../../jest/test-helpers';
|
import { render, screen } from '../../../../jest/test-helpers';
|
||||||
import ChatMessageReaction from '../chat-message-reaction';
|
import ChatMessageReaction from '../chat-message-reaction';
|
||||||
|
|
||||||
const emojiReaction = normalizeEmojiReaction({
|
const emojiReaction = ({
|
||||||
name: '👍',
|
name: '👍',
|
||||||
count: 1,
|
count: 1,
|
||||||
me: false,
|
me: false,
|
||||||
|
@ -56,7 +54,7 @@ describe('<ChatMessageReaction />', () => {
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<ChatMessageReaction
|
<ChatMessageReaction
|
||||||
emojiReaction={normalizeEmojiReaction({
|
emojiReaction={({
|
||||||
name: '👍',
|
name: '👍',
|
||||||
count: 1,
|
count: 1,
|
||||||
me: true,
|
me: true,
|
||||||
|
|
|
@ -312,7 +312,7 @@ const ChatMessage = (props: IChatMessage) => {
|
||||||
</Stack>
|
</Stack>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
{(chatMessage.emoji_reactions?.size) ? (
|
{(chatMessage.emoji_reactions?.length) ? (
|
||||||
<div
|
<div
|
||||||
className={clsx({
|
className={clsx({
|
||||||
'space-y-1': true,
|
'space-y-1': true,
|
||||||
|
|
|
@ -6,8 +6,8 @@ import {
|
||||||
} from 'immutable';
|
} from 'immutable';
|
||||||
|
|
||||||
import { normalizeAttachment } from 'soapbox/normalizers/attachment';
|
import { normalizeAttachment } from 'soapbox/normalizers/attachment';
|
||||||
|
import { emojiReactionSchema } from 'soapbox/schemas';
|
||||||
import { normalizeEmojiReaction } from './emoji-reaction';
|
import { filteredArray } from 'soapbox/schemas/utils';
|
||||||
|
|
||||||
import type { Attachment, Card, Emoji, EmojiReaction } from 'soapbox/types/entities';
|
import type { Attachment, Card, Emoji, EmojiReaction } from 'soapbox/types/entities';
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ export const ChatMessageRecord = ImmutableRecord({
|
||||||
created_at: '',
|
created_at: '',
|
||||||
emojis: ImmutableList<Emoji>(),
|
emojis: ImmutableList<Emoji>(),
|
||||||
expiration: null as number | null,
|
expiration: null as number | null,
|
||||||
emoji_reactions: null as ImmutableList<EmojiReaction> | null,
|
emoji_reactions: null as readonly EmojiReaction[] | null,
|
||||||
id: '',
|
id: '',
|
||||||
unread: false,
|
unread: false,
|
||||||
deleting: false,
|
deleting: false,
|
||||||
|
@ -41,13 +41,8 @@ const normalizeMedia = (status: ImmutableMap<string, any>) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeChatMessageEmojiReaction = (chatMessage: ImmutableMap<string, any>) => {
|
const normalizeChatMessageEmojiReaction = (chatMessage: ImmutableMap<string, any>) => {
|
||||||
const emojiReactions = chatMessage.get('emoji_reactions');
|
const emojiReactions = chatMessage.get('emoji_reactions') || ImmutableList();
|
||||||
|
return chatMessage.set('emoji_reactions', filteredArray(emojiReactionSchema).parse(emojiReactions.toJS()));
|
||||||
if (emojiReactions) {
|
|
||||||
return chatMessage.set('emoji_reactions', ImmutableList(emojiReactions.map(normalizeEmojiReaction)));
|
|
||||||
} else {
|
|
||||||
return chatMessage;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Rewrite `<p></p>` to empty string. */
|
/** Rewrite `<p></p>` to empty string. */
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
import { Map as ImmutableMap, Record as ImmutableRecord, fromJS } from 'immutable';
|
|
||||||
|
|
||||||
// https://docs.joinmastodon.org/entities/emoji/
|
|
||||||
export const EmojiReactionRecord = ImmutableRecord({
|
|
||||||
name: '',
|
|
||||||
count: null as number | null,
|
|
||||||
me: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const normalizeEmojiReaction = (emojiReaction: Record<string, any>) => {
|
|
||||||
return EmojiReactionRecord(
|
|
||||||
ImmutableMap(fromJS(emojiReaction)),
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -7,7 +7,6 @@ export { AttachmentRecord, normalizeAttachment } from './attachment';
|
||||||
export { ChatRecord, normalizeChat } from './chat';
|
export { ChatRecord, normalizeChat } from './chat';
|
||||||
export { ChatMessageRecord, normalizeChatMessage } from './chat-message';
|
export { ChatMessageRecord, normalizeChatMessage } from './chat-message';
|
||||||
export { EmojiRecord, normalizeEmoji } from './emoji';
|
export { EmojiRecord, normalizeEmoji } from './emoji';
|
||||||
export { EmojiReactionRecord } from './emoji-reaction';
|
|
||||||
export { FilterRecord, normalizeFilter } from './filter';
|
export { FilterRecord, normalizeFilter } from './filter';
|
||||||
export { FilterKeywordRecord, normalizeFilterKeyword } from './filter-keyword';
|
export { FilterKeywordRecord, normalizeFilterKeyword } from './filter-keyword';
|
||||||
export { FilterStatusRecord, normalizeFilterStatus } from './filter-status';
|
export { FilterStatusRecord, normalizeFilterStatus } from './filter-status';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
import { Map as ImmutableMap } from 'immutable';
|
||||||
import sumBy from 'lodash/sumBy';
|
import sumBy from 'lodash/sumBy';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import { __stub } from 'soapbox/api';
|
||||||
import { buildRelationship } from 'soapbox/jest/factory';
|
import { buildRelationship } from 'soapbox/jest/factory';
|
||||||
import { createTestStore, mockStore, queryClient, renderHook, rootState, waitFor } from 'soapbox/jest/test-helpers';
|
import { createTestStore, mockStore, queryClient, renderHook, rootState, waitFor } from 'soapbox/jest/test-helpers';
|
||||||
import { normalizeChatMessage } from 'soapbox/normalizers';
|
import { normalizeChatMessage } from 'soapbox/normalizers';
|
||||||
import { normalizeEmojiReaction } from 'soapbox/normalizers/emoji-reaction';
|
|
||||||
import { Store } from 'soapbox/store';
|
import { Store } from 'soapbox/store';
|
||||||
import { ChatMessage } from 'soapbox/types/entities';
|
import { ChatMessage } from 'soapbox/types/entities';
|
||||||
import { flattenPages } from 'soapbox/utils/queries';
|
import { flattenPages } from 'soapbox/utils/queries';
|
||||||
|
@ -426,11 +425,11 @@ describe('useChatActions', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedChatMessage = (queryClient.getQueryData(ChatKeys.chatMessages(chat.id)) as any).pages[0].result[0] as ChatMessage;
|
const updatedChatMessage = (queryClient.getQueryData(ChatKeys.chatMessages(chat.id)) as any).pages[0].result[0] as ChatMessage;
|
||||||
expect(updatedChatMessage.emoji_reactions).toEqual(ImmutableList([normalizeEmojiReaction({
|
expect(updatedChatMessage.emoji_reactions).toEqual([{
|
||||||
name: '👍',
|
name: '👍',
|
||||||
count: 1,
|
count: 1,
|
||||||
me: true,
|
me: true,
|
||||||
})]));
|
}]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
/** Validates the string as an emoji. */
|
||||||
|
const emojiSchema = z.string().refine((v) => /\p{Extended_Pictographic}/u.test(v));
|
||||||
|
|
||||||
|
/** Pleroma emoji reaction. */
|
||||||
|
const emojiReactionSchema = z.object({
|
||||||
|
name: emojiSchema,
|
||||||
|
count: z.number().nullable().catch(null),
|
||||||
|
me: z.boolean().catch(false),
|
||||||
|
});
|
||||||
|
|
||||||
|
type EmojiReaction = z.infer<typeof emojiReactionSchema>;
|
||||||
|
|
||||||
|
export { emojiReactionSchema, EmojiReaction };
|
|
@ -1,6 +1,7 @@
|
||||||
export { accountSchema, type Account } from './account';
|
export { accountSchema, type Account } from './account';
|
||||||
export { cardSchema, type Card } from './card';
|
export { cardSchema, type Card } from './card';
|
||||||
export { customEmojiSchema, type CustomEmoji } from './custom-emoji';
|
export { customEmojiSchema, type CustomEmoji } from './custom-emoji';
|
||||||
|
export { emojiReactionSchema, type EmojiReaction } from './emoji-reaction';
|
||||||
export { groupSchema, type Group } from './group';
|
export { groupSchema, type Group } from './group';
|
||||||
export { groupMemberSchema, type GroupMember } from './group-member';
|
export { groupMemberSchema, type GroupMember } from './group-member';
|
||||||
export { groupRelationshipSchema, type GroupRelationship } from './group-relationship';
|
export { groupRelationshipSchema, type GroupRelationship } from './group-relationship';
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
ChatRecord,
|
ChatRecord,
|
||||||
ChatMessageRecord,
|
ChatMessageRecord,
|
||||||
EmojiRecord,
|
EmojiRecord,
|
||||||
EmojiReactionRecord,
|
|
||||||
FieldRecord,
|
FieldRecord,
|
||||||
FilterRecord,
|
FilterRecord,
|
||||||
FilterKeywordRecord,
|
FilterKeywordRecord,
|
||||||
|
@ -38,7 +37,6 @@ type Attachment = ReturnType<typeof AttachmentRecord>;
|
||||||
type Chat = ReturnType<typeof ChatRecord>;
|
type Chat = ReturnType<typeof ChatRecord>;
|
||||||
type ChatMessage = ReturnType<typeof ChatMessageRecord>;
|
type ChatMessage = ReturnType<typeof ChatMessageRecord>;
|
||||||
type Emoji = ReturnType<typeof EmojiRecord>;
|
type Emoji = ReturnType<typeof EmojiRecord>;
|
||||||
type EmojiReaction = ReturnType<typeof EmojiReactionRecord>;
|
|
||||||
type Field = ReturnType<typeof FieldRecord>;
|
type Field = ReturnType<typeof FieldRecord>;
|
||||||
type Filter = ReturnType<typeof FilterRecord>;
|
type Filter = ReturnType<typeof FilterRecord>;
|
||||||
type FilterKeyword = ReturnType<typeof FilterKeywordRecord>;
|
type FilterKeyword = ReturnType<typeof FilterKeywordRecord>;
|
||||||
|
@ -81,7 +79,6 @@ export {
|
||||||
Chat,
|
Chat,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
Emoji,
|
Emoji,
|
||||||
EmojiReaction,
|
|
||||||
Field,
|
Field,
|
||||||
Filter,
|
Filter,
|
||||||
FilterKeyword,
|
FilterKeyword,
|
||||||
|
@ -105,6 +102,7 @@ export {
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
Card,
|
Card,
|
||||||
|
EmojiReaction,
|
||||||
Group,
|
Group,
|
||||||
GroupMember,
|
GroupMember,
|
||||||
GroupRelationship,
|
GroupRelationship,
|
||||||
|
|
|
@ -254,7 +254,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
||||||
/**
|
/**
|
||||||
* Ability to add reactions to chat messages.
|
* Ability to add reactions to chat messages.
|
||||||
*/
|
*/
|
||||||
chatEmojiReactions: v.software === TRUTHSOCIAL && v.build === UNRELEASED,
|
chatEmojiReactions: v.software === TRUTHSOCIAL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pleroma chats API.
|
* Pleroma chats API.
|
||||||
|
|
Loading…
Reference in New Issue