diff --git a/src/masto/timelines.ts b/src/masto/timelines.ts index 55d1276..917ecf7 100644 --- a/src/masto/timelines.ts +++ b/src/masto/timelines.ts @@ -14,55 +14,49 @@ type Timeline = { }; export function useTimeline(timeline: Accessor) { - let minId: string | undefined; - let maxId: string | undefined; let otl: Timeline | undefined; - const idSet = new Set(); + let npager: mastodon.Paginator | undefined; + let opager: mastodon.Paginator | undefined; const [snapshot, { refetch }] = createResource< - { records: mastodon.v1.Status[]; direction: "old" | "new" }, + { + records: mastodon.v1.Status[]; + direction: "new" | "old"; + tlChanged: boolean; + }, [Timeline], TimelineFetchTips | undefined >( () => [timeline()] as const, async ([tl], info) => { + let tlChanged = false; if (otl !== tl) { - minId = undefined; - maxId = undefined; - idSet.clear(); + console.debug("timeline reset"); + npager = opager = undefined; otl = tl; + tlChanged = true; } const direction = typeof info.refetching !== "boolean" - ? info.refetching?.direction + ? (info.refetching?.direction ?? "old") : "old"; - const pager = await tl.list( - direction === "old" - ? { - maxId: minId, - } - : { - minId: maxId, - }, - ); - const diff = pager.filter((x) => !idSet.has(x.id)); - for (const v of diff.map((x) => x.id)) { - idSet.add(v); - } if (direction === "old") { - minId = pager[pager.length - 1]?.id; - if (!maxId && pager.length > 0) { - maxId = pager[0].id; + if (!opager) { + opager = tl.list({}).setDirection("next"); } + const next = await opager.next(); return { - direction: "old" as const, - records: diff, + direction, + records: next.value ?? [], + end: next.done, + tlChanged, }; } else { - maxId = pager.length > 0 ? pager[0].id : undefined; - if (!minId && pager.length > 0) { - minId = pager[pager.length - 1]?.id; + if (!npager) { + npager = tl.list({}).setDirection("prev"); } - return { direction: "new" as const, records: diff }; + const next = await npager.next(); + const page = next.value ?? []; + return { direction, records: page, end: next.done, tlChanged }; } }, ); @@ -72,7 +66,10 @@ export function useTimeline(timeline: Accessor) { createEffect(() => { const shot = snapshot(); if (!shot) return; - const { direction, records } = shot; + const { direction, records, tlChanged } = shot; + if (tlChanged) { + setStore(() => []); + } if (direction == "new") { setStore((x) => [...records, ...x]); } else if (direction == "old") {