2023-09-28 20:08:17 +02:00
|
|
|
import { ILocalUser } from "@/models/entities/user.js";
|
2023-09-28 18:16:11 +02:00
|
|
|
import { Notification } from "@/models/entities/notification.js";
|
|
|
|
import { notificationTypes } from "@/types.js";
|
|
|
|
import { UserConverter } from "@/server/api/mastodon/converters/user.js";
|
2023-10-07 20:29:58 +02:00
|
|
|
import { UserHelpers } from "@/server/api/mastodon/helpers/user.js";
|
2023-09-28 18:16:11 +02:00
|
|
|
import { awaitAll } from "@/prelude/await-all.js";
|
|
|
|
import { NoteConverter } from "@/server/api/mastodon/converters/note.js";
|
|
|
|
import { getNote } from "@/server/api/common/getters.js";
|
2023-10-07 20:29:58 +02:00
|
|
|
import { MastoContext } from "@/server/api/mastodon/index.js";
|
2023-09-28 18:16:11 +02:00
|
|
|
|
|
|
|
type NotificationType = typeof notificationTypes[number];
|
|
|
|
|
|
|
|
export class NotificationConverter {
|
2023-10-07 21:39:22 +02:00
|
|
|
public static async encode(notification: Notification, ctx: MastoContext): Promise<MastodonEntity.Notification> {
|
|
|
|
const localUser = ctx.user as ILocalUser;
|
2023-10-01 17:52:59 +02:00
|
|
|
if (notification.notifieeId !== localUser.id) throw new Error('User is not recipient of notification');
|
2023-09-28 18:16:11 +02:00
|
|
|
|
2023-10-01 17:52:59 +02:00
|
|
|
const account = notification.notifierId
|
2023-10-07 20:29:58 +02:00
|
|
|
? UserHelpers.getUserCached(notification.notifierId, ctx).then(p => UserConverter.encode(p, ctx))
|
|
|
|
: UserConverter.encode(localUser, ctx);
|
2023-09-28 18:16:11 +02:00
|
|
|
|
2023-10-01 17:52:59 +02:00
|
|
|
let result = {
|
|
|
|
id: notification.id,
|
|
|
|
account: account,
|
|
|
|
created_at: notification.createdAt.toISOString(),
|
|
|
|
type: this.encodeNotificationType(notification.type),
|
|
|
|
};
|
2023-09-28 18:16:11 +02:00
|
|
|
|
2023-10-01 17:52:59 +02:00
|
|
|
if (notification.note) {
|
|
|
|
const isPureRenote = notification.note.renoteId !== null && notification.note.text === null;
|
|
|
|
const encodedNote = isPureRenote
|
2023-10-07 21:39:22 +02:00
|
|
|
? getNote(notification.note.renoteId!, localUser).then(note => NoteConverter.encode(note, ctx))
|
|
|
|
: NoteConverter.encode(notification.note, ctx);
|
2023-10-01 17:52:59 +02:00
|
|
|
result = Object.assign(result, {
|
|
|
|
status: encodedNote,
|
|
|
|
});
|
|
|
|
if (result.type === 'poll') {
|
|
|
|
result = Object.assign(result, {
|
|
|
|
account: encodedNote.then(p => p.account),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (notification.reaction) {
|
|
|
|
//FIXME: Implement reactions;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return awaitAll(result);
|
|
|
|
}
|
2023-09-28 18:16:11 +02:00
|
|
|
|
2023-10-07 21:39:22 +02:00
|
|
|
public static async encodeMany(notifications: Notification[], ctx: MastoContext): Promise<MastodonEntity.Notification[]> {
|
|
|
|
const encoded = notifications.map(u => this.encode(u, ctx));
|
2023-10-01 17:52:59 +02:00
|
|
|
return Promise.all(encoded)
|
|
|
|
.then(p => p.filter(n => n !== null) as MastodonEntity.Notification[]);
|
|
|
|
}
|
2023-09-28 18:16:11 +02:00
|
|
|
|
2023-10-01 17:52:59 +02:00
|
|
|
private static encodeNotificationType(t: NotificationType): MastodonEntity.NotificationType {
|
|
|
|
//FIXME: Implement custom notification for followRequestAccepted
|
|
|
|
//FIXME: Implement mastodon notification type 'update' on misskey side
|
|
|
|
switch (t) {
|
|
|
|
case "follow":
|
|
|
|
return 'follow';
|
|
|
|
case "mention":
|
|
|
|
case "reply":
|
|
|
|
return 'mention'
|
|
|
|
case "renote":
|
|
|
|
return 'reblog';
|
|
|
|
case "quote":
|
|
|
|
return 'reblog';
|
|
|
|
case "reaction":
|
|
|
|
return 'favourite';
|
|
|
|
case "pollEnded":
|
|
|
|
return 'poll';
|
|
|
|
case "receiveFollowRequest":
|
|
|
|
return 'follow_request';
|
|
|
|
case "followRequestAccepted":
|
|
|
|
case "pollVote":
|
|
|
|
case "groupInvited":
|
|
|
|
case "app":
|
|
|
|
throw new Error(`Notification type ${t} not supported`);
|
|
|
|
}
|
|
|
|
}
|
2023-09-28 18:16:11 +02:00
|
|
|
}
|