diff options
| author | Julia <julia@insertdomain.name> | 2025-03-02 19:54:32 +0000 |
|---|---|---|
| committer | Julia <julia@insertdomain.name> | 2025-03-02 19:54:32 +0000 |
| commit | 9e13c375c5ef4103ad5ee87fea583b154e9e16f3 (patch) | |
| tree | fe9e7b1a474e22fb0c37bd68cfd260f7ba39be74 /packages/backend/src/server/api/stream | |
| parent | merge: pin corepack version (!885) (diff) | |
| parent | bump version (diff) | |
| download | sharkey-9e13c375c5ef4103ad5ee87fea583b154e9e16f3.tar.gz sharkey-9e13c375c5ef4103ad5ee87fea583b154e9e16f3.tar.bz2 sharkey-9e13c375c5ef4103ad5ee87fea583b154e9e16f3.zip | |
merge: 2025.2.2 (!927)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/927
Approved-by: Marie <github@yuugi.dev>
Approved-by: Julia <julia@insertdomain.name>
Diffstat (limited to 'packages/backend/src/server/api/stream')
19 files changed, 150 insertions, 105 deletions
diff --git a/packages/backend/src/server/api/stream/Connection.ts b/packages/backend/src/server/api/stream/Connection.ts index f102cb42e1..e98e2a2f3f 100644 --- a/packages/backend/src/server/api/stream/Connection.ts +++ b/packages/backend/src/server/api/stream/Connection.ts @@ -16,11 +16,11 @@ import type { StreamEventEmitter, GlobalEvents } from '@/core/GlobalEventService import { ChannelFollowingService } from '@/core/ChannelFollowingService.js'; import { isJsonObject } from '@/misc/json-value.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; +import { LoggerService } from '@/core/LoggerService.js'; +import type Logger from '@/logger.js'; import type { ChannelsService } from './ChannelsService.js'; import type { EventEmitter } from 'events'; import type Channel from './channel.js'; -import { LoggerService } from '@/core/LoggerService.js'; -import type Logger from '@/logger.js'; const MAX_CHANNELS_PER_CONNECTION = 32; @@ -45,8 +45,8 @@ export default class Connection { public userIdsWhoMeMutingRenotes: Set<string> = new Set(); public userMutedInstances: Set<string> = new Set(); private fetchIntervalId: NodeJS.Timeout | null = null; - private activeRateLimitRequests: number = 0; - private closingConnection: boolean = false; + private activeRateLimitRequests = 0; + private closingConnection = false; private logger: Logger; constructor( diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts index ae9c7e3e99..7a6193ccfc 100644 --- a/packages/backend/src/server/api/stream/channel.ts +++ b/packages/backend/src/server/api/stream/channel.ts @@ -6,9 +6,10 @@ import { bindThis } from '@/decorators.js'; import { isInstanceMuted } from '@/misc/is-instance-muted.js'; import { isUserRelated } from '@/misc/is-user-related.js'; -import { isRenotePacked, isQuotePacked } from '@/misc/is-renote.js'; +import { isRenotePacked, isQuotePacked, isPackedPureRenote } from '@/misc/is-renote.js'; import type { Packed } from '@/misc/json-schema.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import type Connection from './Connection.js'; /** @@ -16,6 +17,7 @@ import type Connection from './Connection.js'; */ // eslint-disable-next-line import/no-default-export export default abstract class Channel { + protected readonly noteEntityService: NoteEntityService; protected connection: Connection; public id: string; public abstract readonly chName: string; @@ -74,12 +76,29 @@ export default abstract class Channel { // 流れてきたNoteがリノートをミュートしてるユーザが行ったもの if (isRenotePacked(note) && !isQuotePacked(note) && this.userIdsWhoMeMutingRenotes.has(note.user.id)) return true; + // If it's a boost (pure renote) then we need to check the target as well + if (isPackedPureRenote(note) && note.renote && this.isNoteMutedOrBlocked(note.renote)) return true; + return false; } - constructor(id: string, connection: Connection) { + protected async hideNote(note: Packed<'Note'>): Promise<void> { + if (note.renote) { + await this.hideNote(note.renote); + } + + if (note.reply) { + await this.hideNote(note.reply); + } + + const meId = this.user?.id ?? null; + await this.noteEntityService.hideNote(note, meId); + } + + constructor(id: string, connection: Connection, noteEntityService: NoteEntityService) { this.id = id; this.connection = connection; + this.noteEntityService = noteEntityService; } public send(payload: { type: string, body: JsonValue }): void @@ -101,6 +120,44 @@ export default abstract class Channel { public dispose?(): void; public onMessage?(type: string, body: JsonValue): void; + + public async assignMyReaction(note: Packed<'Note'>): Promise<Packed<'Note'>> { + let changed = false; + // StreamingApiServerService creates a single EventEmitter per server process, + // so a new note arriving from redis gets de-serialised once per server process, + // and then that single object is passed to all active channels on each connection. + // If we didn't clone the notes here, different connections would asynchronously write + // different values to the same object, resulting in a random value being sent to each frontend. -- Dakkar + const clonedNote = { ...note }; + if (this.user && isRenotePacked(note) && !isQuotePacked(note)) { + if (note.renote && Object.keys(note.renote.reactions).length > 0) { + const myReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); + if (myReaction) { + changed = true; + clonedNote.renote = { ...note.renote }; + clonedNote.renote.myReaction = myReaction; + } + } + if (note.renote?.reply && Object.keys(note.renote.reply.reactions).length > 0) { + const myReaction = await this.noteEntityService.populateMyReaction(note.renote.reply, this.user.id); + if (myReaction) { + changed = true; + clonedNote.renote = { ...note.renote }; + clonedNote.renote.reply = { ...note.renote.reply }; + clonedNote.renote.reply.myReaction = myReaction; + } + } + } + if (this.user && note.reply && Object.keys(note.reply.reactions).length > 0) { + const myReaction = await this.noteEntityService.populateMyReaction(note.reply, this.user.id); + if (myReaction) { + changed = true; + clonedNote.reply = { ...note.reply }; + clonedNote.reply.myReaction = myReaction; + } + } + return changed ? clonedNote : note; + } } export type MiChannelService<T extends boolean> = { diff --git a/packages/backend/src/server/api/stream/channels/admin.ts b/packages/backend/src/server/api/stream/channels/admin.ts index 355d5dba21..a0140d395d 100644 --- a/packages/backend/src/server/api/stream/channels/admin.ts +++ b/packages/backend/src/server/api/stream/channels/admin.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; import type { JsonObject } from '@/misc/json-value.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import Channel, { type MiChannelService } from '../channel.js'; class AdminChannel extends Channel { @@ -30,6 +31,7 @@ export class AdminChannelService implements MiChannelService<true> { public readonly kind = AdminChannel.kind; constructor( + private readonly noteEntityService: NoteEntityService, ) { } @@ -38,6 +40,7 @@ export class AdminChannelService implements MiChannelService<true> { return new AdminChannel( id, connection, + this.noteEntityService, ); } } diff --git a/packages/backend/src/server/api/stream/channels/antenna.ts b/packages/backend/src/server/api/stream/channels/antenna.ts index 53dc7f18b6..a73d158b7f 100644 --- a/packages/backend/src/server/api/stream/channels/antenna.ts +++ b/packages/backend/src/server/api/stream/channels/antenna.ts @@ -18,12 +18,12 @@ class AntennaChannel extends Channel { private antennaId: string; constructor( - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.onEvent = this.onEvent.bind(this); } diff --git a/packages/backend/src/server/api/stream/channels/bubble-timeline.ts b/packages/backend/src/server/api/stream/channels/bubble-timeline.ts index 8693f0c6ac..5ebbdcbb86 100644 --- a/packages/backend/src/server/api/stream/channels/bubble-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/bubble-timeline.ts @@ -3,8 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; +import { Injectable } from '@nestjs/common'; import type { Packed } from '@/misc/json-schema.js'; import { MetaService } from '@/core/MetaService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; @@ -27,13 +26,12 @@ class BubbleTimelineChannel extends Channel { constructor( private metaService: MetaService, private roleService: RoleService, - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); - //this.onNote = this.onNote.bind(this); + super(id, connection, noteEntityService); } @bindThis @@ -65,16 +63,12 @@ class BubbleTimelineChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - if (this.user && isRenotePacked(note) && !isQuotePacked(note)) { - if (note.renote && Object.keys(note.renote.reactions).length > 0) { - const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); - note.renote.myReaction = myRenoteReaction; - } - } + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); - this.connection.cacheNote(note); + this.connection.cacheNote(clonedNote); - this.send('note', note); + this.send('note', clonedNote); } @bindThis diff --git a/packages/backend/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts index 9939aa49ee..ec0bc7e13a 100644 --- a/packages/backend/src/server/api/stream/channels/channel.ts +++ b/packages/backend/src/server/api/stream/channels/channel.ts @@ -7,7 +7,6 @@ import { Injectable } from '@nestjs/common'; import type { Packed } from '@/misc/json-schema.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { bindThis } from '@/decorators.js'; -import { isRenotePacked, isQuotePacked } from '@/misc/is-renote.js'; import type { JsonObject } from '@/misc/json-value.js'; import Channel, { type MiChannelService } from '../channel.js'; @@ -20,12 +19,12 @@ class ChannelChannel extends Channel { private withRenotes: boolean; constructor( - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.onNote = this.onNote.bind(this); } @@ -50,16 +49,12 @@ class ChannelChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - if (this.user && isRenotePacked(note) && !isQuotePacked(note)) { - if (note.renote && Object.keys(note.renote.reactions).length > 0) { - const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); - note.renote.myReaction = myRenoteReaction; - } - } + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); - this.connection.cacheNote(note); + this.connection.cacheNote(clonedNote); - this.send('note', note); + this.send('note', clonedNote); } @bindThis diff --git a/packages/backend/src/server/api/stream/channels/drive.ts b/packages/backend/src/server/api/stream/channels/drive.ts index 03768f3d23..fa097fdc35 100644 --- a/packages/backend/src/server/api/stream/channels/drive.ts +++ b/packages/backend/src/server/api/stream/channels/drive.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; import type { JsonObject } from '@/misc/json-value.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import Channel, { type MiChannelService } from '../channel.js'; class DriveChannel extends Channel { @@ -30,6 +31,7 @@ export class DriveChannelService implements MiChannelService<true> { public readonly kind = DriveChannel.kind; constructor( + private readonly noteEntityService: NoteEntityService, ) { } @@ -38,6 +40,7 @@ export class DriveChannelService implements MiChannelService<true> { return new DriveChannel( id, connection, + this.noteEntityService, ); } } diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts index 6fe76747ee..72a8a8b156 100644 --- a/packages/backend/src/server/api/stream/channels/global-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts @@ -24,12 +24,12 @@ class GlobalTimelineChannel extends Channel { constructor( private metaService: MetaService, private roleService: RoleService, - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.onNote = this.onNote.bind(this); } @@ -60,16 +60,12 @@ class GlobalTimelineChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - if (this.user && isRenotePacked(note) && !isQuotePacked(note)) { - if (note.renote && Object.keys(note.renote.reactions).length > 0) { - const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); - note.renote.myReaction = myRenoteReaction; - } - } + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); - this.connection.cacheNote(note); + this.connection.cacheNote(clonedNote); - this.send('note', note); + this.send('note', clonedNote); } @bindThis diff --git a/packages/backend/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts index 8105f15cb1..7c8df87721 100644 --- a/packages/backend/src/server/api/stream/channels/hashtag.ts +++ b/packages/backend/src/server/api/stream/channels/hashtag.ts @@ -8,7 +8,6 @@ import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import type { Packed } from '@/misc/json-schema.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { bindThis } from '@/decorators.js'; -import { isRenotePacked, isQuotePacked } from '@/misc/is-renote.js'; import type { JsonObject } from '@/misc/json-value.js'; import Channel, { type MiChannelService } from '../channel.js'; @@ -19,12 +18,12 @@ class HashtagChannel extends Channel { private q: string[][]; constructor( - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.onNote = this.onNote.bind(this); } @@ -46,16 +45,12 @@ class HashtagChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - if (this.user && isRenotePacked(note) && !isQuotePacked(note)) { - if (note.renote && Object.keys(note.renote.reactions).length > 0) { - const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); - note.renote.myReaction = myRenoteReaction; - } - } + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); - this.connection.cacheNote(note); + this.connection.cacheNote(clonedNote); - this.send('note', note); + this.send('note', clonedNote); } @bindThis diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts index 359ab3e223..c87a21be82 100644 --- a/packages/backend/src/server/api/stream/channels/home-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts @@ -20,12 +20,12 @@ class HomeTimelineChannel extends Channel { private withFiles: boolean; constructor( - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.onNote = this.onNote.bind(this); } @@ -81,16 +81,12 @@ class HomeTimelineChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - if (this.user && isRenotePacked(note) && !isQuotePacked(note)) { - if (note.renote && Object.keys(note.renote.reactions).length > 0) { - const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); - note.renote.myReaction = myRenoteReaction; - } - } + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); - this.connection.cacheNote(note); + this.connection.cacheNote(clonedNote); - this.send('note', note); + this.send('note', clonedNote); } @bindThis diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index 01645fe657..95b762e2b7 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -26,12 +26,12 @@ class HybridTimelineChannel extends Channel { constructor( private metaService: MetaService, private roleService: RoleService, - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.onNote = this.onNote.bind(this); } @@ -98,17 +98,12 @@ class HybridTimelineChannel extends Channel { } } - if (this.user && note.renoteId && !note.text) { - if (note.renote && Object.keys(note.renote.reactions).length > 0) { - console.log(note.renote.reactionAndUserPairCache); - const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); - note.renote.myReaction = myRenoteReaction; - } - } + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); - this.connection.cacheNote(note); + this.connection.cacheNote(clonedNote); - this.send('note', note); + this.send('note', clonedNote); } @bindThis diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts index 1f9d25b44d..b9e0a4c234 100644 --- a/packages/backend/src/server/api/stream/channels/local-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts @@ -25,12 +25,12 @@ class LocalTimelineChannel extends Channel { constructor( private metaService: MetaService, private roleService: RoleService, - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.onNote = this.onNote.bind(this); } @@ -70,16 +70,12 @@ class LocalTimelineChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - if (this.user && isRenotePacked(note) && !isQuotePacked(note)) { - if (note.renote && Object.keys(note.renote.reactions).length > 0) { - const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); - note.renote.myReaction = myRenoteReaction; - } - } + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); - this.connection.cacheNote(note); + this.connection.cacheNote(clonedNote); - this.send('note', note); + this.send('note', clonedNote); } @bindThis diff --git a/packages/backend/src/server/api/stream/channels/main.ts b/packages/backend/src/server/api/stream/channels/main.ts index 863d7f4c4e..6b144e43e4 100644 --- a/packages/backend/src/server/api/stream/channels/main.ts +++ b/packages/backend/src/server/api/stream/channels/main.ts @@ -17,12 +17,12 @@ class MainChannel extends Channel { public static kind = 'read:account'; constructor( - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); } @bindThis diff --git a/packages/backend/src/server/api/stream/channels/queue-stats.ts b/packages/backend/src/server/api/stream/channels/queue-stats.ts index 91b62255b4..a4006ab752 100644 --- a/packages/backend/src/server/api/stream/channels/queue-stats.ts +++ b/packages/backend/src/server/api/stream/channels/queue-stats.ts @@ -8,6 +8,7 @@ import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; import { isJsonObject } from '@/misc/json-value.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import Channel, { type MiChannelService } from '../channel.js'; const ev = new Xev(); @@ -17,8 +18,8 @@ class QueueStatsChannel extends Channel { public static shouldShare = true; public static requireCredential = false as const; - constructor(id: string, connection: Channel['connection']) { - super(id, connection); + constructor(id: string, connection: Channel['connection'], noteEntityService: NoteEntityService) { + super(id, connection, noteEntityService); //this.onStats = this.onStats.bind(this); //this.onMessage = this.onMessage.bind(this); } @@ -64,6 +65,7 @@ export class QueueStatsChannelService implements MiChannelService<false> { public readonly kind = QueueStatsChannel.kind; constructor( + private readonly noteEntityService: NoteEntityService, ) { } @@ -72,6 +74,7 @@ export class QueueStatsChannelService implements MiChannelService<false> { return new QueueStatsChannel( id, connection, + this.noteEntityService, ); } } diff --git a/packages/backend/src/server/api/stream/channels/reversi-game.ts b/packages/backend/src/server/api/stream/channels/reversi-game.ts index 7597a1cfa3..b7fffbe844 100644 --- a/packages/backend/src/server/api/stream/channels/reversi-game.ts +++ b/packages/backend/src/server/api/stream/channels/reversi-game.ts @@ -11,6 +11,7 @@ import { ReversiService } from '@/core/ReversiService.js'; import { ReversiGameEntityService } from '@/core/entities/ReversiGameEntityService.js'; import { isJsonObject } from '@/misc/json-value.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import Channel, { type MiChannelService } from '../channel.js'; import { reversiUpdateKeys } from 'misskey-js'; @@ -23,11 +24,12 @@ class ReversiGameChannel extends Channel { constructor( private reversiService: ReversiService, private reversiGameEntityService: ReversiGameEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); } @bindThis @@ -116,6 +118,7 @@ export class ReversiGameChannelService implements MiChannelService<false> { constructor( private reversiService: ReversiService, private reversiGameEntityService: ReversiGameEntityService, + private noteEntityService: NoteEntityService, ) { } @@ -124,6 +127,7 @@ export class ReversiGameChannelService implements MiChannelService<false> { return new ReversiGameChannel( this.reversiService, this.reversiGameEntityService, + this.noteEntityService, id, connection, ); diff --git a/packages/backend/src/server/api/stream/channels/reversi.ts b/packages/backend/src/server/api/stream/channels/reversi.ts index 6e88939724..dc73d3a3d8 100644 --- a/packages/backend/src/server/api/stream/channels/reversi.ts +++ b/packages/backend/src/server/api/stream/channels/reversi.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; import type { JsonObject } from '@/misc/json-value.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import Channel, { type MiChannelService } from '../channel.js'; class ReversiChannel extends Channel { @@ -17,8 +18,9 @@ class ReversiChannel extends Channel { constructor( id: string, connection: Channel['connection'], + noteEntityService: NoteEntityService, ) { - super(id, connection); + super(id, connection, noteEntityService); } @bindThis @@ -40,6 +42,7 @@ export class ReversiChannelService implements MiChannelService<true> { public readonly kind = ReversiChannel.kind; constructor( + private readonly noteEntityService: NoteEntityService, ) { } @@ -48,6 +51,7 @@ export class ReversiChannelService implements MiChannelService<true> { return new ReversiChannel( id, connection, + this.noteEntityService, ); } } diff --git a/packages/backend/src/server/api/stream/channels/role-timeline.ts b/packages/backend/src/server/api/stream/channels/role-timeline.ts index fcfa26c38b..14c4d96479 100644 --- a/packages/backend/src/server/api/stream/channels/role-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/role-timeline.ts @@ -18,13 +18,13 @@ class RoleTimelineChannel extends Channel { private roleId: string; constructor( - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, private roleservice: RoleService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.onNote = this.onNote.bind(this); } @@ -48,7 +48,12 @@ class RoleTimelineChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - this.send('note', note); + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); + + this.connection.cacheNote(clonedNote); + + this.send('note', clonedNote); } else { this.send(data.type, data.body); } diff --git a/packages/backend/src/server/api/stream/channels/server-stats.ts b/packages/backend/src/server/api/stream/channels/server-stats.ts index ec5352d12d..43cbf65110 100644 --- a/packages/backend/src/server/api/stream/channels/server-stats.ts +++ b/packages/backend/src/server/api/stream/channels/server-stats.ts @@ -8,6 +8,7 @@ import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; import { isJsonObject } from '@/misc/json-value.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import Channel, { type MiChannelService } from '../channel.js'; const ev = new Xev(); @@ -17,8 +18,8 @@ class ServerStatsChannel extends Channel { public static shouldShare = true; public static requireCredential = false as const; - constructor(id: string, connection: Channel['connection']) { - super(id, connection); + constructor(id: string, connection: Channel['connection'], noteEntityService: NoteEntityService) { + super(id, connection, noteEntityService); //this.onStats = this.onStats.bind(this); //this.onMessage = this.onMessage.bind(this); } @@ -62,6 +63,7 @@ export class ServerStatsChannelService implements MiChannelService<false> { public readonly kind = ServerStatsChannel.kind; constructor( + private readonly noteEntityService: NoteEntityService, ) { } @@ -70,6 +72,7 @@ export class ServerStatsChannelService implements MiChannelService<false> { return new ServerStatsChannel( id, connection, + this.noteEntityService, ); } } diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index 4f38351e94..d09a9b8d9f 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -26,12 +26,12 @@ class UserListChannel extends Channel { constructor( private userListsRepository: UserListsRepository, private userListMembershipsRepository: UserListMembershipsRepository, - private noteEntityService: NoteEntityService, + noteEntityService: NoteEntityService, id: string, connection: Channel['connection'], ) { - super(id, connection); + super(id, connection, noteEntityService); //this.updateListUsers = this.updateListUsers.bind(this); //this.onNote = this.onNote.bind(this); } @@ -111,16 +111,12 @@ class UserListChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - if (this.user && isRenotePacked(note) && !isQuotePacked(note)) { - if (note.renote && Object.keys(note.renote.reactions).length > 0) { - const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id); - note.renote.myReaction = myRenoteReaction; - } - } + const clonedNote = await this.assignMyReaction(note); + await this.hideNote(clonedNote); - this.connection.cacheNote(note); + this.connection.cacheNote(clonedNote); - this.send('note', note); + this.send('note', clonedNote); } @bindThis |