fix: 通知インジケータが光りっぱなしになる問題を修正 (#10483)

* fix(misskey-js): ストリームがstringで送信される場合があるのを修正

* pnpm run api

* force read notification

* fix competition
This commit is contained in:
tamaina 2023-04-06 06:11:59 +09:00 committed by GitHub
parent 712c60106a
commit 2650a7a5b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 22 deletions

View file

@ -43,6 +43,7 @@ export class NotificationService implements OnApplicationShutdown {
@bindThis @bindThis
public async readAllNotification( public async readAllNotification(
userId: User['id'], userId: User['id'],
force = false,
) { ) {
const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${userId}`); const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${userId}`);
@ -57,7 +58,7 @@ export class NotificationService implements OnApplicationShutdown {
this.redisClient.set(`latestReadNotification:${userId}`, latestNotificationId); this.redisClient.set(`latestReadNotification:${userId}`, latestNotificationId);
if (latestReadNotificationId == null || (latestReadNotificationId < latestNotificationId)) { if (force || latestReadNotificationId == null || (latestReadNotificationId < latestNotificationId)) {
return this.postReadAllNotifications(userId); return this.postReadAllNotifications(userId);
} }
} }
@ -95,7 +96,7 @@ export class NotificationService implements OnApplicationShutdown {
...data, ...data,
} as Notification; } as Notification;
this.redisClient.xadd( const redisIdPromise = this.redisClient.xadd(
`notificationTimeline:${notifieeId}`, `notificationTimeline:${notifieeId}`,
'MAXLEN', '~', '300', 'MAXLEN', '~', '300',
`${this.idService.parse(notification.id).date.getTime()}-*`, `${this.idService.parse(notification.id).date.getTime()}-*`,
@ -109,7 +110,7 @@ export class NotificationService implements OnApplicationShutdown {
// 2秒経っても(今回作成した)通知が既読にならなかったら「未読の通知がありますよ」イベントを発行する // 2秒経っても(今回作成した)通知が既読にならなかったら「未読の通知がありますよ」イベントを発行する
setTimeout(2000, 'unread notification', { signal: this.#shutdownController.signal }).then(async () => { setTimeout(2000, 'unread notification', { signal: this.#shutdownController.signal }).then(async () => {
const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${notifieeId}`); 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.globalEventService.publishMainStream(notifieeId, 'unreadNotification', packed);
this.pushNotificationService.pushNotification(notifieeId, 'notification', packed); this.pushNotificationService.pushNotification(notifieeId, 'notification', packed);

View file

@ -24,7 +24,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private notificationService: NotificationService, private notificationService: NotificationService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
this.notificationService.readAllNotification(me.id); this.notificationService.readAllNotification(me.id, true);
}); });
} }
} }

View file

@ -166,8 +166,6 @@ export type Channels = {
readAllAntennas: () => void; readAllAntennas: () => void;
unreadAntenna: (payload: Antenna) => void; unreadAntenna: (payload: Antenna) => void;
readAllAnnouncements: () => void; readAllAnnouncements: () => void;
readAllChannels: () => void;
unreadChannel: (payload: Note['id']) => void;
myTokenRegenerated: () => void; myTokenRegenerated: () => void;
reversiNoInvites: () => void; reversiNoInvites: () => void;
reversiInvited: (payload: FIXME) => void; reversiInvited: (payload: FIXME) => void;
@ -1857,12 +1855,6 @@ export type Endpoints = {
req: NoParams; req: NoParams;
res: null; res: null;
}; };
'notifications/read': {
req: {
notificationId: Notification_2['id'];
};
res: null;
};
'page-push': { 'page-push': {
req: { req: {
pageId: Page['id']; pageId: Page['id'];
@ -2361,7 +2353,6 @@ type MeDetailed = UserDetailed & {
hasPendingReceivedFollowRequest: boolean; hasPendingReceivedFollowRequest: boolean;
hasUnreadAnnouncement: boolean; hasUnreadAnnouncement: boolean;
hasUnreadAntenna: boolean; hasUnreadAntenna: boolean;
hasUnreadChannel: boolean;
hasUnreadMentions: boolean; hasUnreadMentions: boolean;
hasUnreadMessagingMessage: boolean; hasUnreadMessagingMessage: boolean;
hasUnreadNotification: boolean; hasUnreadNotification: boolean;
@ -2618,7 +2609,11 @@ export class Stream extends EventEmitter<StreamEvents> {
// (undocumented) // (undocumented)
removeSharedConnectionPool(pool: Pool): void; removeSharedConnectionPool(pool: Pool): void;
// (undocumented) // (undocumented)
send(typeOrPayload: any, payload?: any): void; send(typeOrPayload: string): void;
// (undocumented)
send(typeOrPayload: string, payload: any): void;
// (undocumented)
send(typeOrPayload: Record<string, any> | any[]): void;
// (undocumented) // (undocumented)
state: 'initializing' | 'reconnecting' | 'connected'; state: 'initializing' | 'reconnecting' | 'connected';
// (undocumented) // (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: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: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/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:35:4 - (ae-forgotten-export) The symbol "FIXME" 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) // (No @packageDocumentation comment for this package)

View file

@ -169,14 +169,21 @@ export default class Stream extends EventEmitter<StreamEvents> {
/** /**
* Send a message to connection * Send a message to connection
* ! JSONで行われます !
*/ */
public send(typeOrPayload: any, payload?: any): void { public send(typeOrPayload: string): void
const data = payload === undefined ? typeOrPayload : { public send(typeOrPayload: string, payload: any): void
public send(typeOrPayload: Record<string, any> | any[]): void
public send(typeOrPayload: string | Record<string, any> | any[], payload?: any): void {
if (typeof typeOrPayload === 'string') {
this.stream.send(JSON.stringify({
type: typeOrPayload, type: typeOrPayload,
body: payload, ...(payload === undefined ? {} : { body: payload }),
}; }));
return;
}
this.stream.send(JSON.stringify(data)); this.stream.send(JSON.stringify(typeOrPayload));
} }
/** /**