Resolve custom emojis from federated posts

This commit is contained in:
Jesse Wierzbinski 2024-04-10 15:40:43 -10:00
parent ec7b5dcbab
commit 275244b941
No known key found for this signature in database
3 changed files with 54 additions and 16 deletions

View file

@ -2,6 +2,7 @@ import type { Emoji } from "@prisma/client";
import { client } from "~database/datasource";
import type { APIEmoji } from "~types/entities/emoji";
import type * as Lysand from "lysand-types";
import { addInstanceIfNotExists } from "./Instance";
/**
* Represents an emoji entity in the database.
@ -29,16 +30,28 @@ export const parseEmojis = async (text: string): Promise<Emoji[]> => {
});
};
export const addEmojiIfNotExists = async (emoji: Lysand.Emoji) => {
/**
* Gets an emoji from the database, and fetches it from the remote instance if it doesn't exist.
* @param emoji Emoji to fetch
* @param host Host to fetch the emoji from if remote
* @returns The emoji
*/
export const fetchEmoji = async (emoji: Lysand.Emoji, host?: string) => {
const existingEmoji = await client.emoji.findFirst({
where: {
shortcode: emoji.name,
instance: null,
instance: host
? {
base_url: host,
}
: null,
},
});
if (existingEmoji) return existingEmoji;
const instance = host ? await addInstanceIfNotExists(host) : null;
return await client.emoji.create({
data: {
shortcode: emoji.name,
@ -46,6 +59,13 @@ export const addEmojiIfNotExists = async (emoji: Lysand.Emoji) => {
alt: emoji.alt || emoji.url[0].description || undefined,
content_type: Object.keys(emoji.url)[0],
visible_in_picker: true,
instance: host
? {
connect: {
id: instance?.id,
},
}
: undefined,
},
});
};

View file

@ -26,7 +26,7 @@ import {
attachmentToAPI,
attachmentToLysand,
} from "./Attachment";
import { emojiToAPI, emojiToLysand, parseEmojis } from "./Emoji";
import { emojiToAPI, emojiToLysand, fetchEmoji, parseEmojis } from "./Emoji";
import type { UserWithRelations } from "./User";
import { getUserUri, resolveUser, resolveWebFinger, userToAPI } from "./User";
import { statusAndUserRelations, userRelations } from "./relations";
@ -116,16 +116,34 @@ export const resolveStatus = async (
throw new Error("Invalid object author");
}
const attachments = (
await Promise.all(
(note.attachments ?? []).map((attachment) =>
attachmentFromLysand(attachment).catch((e) => {
console.error(e);
return null;
}),
),
)
).filter((attachment) => attachment !== null) as Attachment[];
const attachments = [];
for (const attachment of note.attachments ?? []) {
const resolvedAttachment = await attachmentFromLysand(attachment).catch(
(e) => {
console.error(e);
return null;
},
);
if (resolvedAttachment) {
attachments.push(resolvedAttachment);
}
}
const emojis = [];
for (const emoji of note.extensions?.["org.lysand:custom_emojis"]?.emojis ??
[]) {
const resolvedEmoji = await fetchEmoji(emoji).catch((e) => {
console.error(e);
return null;
});
if (resolvedEmoji) {
emojis.push(resolvedEmoji);
}
}
return await createNewStatus(
author,
@ -137,7 +155,7 @@ export const resolveStatus = async (
note.visibility as APIStatus["visibility"],
note.is_sensitive ?? false,
note.subject ?? "",
[],
emojis,
note.uri,
await Promise.all(
(note.mentions ?? [])

View file

@ -7,7 +7,7 @@ import { client } from "~database/datasource";
import type { APIAccount } from "~types/entities/account";
import type { APISource } from "~types/entities/source";
import type * as Lysand from "lysand-types";
import { addEmojiIfNotExists, emojiToAPI, emojiToLysand } from "./Emoji";
import { fetchEmoji, emojiToAPI, emojiToLysand } from "./Emoji";
import { addInstanceIfNotExists } from "./Instance";
import { userRelations } from "./relations";
import { createNewRelationship } from "./Relationship";
@ -241,7 +241,7 @@ export const resolveUser = async (uri: string) => {
const emojis = [];
for (const emoji of userEmojis) {
emojis.push(await addEmojiIfNotExists(emoji));
emojis.push(await fetchEmoji(emoji));
}
const user = await client.user.create({