useTimeline: use masto's Paginator
This commit is contained in:
		
							parent
							
								
									e8fcc40bde
								
							
						
					
					
						commit
						88a81e4904
					
				
					 1 changed files with 28 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -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") {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue