Support custom emojis in statuses

This commit is contained in:
Alex Gleason 2023-05-11 23:49:32 -05:00
parent d109043440
commit 837a3ae1dd
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
2 changed files with 37 additions and 12 deletions

View File

@ -4,6 +4,17 @@ import type { Event } from './event.ts';
const optionalString = z.string().optional().catch(undefined);
/** Validates individual items in an array, dropping any that aren't valid. */
function filteredArray<T extends z.ZodTypeAny>(schema: T) {
return z.any().array().catch([])
.transform((arr) => (
arr.map((item) => {
const parsed = schema.safeParse(item);
return parsed.success ? parsed.data : undefined;
}).filter((item): item is z.infer<T> => Boolean(item))
));
}
const jsonSchema = z.string().transform((value, ctx) => {
try {
return JSON.parse(value);
@ -56,4 +67,15 @@ const relaySchema = z.custom<URL>((relay) => {
}
});
export { jsonSchema, type MetaContent, metaContentSchema, parseMetaContent, parseRelay, relaySchema };
const emojiTagSchema = z.tuple([z.literal('emoji'), z.string(), z.string().url()]);
export {
emojiTagSchema,
filteredArray,
jsonSchema,
type MetaContent,
metaContentSchema,
parseMetaContent,
parseRelay,
relaySchema,
};

View File

@ -1,6 +1,6 @@
import { findReplyTag, lodash, nip19, nip21, TTLCache, unfurl, z } from '@/deps.ts';
import { type Event } from '@/event.ts';
import { type MetaContent, parseMetaContent } from '@/schema.ts';
import { emojiTagSchema, filteredArray, type MetaContent, parseMetaContent } from '@/schema.ts';
import { LOCAL_DOMAIN } from './config.ts';
import { getAuthor } from './client.ts';
@ -32,14 +32,6 @@ async function toAccount(event: Event<0>, opts: ToAccountOpts = {}) {
//
}
const emojis = event.tags
.filter((tag) => tag[0] === 'emoji')
.map((tag) => ({
shortcode: tag[1],
static_url: tag[2],
url: tag[2],
}));
return {
id: pubkey,
acct: parsed05?.handle || npub,
@ -48,7 +40,7 @@ async function toAccount(event: Event<0>, opts: ToAccountOpts = {}) {
bot: false,
created_at: event ? new Date(event.created_at * 1000).toISOString() : new Date().toISOString(),
display_name: name,
emojis,
emojis: toEmojis(event),
fields: [],
follow_requests_count: 0,
followers_count: 0,
@ -146,7 +138,7 @@ async function toStatus(event: Event<1>) {
media_attachments: mediaLinks.map(renderAttachment),
mentions,
tags: [],
emojis: [],
emojis: toEmojis(event),
poll: null,
uri: `${LOCAL_DOMAIN}/posts/${event.id}`,
url: `${LOCAL_DOMAIN}/posts/${event.id}`,
@ -243,4 +235,15 @@ function unfurlCardCached(url: string): Promise<PreviewCard | null> {
return card;
}
function toEmojis(event: Event) {
const emojiTags = event.tags.filter((tag) => tag[0] === 'emoji');
return filteredArray(emojiTagSchema).parse(emojiTags)
.map((tag) => ({
shortcode: tag[1],
static_url: tag[2],
url: tag[2],
}));
}
export { toAccount, toStatus };