diff --git a/packages/backend/src/core/NotificationService.ts b/packages/backend/src/core/NotificationService.ts index 366dc08c02..c44dddea41 100644 --- a/packages/backend/src/core/NotificationService.ts +++ b/packages/backend/src/core/NotificationService.ts @@ -43,6 +43,7 @@ export class NotificationService implements OnApplicationShutdown { @bindThis public async readAllNotification( userId: User['id'], + force = false, ) { const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${userId}`); @@ -57,7 +58,7 @@ export class NotificationService implements OnApplicationShutdown { this.redisClient.set(`latestReadNotification:${userId}`, latestNotificationId); - if (latestReadNotificationId == null || (latestReadNotificationId < latestNotificationId)) { + if (force || latestReadNotificationId == null || (latestReadNotificationId < latestNotificationId)) { return this.postReadAllNotifications(userId); } } @@ -95,7 +96,7 @@ export class NotificationService implements OnApplicationShutdown { ...data, } as Notification; - this.redisClient.xadd( + const redisIdPromise = this.redisClient.xadd( `notificationTimeline:${notifieeId}`, 'MAXLEN', '~', '300', `${this.idService.parse(notification.id).date.getTime()}-*`, @@ -109,7 +110,7 @@ export class NotificationService implements OnApplicationShutdown { // 2秒経っても(今回作成した)通知が既読にならなかったら「未読の通知がありますよ」イベントを発行する setTimeout(2000, 'unread notification', { signal: this.#shutdownController.signal }).then(async () => { const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${notifieeId}`); - if (latestReadNotificationId && (latestReadNotificationId >= notification.id)) return; + if (latestReadNotificationId && (latestReadNotificationId >= await redisIdPromise)) return; this.globalEventService.publishMainStream(notifieeId, 'unreadNotification', packed); this.pushNotificationService.pushNotification(notifieeId, 'notification', packed); diff --git a/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts b/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts index 9ba6079189..e601bf9d5b 100644 --- a/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts +++ b/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts @@ -24,7 +24,7 @@ export default class extends Endpoint { private notificationService: NotificationService, ) { super(meta, paramDef, async (ps, me) => { - this.notificationService.readAllNotification(me.id); + this.notificationService.readAllNotification(me.id, true); }); } } diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index e57484be6b..2511f14dcc 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -166,8 +166,6 @@ export type Channels = { readAllAntennas: () => void; unreadAntenna: (payload: Antenna) => void; readAllAnnouncements: () => void; - readAllChannels: () => void; - unreadChannel: (payload: Note['id']) => void; myTokenRegenerated: () => void; reversiNoInvites: () => void; reversiInvited: (payload: FIXME) => void; @@ -1857,12 +1855,6 @@ export type Endpoints = { req: NoParams; res: null; }; - 'notifications/read': { - req: { - notificationId: Notification_2['id']; - }; - res: null; - }; 'page-push': { req: { pageId: Page['id']; @@ -2361,7 +2353,6 @@ type MeDetailed = UserDetailed & { hasPendingReceivedFollowRequest: boolean; hasUnreadAnnouncement: boolean; hasUnreadAntenna: boolean; - hasUnreadChannel: boolean; hasUnreadMentions: boolean; hasUnreadMessagingMessage: boolean; hasUnreadNotification: boolean; @@ -2618,7 +2609,11 @@ export class Stream extends EventEmitter { // (undocumented) removeSharedConnectionPool(pool: Pool): void; // (undocumented) - send(typeOrPayload: any, payload?: any): void; + send(typeOrPayload: string): void; + // (undocumented) + send(typeOrPayload: string, payload: any): void; + // (undocumented) + send(typeOrPayload: Record | any[]): void; // (undocumented) state: 'initializing' | 'reconnecting' | 'connected'; // (undocumented) @@ -2714,8 +2709,8 @@ type UserSorting = '+follower' | '-follower' | '+createdAt' | '-createdAt' | '+u // // src/api.types.ts:16:32 - (ae-forgotten-export) The symbol "TODO" needs to be exported by the entry point index.d.ts // src/api.types.ts:18:25 - (ae-forgotten-export) The symbol "NoParams" needs to be exported by the entry point index.d.ts -// src/api.types.ts:595:18 - (ae-forgotten-export) The symbol "ShowUserReq" needs to be exported by the entry point index.d.ts -// src/streaming.types.ts:35:4 - (ae-forgotten-export) The symbol "FIXME" needs to be exported by the entry point index.d.ts +// src/api.types.ts:594:18 - (ae-forgotten-export) The symbol "ShowUserReq" needs to be exported by the entry point index.d.ts +// src/streaming.types.ts:33:4 - (ae-forgotten-export) The symbol "FIXME" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/packages/misskey-js/src/streaming.ts b/packages/misskey-js/src/streaming.ts index 12f386ddbf..0218b40a03 100644 --- a/packages/misskey-js/src/streaming.ts +++ b/packages/misskey-js/src/streaming.ts @@ -169,14 +169,21 @@ export default class Stream extends EventEmitter { /** * Send a message to connection + * ! ストリーム上のやり取りはすべてJSONで行われます ! */ - public send(typeOrPayload: any, payload?: any): void { - const data = payload === undefined ? typeOrPayload : { - type: typeOrPayload, - body: payload, - }; + public send(typeOrPayload: string): void + public send(typeOrPayload: string, payload: any): void + public send(typeOrPayload: Record | any[]): void + public send(typeOrPayload: string | Record | any[], payload?: any): void { + if (typeof typeOrPayload === 'string') { + this.stream.send(JSON.stringify({ + type: typeOrPayload, + ...(payload === undefined ? {} : { body: payload }), + })); + return; + } - this.stream.send(JSON.stringify(data)); + this.stream.send(JSON.stringify(typeOrPayload)); } /**