summaryrefslogtreecommitdiff
path: root/packages/backend/src/core/NoteEditService.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/src/core/NoteEditService.ts')
-rw-r--r--packages/backend/src/core/NoteEditService.ts50
1 files changed, 42 insertions, 8 deletions
diff --git a/packages/backend/src/core/NoteEditService.ts b/packages/backend/src/core/NoteEditService.ts
index a01dfec664..0cb58d04a2 100644
--- a/packages/backend/src/core/NoteEditService.ts
+++ b/packages/backend/src/core/NoteEditService.ts
@@ -298,7 +298,11 @@ export class NoteEditService implements OnApplicationShutdown {
data.visibility = 'home';
}
- if (data.renote) {
+ if (this.isRenote(data)) {
+ if (data.renote.id === oldnote.id) {
+ throw new Error("A note can't renote itself");
+ }
+
switch (data.renote.visibility) {
case 'public':
// public noteは無条件にrenote可能
@@ -325,7 +329,7 @@ export class NoteEditService implements OnApplicationShutdown {
}
// Check blocking
- if (data.renote && !this.isQuote(data)) {
+ if (this.isRenote(data) && !this.isQuote(data)) {
if (data.renote.userHost === null) {
if (data.renote.userId !== user.id) {
const blocked = await this.userBlockingService.checkBlocked(data.renote.userId, user.id);
@@ -342,7 +346,7 @@ export class NoteEditService implements OnApplicationShutdown {
}
// ローカルのみをRenoteしたらローカルのみにする
- if (data.renote && data.renote.localOnly && data.channel == null) {
+ if (this.isRenote(data) && data.renote.localOnly && data.channel == null) {
data.localOnly = true;
}
@@ -524,6 +528,7 @@ export class NoteEditService implements OnApplicationShutdown {
noteVisibility: note.visibility,
userId: user.id,
userHost: user.host,
+ channelId: data.channel ? data.channel.id : null,
});
if (!oldnote.hasPoll) {
@@ -689,7 +694,7 @@ export class NoteEditService implements OnApplicationShutdown {
}
// 投稿がRenoteかつ投稿者がローカルユーザーかつRenote元の投稿の投稿者がリモートユーザーなら配送
- if (data.renote && data.renote.userHost !== null) {
+ if (this.isRenote(data) && data.renote.userHost !== null) {
const u = await this.usersRepository.findOneBy({ id: data.renote.userId });
if (u && this.userEntityService.isRemoteUser(u)) dm.addDirectRecipe(u);
}
@@ -699,6 +704,24 @@ export class NoteEditService implements OnApplicationShutdown {
dm.addFollowersRecipe();
}
+ if (['public', 'home'].includes(note.visibility)) {
+ // Send edit event to all users who replied to,
+ // renoted a post or reacted to a note.
+ const noteId = note.id;
+ const users = await this.usersRepository.createQueryBuilder()
+ .where(
+ 'id IN (SELECT "userId" FROM note WHERE "replyId" = :noteId OR "renoteId" = :noteId UNION SELECT "userId" FROM note_reaction WHERE "noteId" = :noteId)',
+ { noteId },
+ )
+ .andWhere('host IS NOT NULL')
+ .getMany();
+ for (const u of users) {
+ // User was verified to be remote by checking
+ // whether host IS NOT NULL in SQL query.
+ dm.addDirectRecipe(u as MiRemoteUser);
+ }
+ }
+
if (['public'].includes(note.visibility)) {
this.relayService.deliverToRelays(user, noteActivity);
}
@@ -732,9 +755,20 @@ export class NoteEditService implements OnApplicationShutdown {
}
@bindThis
- private isQuote(note: Option): note is Option & { renote: MiNote } {
- // sync with misc/is-quote.ts
- return !!note.renote && (!!note.text || !!note.cw || (!!note.files && !!note.files.length) || !!note.poll);
+ private isRenote(note: Option): note is Option & { renote: MiNote } {
+ return note.renote != null;
+ }
+
+ @bindThis
+ private isQuote(note: Option & { renote: MiNote }): note is Option & { renote: MiNote } & (
+ { text: string } | { cw: string } | { reply: MiNote } | { poll: IPoll } | { files: MiDriveFile[] }
+ ) {
+ // NOTE: SYNC WITH misc/is-quote.ts
+ return note.text != null ||
+ note.reply != null ||
+ note.cw != null ||
+ note.poll != null ||
+ (note.files != null && note.files.length > 0);
}
@bindThis
@@ -783,7 +817,7 @@ export class NoteEditService implements OnApplicationShutdown {
const user = await this.usersRepository.findOneBy({ id: note.userId });
if (user == null) throw new Error('user not found');
- const content = data.renote && !this.isQuote(data)
+ const content = this.isRenote(data) && !this.isQuote(data)
? this.apRendererService.renderAnnounce(data.renote.uri ? data.renote.uri : `${this.config.url}/notes/${data.renote.id}`, note)
: this.apRendererService.renderUpdate(await this.apRendererService.renderUpNote(note, false), user);