useTimeline: use masto's Paginator

This commit is contained in:
thislight 2024-08-12 22:29:55 +08:00
parent e8fcc40bde
commit 88a81e4904

View file

@ -14,55 +14,49 @@ type Timeline = {
};
export function useTimeline(timeline: Accessor<Timeline>) {
let minId: string | undefined;
let maxId: string | undefined;
let otl: Timeline | undefined;
const idSet = new Set<string>();
let npager: mastodon.Paginator<mastodon.v1.Status[], unknown> | undefined;
let opager: mastodon.Paginator<mastodon.v1.Status[], unknown> | 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<Timeline>) {
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") {