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,