summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/stream/channels
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2025-03-24 21:32:46 +0900
committerGitHub <noreply@github.com>2025-03-24 21:32:46 +0900
commitf1f24e39d2df3135493e2c2087230b428e2d02b7 (patch)
treea5ae0e9d2cf810649b2f4e08ef4d00ce7ea91dc9 /packages/backend/src/server/api/stream/channels
parentfix(frontend): fix broken styles (diff)
downloadsharkey-f1f24e39d2df3135493e2c2087230b428e2d02b7.tar.gz
sharkey-f1f24e39d2df3135493e2c2087230b428e2d02b7.tar.bz2
sharkey-f1f24e39d2df3135493e2c2087230b428e2d02b7.zip
Feat: Chat (#15686)
* wip * wip * wip * wip * wip * wip * Update types.ts * Create 1742203321812-chat.js * wip * wip * Update room.vue * Update home.vue * Update home.vue * Update ja-JP.yml * Update index.d.ts * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update CHANGELOG.md * wip * Update home.vue * clean up * Update misskey-js.api.md * wip * wip * wip * wip * wip * wip * wip * wip * wip * lint fixes * lint * Update UserEntityService.ts * search * wip * 🎨 * wip * Update home.ownedRooms.vue * wip * Update CHANGELOG.md * Update style.scss * wip * improve performance * improve performance * Update timeline.test.ts
Diffstat (limited to 'packages/backend/src/server/api/stream/channels')
-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
2 files changed, 156 insertions, 0 deletions
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,
+ );
+ }
+}