Revert "refactor: remove note.mentionedRemoteUsers column"

This reverts commit 65797a934a.
This commit is contained in:
naskya 2024-03-18 03:29:19 +09:00
parent e4a72bbfe5
commit f7a8a58cb2
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
6 changed files with 58 additions and 44 deletions

View file

@ -1,20 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class RemoveMentionedUsersColumn1710688552234
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "note" DROP COLUMN "mentionedRemoteUsers"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "note" ADD "mentionedRemoteUsers" TEXT NOT NULL DEFAULT '[]'::text`,
);
await queryRunner.query(
`UPDATE "note" SET "mentionedRemoteUsers" = (SELECT COALESCE(json_agg(row_to_json("data"))::text, '[]') FROM (SELECT "url", "uri", "username", "host" FROM "user" JOIN "user_profile" ON "user"."id" = "user_profile". "userId" WHERE "user"."host" IS NOT NULL AND "user"."id" = ANY("note"."mentions")) AS "data")`,
);
}
}

View file

@ -172,6 +172,12 @@ export class Note {
}) })
public mentions: User["id"][]; public mentions: User["id"][];
// FIXME: WHAT IS THIS
@Column("text", {
default: "[]",
})
public mentionedRemoteUsers: string;
@Column("varchar", { @Column("varchar", {
length: 128, length: 128,
array: true, array: true,
@ -301,3 +307,10 @@ export class Note {
} }
} }
} }
export type IMentionedRemoteUsers = {
uri: string;
url?: string;
username: string;
host: string;
}[];

View file

@ -1,6 +1,6 @@
import { In, IsNull } from "typeorm"; import { In, IsNull } from "typeorm";
import config from "@/config/index.js"; import config from "@/config/index.js";
import type { Note } from "@/models/entities/note.js"; import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js";
import type { DriveFile } from "@/models/entities/drive-file.js"; import type { DriveFile } from "@/models/entities/drive-file.js";
import { DriveFiles, Notes, Users, Emojis, Polls } from "@/models/index.js"; import { DriveFiles, Notes, Users, Emojis, Polls } from "@/models/index.js";
import type { Emoji } from "@/models/entities/emoji.js"; import type { Emoji } from "@/models/entities/emoji.js";
@ -61,34 +61,33 @@ export default async function renderNote(
const attributedTo = `${config.url}/users/${note.userId}`; const attributedTo = `${config.url}/users/${note.userId}`;
const mentionedUsers = const mentions = (
note.mentions.length > 0 JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers
? await Users.findBy({ ).map((x) => x.uri);
id: In(note.mentions),
})
: [];
const mentionUris = mentionedUsers
// only remote users
.filter((user) => Users.isRemoteUser(user))
.map((user) => user.uri);
let to: string[] = []; let to: string[] = [];
let cc: string[] = []; let cc: string[] = [];
if (note.visibility === "public") { if (note.visibility === "public") {
to = ["https://www.w3.org/ns/activitystreams#Public"]; to = ["https://www.w3.org/ns/activitystreams#Public"];
cc = [`${attributedTo}/followers`].concat(mentionUris); cc = [`${attributedTo}/followers`].concat(mentions);
} else if (note.visibility === "home") { } else if (note.visibility === "home") {
to = [`${attributedTo}/followers`]; to = [`${attributedTo}/followers`];
cc = ["https://www.w3.org/ns/activitystreams#Public"].concat(mentionUris); cc = ["https://www.w3.org/ns/activitystreams#Public"].concat(mentions);
} else if (note.visibility === "followers") { } else if (note.visibility === "followers") {
to = [`${attributedTo}/followers`]; to = [`${attributedTo}/followers`];
cc = mentionUris; cc = mentions;
} else { } else {
to = mentionUris; to = mentions;
} }
const mentionedUsers =
note.mentions.length > 0
? await Users.findBy({
id: In(note.mentions),
})
: [];
const hashtagTags = (note.tags || []).map((tag) => renderHashtag(tag)); const hashtagTags = (note.tags || []).map((tag) => renderHashtag(tag));
const mentionTags = mentionedUsers.map((u) => renderMention(u)); const mentionTags = mentionedUsers.map((u) => renderMention(u));

View file

@ -134,6 +134,13 @@ export async function createMessage(
userId: message.userId, userId: message.userId,
visibility: "specified", visibility: "specified",
mentions: [recipientUser].map((u) => u.id), mentions: [recipientUser].map((u) => u.id),
mentionedRemoteUsers: JSON.stringify(
[recipientUser].map((u) => ({
uri: u.uri,
username: u.username,
host: u.host,
})),
),
} as Note; } as Note;
let renderedNote: Record<string, unknown> = await renderNote( let renderedNote: Record<string, unknown> = await renderNote(

View file

@ -18,6 +18,7 @@ import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instanc
import { extractMentions } from "@/misc/extract-mentions.js"; import { extractMentions } from "@/misc/extract-mentions.js";
import { extractCustomEmojisFromMfm } from "@/misc/extract-custom-emojis-from-mfm.js"; import { extractCustomEmojisFromMfm } from "@/misc/extract-custom-emojis-from-mfm.js";
import { extractHashtags } from "@/misc/extract-hashtags.js"; import { extractHashtags } from "@/misc/extract-hashtags.js";
import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
import { Note } from "@/models/entities/note.js"; import { Note } from "@/models/entities/note.js";
import { import {
Mutings, Mutings,
@ -750,6 +751,21 @@ async function insertNote(
// Append mentions data // Append mentions data
if (mentionedUsers.length > 0) { if (mentionedUsers.length > 0) {
insert.mentions = mentionedUsers.map((u) => u.id); insert.mentions = mentionedUsers.map((u) => u.id);
const profiles = await UserProfiles.findBy({ userId: In(insert.mentions) });
insert.mentionedRemoteUsers = JSON.stringify(
mentionedUsers
.filter((u) => Users.isRemoteUser(u))
.map((u) => {
const profile = profiles.find((p) => p.userId === u.id);
const url = profile != null ? profile.url : null;
return {
uri: u.uri,
url: url == null ? undefined : url,
username: u.username,
host: u.host,
} as IMentionedRemoteUsers[0];
}),
);
} }
// 投稿を作成 // 投稿を作成

View file

@ -1,4 +1,4 @@
import { Brackets, In, IsNull, Not } from "typeorm"; import { Brackets, In } from "typeorm";
import { publishNoteStream } from "@/services/stream.js"; import { publishNoteStream } from "@/services/stream.js";
import renderDelete from "@/remote/activitypub/renderer/delete.js"; import renderDelete from "@/remote/activitypub/renderer/delete.js";
import renderAnnounce from "@/remote/activitypub/renderer/announce.js"; import renderAnnounce from "@/remote/activitypub/renderer/announce.js";
@ -7,7 +7,7 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js";
import renderTombstone from "@/remote/activitypub/renderer/tombstone.js"; import renderTombstone from "@/remote/activitypub/renderer/tombstone.js";
import config from "@/config/index.js"; import config from "@/config/index.js";
import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js"; import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js";
import type { Note } from "@/models/entities/note.js"; import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js";
import { Notes, Users, Instances } from "@/models/index.js"; import { Notes, Users, Instances } from "@/models/index.js";
import { import {
deliverToFollowers, deliverToFollowers,
@ -147,12 +147,11 @@ async function getMentionedRemoteUsers(note: Note) {
const where = [] as any[]; const where = [] as any[];
// mention / reply / dm // mention / reply / dm
if (note.mentions.length > 0) { const uris = (
where.push({ JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers
id: In(note.mentions), ).map((x) => x.uri);
// only remote users, local users are on the server and do not need to be notified if (uris.length > 0) {
host: Not(IsNull()), where.push({ uri: In(uris) });
});
} }
// renote / quote // renote / quote