Paginate notifications
This commit is contained in:
parent
8695d3e40e
commit
982c20d1fa
3 changed files with 104 additions and 18 deletions
|
|
@ -6,14 +6,18 @@ import {
|
|||
fetchThreadTitles,
|
||||
parseNotification,
|
||||
type Notification,
|
||||
type NotificationPage,
|
||||
} from "$lib/forum/notifications";
|
||||
|
||||
export type { Notification };
|
||||
|
||||
const SEEN_KEY = "notifications_seen";
|
||||
const scope = () => (MODE === "simple" ? GROUP_ID : undefined);
|
||||
|
||||
let pubkey = $state<string | null>(null);
|
||||
let items = $state<Notification[] | null>(null);
|
||||
let done = $state(true);
|
||||
let loadingMore = $state(false);
|
||||
let seenAt = $state(0);
|
||||
let liveSub: { close(): void } | null = null;
|
||||
let req = 0; // supersedes an in-flight load on login/logout
|
||||
|
|
@ -33,6 +37,12 @@ export const notificationsStore = {
|
|||
get items() {
|
||||
return items;
|
||||
},
|
||||
get done() {
|
||||
return done;
|
||||
},
|
||||
get loadingMore() {
|
||||
return loadingMore;
|
||||
},
|
||||
get seenAt() {
|
||||
return seenAt;
|
||||
},
|
||||
|
|
@ -55,23 +65,24 @@ export async function startNotifications(pk: string) {
|
|||
pubkey = pk;
|
||||
seenAt = readSeen(pk);
|
||||
const current = ++req;
|
||||
const scope = MODE === "simple" ? GROUP_ID : undefined;
|
||||
const groupId = scope();
|
||||
|
||||
let result: Notification[] = [];
|
||||
let result: NotificationPage = { items: [], done: true };
|
||||
try {
|
||||
result = await fetchNotifications(queryForum, pk, scope);
|
||||
result = await fetchNotifications(queryForum, pk, { groupId });
|
||||
} catch (e) {
|
||||
console.error("[notifications] load failed", e);
|
||||
}
|
||||
if (current !== req) return;
|
||||
items = result;
|
||||
for (const n of result) ensureProfile(n.pubkey);
|
||||
items = result.items;
|
||||
done = result.done;
|
||||
for (const n of result.items) ensureProfile(n.pubkey);
|
||||
|
||||
liveSub = subscribeForum(
|
||||
{
|
||||
kinds: [1111, 9],
|
||||
"#p": [pk],
|
||||
...(scope ? { "#h": [scope] } : {}),
|
||||
...(groupId ? { "#h": [groupId] } : {}),
|
||||
since: Math.floor(Date.now() / 1000),
|
||||
},
|
||||
{
|
||||
|
|
@ -97,9 +108,35 @@ export function stopNotifications() {
|
|||
liveSub = null;
|
||||
pubkey = null;
|
||||
items = null;
|
||||
done = true;
|
||||
loadingMore = false;
|
||||
seenAt = 0;
|
||||
}
|
||||
|
||||
// Append the next page of older notifications.
|
||||
export async function loadMoreNotifications() {
|
||||
const pk = pubkey;
|
||||
const current = req;
|
||||
if (!pk || !items || done || loadingMore) return;
|
||||
loadingMore = true;
|
||||
const oldest = items[items.length - 1];
|
||||
try {
|
||||
const next = await fetchNotifications(queryForum, pk, {
|
||||
groupId: scope(),
|
||||
until: oldest?.createdAt,
|
||||
exclude: new Set(items.map((n) => n.id)),
|
||||
});
|
||||
if (current !== req || !items) return;
|
||||
items = [...items, ...next.items];
|
||||
done = next.done;
|
||||
for (const n of next.items) ensureProfile(n.pubkey);
|
||||
} catch (e) {
|
||||
console.error("[notifications] failed to load more", e);
|
||||
} finally {
|
||||
if (current === req) loadingMore = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Everything loaded so far counts as read.
|
||||
export function markNotificationsSeen() {
|
||||
if (!pubkey) return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue