From 6a6e6bfb74715eec6f4fe4a08d696fbab8223c71 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 9 Jan 2023 11:31:56 +0000 Subject: [PATCH] feat: track unread notifications using marker api (#891) --- composables/users.ts | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/composables/users.ts b/composables/users.ts index e1c50bcc..f9232206 100644 --- a/composables/users.ts +++ b/composables/users.ts @@ -256,16 +256,21 @@ export async function signout() { await masto.loginTo(currentUser.value) } -const notifications = reactive, number]>>({}) +const notifications = reactive, string[]]>>({}) export const useNotifications = () => { const id = currentUser.value?.account.id const masto = useMasto() - const clearNotifications = () => { + async function clearNotifications() { if (!id || !notifications[id]) return - notifications[id]![1] = 0 + const lastReadId = notifications[id]![1][0] + notifications[id]![1] = [] + // @ts-expect-error https://github.com/neet/masto.js/pull/793 + await masto.v1.markers.create({ + notifications: { lastReadId }, + }) } async function connect(): Promise { @@ -273,11 +278,24 @@ export const useNotifications = () => { return const stream = masto.v1.stream.streamUser() - notifications[id] = [stream, 0] - ;(await stream).on('notification', () => { + notifications[id] = [stream, []] + stream.then(s => s.on('notification', (n) => { if (notifications[id]) - notifications[id]![1]++ - }) + notifications[id]![1].unshift(n.id) + })) + + const position = await masto.v1.markers.fetch({ timeline: ['notifications'] }) + const paginator = masto.v1.notifications.list({ limit: 30 }) + do { + const result = await paginator.next() + if (result.value?.length) { + for (const notification of result.value as mastodon.v1.Notification[]) { + if (notification.id === position.notifications.lastReadId) + return + notifications[id]![1].push(notification.id) + } + } + } while (true) } function disconnect(): void { @@ -288,10 +306,13 @@ export const useNotifications = () => { } watch(currentUser, disconnect) - connect() + if (isMastoInitialised.value) + connect() + else + watchOnce(isMastoInitialised, connect) return { - notifications: computed(() => id ? notifications[id]?.[1] ?? 0 : 0), + notifications: computed(() => id ? notifications[id]?.[1].length ?? 0 : 0), disconnect, clearNotifications, }