From 1c8847ac6d9b23f207ed654bdef4708e412362ad Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Tue, 9 Apr 2024 23:33:21 -1000 Subject: [PATCH] Few bugfixes --- database/entities/Status.ts | 30 ++++++++++++++++++- server/api/api/v1/accounts/[id]/statuses.ts | 4 +-- server/api/api/v1/statuses/[id]/reblog.ts | 32 ++------------------- server/api/api/v1/statuses/index.ts | 14 ++++----- 4 files changed, 38 insertions(+), 42 deletions(-) diff --git a/database/entities/Status.ts b/database/entities/Status.ts index 938796e0..11fef76f 100644 --- a/database/entities/Status.ts +++ b/database/entities/Status.ts @@ -236,6 +236,32 @@ export const parseTextMentions = async (text: string) => { }); }; +export const replaceTextMentions = async ( + text: string, + mentions: UserWithRelations[], +) => { + let finalText = text; + for (const mention of mentions) { + // Replace @username and @username@domain + if (mention.instanceId) { + finalText = finalText.replace( + new RegExp( + `@${mention.username}@${mention.instance?.base_url}`, + "g", + ), + `@${mention.username}@${mention.instance?.base_url}`, + ); + } else { + finalText = finalText.replace( + new RegExp(`@${mention.username}`, "g"), + `@${mention.username}`, + ); + } + } + + return finalText; +}; + /** * Creates a new status and saves it to the database. * @returns A promise that resolves with the new status. @@ -274,6 +300,9 @@ export const createNewStatus = async ( htmlContent = ""; } + // Replace mentions text + htmlContent = await replaceTextMentions(htmlContent, mentions ?? []); + // Parse emojis and fuse with existing emojis let foundEmojis = emojis; @@ -298,7 +327,6 @@ export const createNewStatus = async ( visibility: visibility, sensitive: is_sensitive, spoilerText: spoiler_text, - isReblog: false, // DEPRECATED FIELD emojis: { connect: foundEmojis.map((emoji) => { return { diff --git a/server/api/api/v1/accounts/[id]/statuses.ts b/server/api/api/v1/accounts/[id]/statuses.ts index 075fd6f2..59268581 100644 --- a/server/api/api/v1/accounts/[id]/statuses.ts +++ b/server/api/api/v1/accounts/[id]/statuses.ts @@ -65,7 +65,7 @@ export default apiRoute<{ { where: { authorId: id, - isReblog: false, + reblogId: null, pinnedBy: { some: { id: user.id, @@ -104,7 +104,7 @@ export default apiRoute<{ { where: { authorId: id, - isReblog: exclude_reblogs ? true : undefined, + reblogId: exclude_reblogs ? null : undefined, id: { lt: max_id, gt: min_id, diff --git a/server/api/api/v1/statuses/[id]/reblog.ts b/server/api/api/v1/statuses/[id]/reblog.ts index 65bd2a84..9f4c33fb 100644 --- a/server/api/api/v1/statuses/[id]/reblog.ts +++ b/server/api/api/v1/statuses/[id]/reblog.ts @@ -24,7 +24,6 @@ export default apiRoute<{ visibility: "public" | "unlisted" | "private"; }>(async (req, matchedRoute, extraData) => { const id = matchedRoute.params.id; - const config = await extraData.configManager.getConfig(); const { user } = extraData.auth; @@ -56,30 +55,14 @@ export default apiRoute<{ data: { authorId: user.id, reblogId: status.id, - isReblog: true, - uri: new URL( - `/statuses/FAKE-${crypto.randomUUID()}`, - config.http.base_url, - ).toString(), visibility, sensitive: false, }, include: statusAndUserRelations, }); - await client.status.update({ - where: { id: newReblog.id }, - data: { - uri: new URL( - `/statuses/${newReblog.id}`, - config.http.base_url, - ).toString(), - }, - include: statusAndUserRelations, - }); - // Create notification for reblog if reblogged user is on the same instance - if ((status.author as UserWithRelations).instanceId === user.instanceId) { + if (status.author.instanceId === user.instanceId) { await client.notification.create({ data: { accountId: user.id, @@ -90,16 +73,5 @@ export default apiRoute<{ }); } - return jsonResponse( - await statusToAPI( - { - ...newReblog, - uri: new URL( - `/statuses/${newReblog.id}`, - config.http.base_url, - ).toString(), - }, - user, - ), - ); + return jsonResponse(await statusToAPI(newReblog, user)); }); diff --git a/server/api/api/v1/statuses/index.ts b/server/api/api/v1/statuses/index.ts index c423ca9e..92779c34 100644 --- a/server/api/api/v1/statuses/index.ts +++ b/server/api/api/v1/statuses/index.ts @@ -8,6 +8,7 @@ import type { StatusWithRelations } from "~database/entities/Status"; import { createNewStatus, federateStatus, + parseTextMentions, statusToAPI, } from "~database/entities/Status"; import type { UserWithRelations } from "~database/entities/User"; @@ -169,7 +170,6 @@ export default apiRoute<{ // Get reply account and status if exists let replyStatus: StatusWithRelations | null = null; - let replyUser: UserWithRelations | null = null; let quote: StatusWithRelations | null = null; if (in_reply_to_id) { @@ -181,9 +181,6 @@ export default apiRoute<{ if (!replyStatus) { return errorResponse("Reply status not found", 404); } - - // @ts-expect-error Prisma Typescript doesn't include relations - replyUser = replyStatus.author; } if (quote_id) { @@ -216,14 +213,13 @@ export default apiRoute<{ return errorResponse("Invalid media IDs", 422); } + const mentions = await parseTextMentions(sanitizedStatus); + const newStatus = await createNewStatus( user, { - "text/html": { - content: sanitizedStatus, - }, [content_type ?? "text/plain"]: { - content: status ?? "", + content: sanitizedStatus ?? "", }, }, visibility as APIStatus["visibility"], @@ -231,7 +227,7 @@ export default apiRoute<{ spoiler_text ?? "", [], undefined, - [], + mentions, media_ids, replyStatus ?? undefined, quote ?? undefined,