summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/stream
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2025-03-25 16:14:53 -0400
committerHazelnoot <acomputerdog@gmail.com>2025-03-25 16:14:53 -0400
commitd8908ef2d8fa84d8e0fc1d30ab90a600a3d88054 (patch)
tree0c8d3e0385ce7021c7187ef8b608f1abd87496e5 /packages/backend/src/server/api/stream
parentmerge: enhance: Update de-DE.yml (!949) (diff)
parentenhance(frontend): 設定の移行を手動でトリガーできるように (diff)
downloadsharkey-d8908ef2d8fa84d8e0fc1d30ab90a600a3d88054.tar.gz
sharkey-d8908ef2d8fa84d8e0fc1d30ab90a600a3d88054.tar.bz2
sharkey-d8908ef2d8fa84d8e0fc1d30ab90a600a3d88054.zip
merge upstream
Diffstat (limited to 'packages/backend/src/server/api/stream')
-rw-r--r--packages/backend/src/server/api/stream/ChannelsService.ts6
-rw-r--r--packages/backend/src/server/api/stream/Connection.ts17
-rw-r--r--packages/backend/src/server/api/stream/channel.ts6
-rw-r--r--packages/backend/src/server/api/stream/channels/chat-room.ts78
-rw-r--r--packages/backend/src/server/api/stream/channels/chat-user.ts78
5 files changed, 166 insertions, 19 deletions
diff --git a/packages/backend/src/server/api/stream/ChannelsService.ts b/packages/backend/src/server/api/stream/ChannelsService.ts
index 83c5fcdf52..13934628a8 100644
--- a/packages/backend/src/server/api/stream/ChannelsService.ts
+++ b/packages/backend/src/server/api/stream/ChannelsService.ts
@@ -20,6 +20,8 @@ import { AntennaChannelService } from './channels/antenna.js';
import { DriveChannelService } from './channels/drive.js';
import { HashtagChannelService } from './channels/hashtag.js';
import { RoleTimelineChannelService } from './channels/role-timeline.js';
+import { ChatUserChannelService } from './channels/chat-user.js';
+import { ChatRoomChannelService } from './channels/chat-room.js';
import { ReversiChannelService } from './channels/reversi.js';
import { ReversiGameChannelService } from './channels/reversi-game.js';
import { type MiChannelService } from './channel.js';
@@ -42,6 +44,8 @@ export class ChannelsService {
private serverStatsChannelService: ServerStatsChannelService,
private queueStatsChannelService: QueueStatsChannelService,
private adminChannelService: AdminChannelService,
+ private chatUserChannelService: ChatUserChannelService,
+ private chatRoomChannelService: ChatRoomChannelService,
private reversiChannelService: ReversiChannelService,
private reversiGameChannelService: ReversiGameChannelService,
) {
@@ -65,6 +69,8 @@ export class ChannelsService {
case 'serverStats': return this.serverStatsChannelService;
case 'queueStats': return this.queueStatsChannelService;
case 'admin': return this.adminChannelService;
+ case 'chatUser': return this.chatUserChannelService;
+ case 'chatRoom': return this.chatRoomChannelService;
case 'reversi': return this.reversiChannelService;
case 'reversiGame': return this.reversiGameChannelService;
diff --git a/packages/backend/src/server/api/stream/Connection.ts b/packages/backend/src/server/api/stream/Connection.ts
index e98e2a2f3f..a1ea947d20 100644
--- a/packages/backend/src/server/api/stream/Connection.ts
+++ b/packages/backend/src/server/api/stream/Connection.ts
@@ -7,7 +7,6 @@ import * as WebSocket from 'ws';
import type { MiUser } from '@/models/User.js';
import type { MiAccessToken } from '@/models/AccessToken.js';
import type { Packed } from '@/misc/json-schema.js';
-import type { NoteReadService } from '@/core/NoteReadService.js';
import type { NotificationService } from '@/core/NotificationService.js';
import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js';
@@ -51,7 +50,6 @@ export default class Connection {
constructor(
private channelsService: ChannelsService,
- private noteReadService: NoteReadService,
private notificationService: NotificationService,
private cacheService: CacheService,
private channelFollowingService: ChannelFollowingService,
@@ -154,7 +152,7 @@ export default class Connection {
case 'readNotification': this.onReadNotification(body); break;
case 'subNote': this.onSubscribeNote(body); break;
case 's': this.onSubscribeNote(body); break; // alias
- case 'sr': this.onSubscribeNote(body); this.readNote(body); break;
+ case 'sr': this.onSubscribeNote(body); break;
case 'unsubNote': this.onUnsubscribeNote(body); break;
case 'un': this.onUnsubscribeNote(body); break; // alias
case 'connect': this.onChannelConnectRequested(body); break;
@@ -190,19 +188,6 @@ export default class Connection {
}
@bindThis
- private readNote(body: JsonValue | undefined) {
- if (!isJsonObject(body)) return;
- const id = body.id;
-
- const note = this.cachedNotes.find(n => n.id === id);
- if (note == null) return;
-
- if (this.user && (note.userId !== this.user.id)) {
- this.noteReadService.read(this.user.id, [note]);
- }
- }
-
- @bindThis
private onReadNotification(payload: JsonValue | undefined) {
this.notificationService.readAllNotification(this.user!.id);
}
diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts
index 5189c86de8..9af816dfbb 100644
--- a/packages/backend/src/server/api/stream/channel.ts
+++ b/packages/backend/src/server/api/stream/channel.ts
@@ -106,8 +106,8 @@ export default abstract class Channel {
this.noteEntityService = noteEntityService;
}
- public send(payload: { type: string, body: JsonValue }): void
- public send(type: string, payload: JsonValue): void
+ public send(payload: { type: string, body: JsonValue }): void;
+ public send(type: string, payload: JsonValue): void;
@bindThis
public send(typeOrPayload: { type: string, body: JsonValue } | string, payload?: JsonValue) {
const type = payload === undefined ? (typeOrPayload as { type: string, body: JsonValue }).type : (typeOrPayload as string);
@@ -166,4 +166,4 @@ export type MiChannelService<T extends boolean> = {
requireCredential: T;
kind: T extends true ? string : string | null | undefined;
create: (id: string, connection: Connection) => Channel;
-}
+};
diff --git a/packages/backend/src/server/api/stream/channels/chat-room.ts b/packages/backend/src/server/api/stream/channels/chat-room.ts
new file mode 100644
index 0000000000..e989969345
--- /dev/null
+++ b/packages/backend/src/server/api/stream/channels/chat-room.ts
@@ -0,0 +1,78 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { Injectable } from '@nestjs/common';
+import { bindThis } from '@/decorators.js';
+import type { GlobalEvents } from '@/core/GlobalEventService.js';
+import type { JsonObject } from '@/misc/json-value.js';
+import { ChatService } from '@/core/ChatService.js';
+import Channel, { type MiChannelService } from '../channel.js';
+
+class ChatRoomChannel extends Channel {
+ public readonly chName = 'chatRoom';
+ public static shouldShare = false;
+ public static requireCredential = true as const;
+ public static kind = 'read:chat';
+ private roomId: string;
+
+ constructor(
+ private chatService: ChatService,
+
+ id: string,
+ connection: Channel['connection'],
+ ) {
+ super(id, connection);
+ }
+
+ @bindThis
+ public async init(params: JsonObject) {
+ if (typeof params.roomId !== 'string') return;
+ this.roomId = params.roomId;
+
+ this.subscriber.on(`chatRoomStream:${this.roomId}`, this.onEvent);
+ }
+
+ @bindThis
+ private async onEvent(data: GlobalEvents['chat']['payload']) {
+ this.send(data.type, data.body);
+ }
+
+ @bindThis
+ public onMessage(type: string, body: any) {
+ switch (type) {
+ case 'read':
+ if (this.roomId) {
+ this.chatService.readRoomChatMessage(this.user!.id, this.roomId);
+ }
+ break;
+ }
+ }
+
+ @bindThis
+ public dispose() {
+ this.subscriber.off(`chatRoomStream:${this.roomId}`, this.onEvent);
+ }
+}
+
+@Injectable()
+export class ChatRoomChannelService implements MiChannelService<true> {
+ public readonly shouldShare = ChatRoomChannel.shouldShare;
+ public readonly requireCredential = ChatRoomChannel.requireCredential;
+ public readonly kind = ChatRoomChannel.kind;
+
+ constructor(
+ private chatService: ChatService,
+ ) {
+ }
+
+ @bindThis
+ public create(id: string, connection: Channel['connection']): ChatRoomChannel {
+ return new ChatRoomChannel(
+ this.chatService,
+ id,
+ connection,
+ );
+ }
+}
diff --git a/packages/backend/src/server/api/stream/channels/chat-user.ts b/packages/backend/src/server/api/stream/channels/chat-user.ts
new file mode 100644
index 0000000000..c4e898cd5b
--- /dev/null
+++ b/packages/backend/src/server/api/stream/channels/chat-user.ts
@@ -0,0 +1,78 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { Injectable } from '@nestjs/common';
+import { bindThis } from '@/decorators.js';
+import type { GlobalEvents } from '@/core/GlobalEventService.js';
+import type { JsonObject } from '@/misc/json-value.js';
+import { ChatService } from '@/core/ChatService.js';
+import Channel, { type MiChannelService } from '../channel.js';
+
+class ChatUserChannel extends Channel {
+ public readonly chName = 'chatUser';
+ public static shouldShare = false;
+ public static requireCredential = true as const;
+ public static kind = 'read:chat';
+ private otherId: string;
+
+ constructor(
+ private chatService: ChatService,
+
+ id: string,
+ connection: Channel['connection'],
+ ) {
+ super(id, connection);
+ }
+
+ @bindThis
+ public async init(params: JsonObject) {
+ if (typeof params.otherId !== 'string') return;
+ this.otherId = params.otherId;
+
+ this.subscriber.on(`chatUserStream:${this.user!.id}-${this.otherId}`, this.onEvent);
+ }
+
+ @bindThis
+ private async onEvent(data: GlobalEvents['chat']['payload']) {
+ this.send(data.type, data.body);
+ }
+
+ @bindThis
+ public onMessage(type: string, body: any) {
+ switch (type) {
+ case 'read':
+ if (this.otherId) {
+ this.chatService.readUserChatMessage(this.user!.id, this.otherId);
+ }
+ break;
+ }
+ }
+
+ @bindThis
+ public dispose() {
+ this.subscriber.off(`chatUserStream:${this.user!.id}-${this.otherId}`, this.onEvent);
+ }
+}
+
+@Injectable()
+export class ChatUserChannelService implements MiChannelService<true> {
+ public readonly shouldShare = ChatUserChannel.shouldShare;
+ public readonly requireCredential = ChatUserChannel.requireCredential;
+ public readonly kind = ChatUserChannel.kind;
+
+ constructor(
+ private chatService: ChatService,
+ ) {
+ }
+
+ @bindThis
+ public create(id: string, connection: Channel['connection']): ChatUserChannel {
+ return new ChatUserChannel(
+ this.chatService,
+ id,
+ connection,
+ );
+ }
+}