MoreChanges

tcmts.share.MoreChanges · #y6enulrj · term · runs in the browser

uses IntersectionObserver

A history entry's changes from from on, loaded as they're scrolled to: ten at a time, each ten asked for when the page comes within a screen of them, and the next ten's turn only once those are in. A merge of hundreds sends what's read.

import { EntryChangeGroup } from "#codebase/tcmts/share";
import { Suspense, useEffect, useRef, useState } from "react";

export function MoreChanges({ hash, from, total }: { hash: string; from: number; total: number }) {
  const [near, setNear] = useState(false);
  const mark = useRef<HTMLDivElement>(null);
  useEffect(() => {
    const el = mark.current;
    if (!el || near) return;
    const seen = new IntersectionObserver(
      (es) => es.some((e) => e.isIntersecting) && setNear(true),
      {
        rootMargin: "800px 0px",
      },
    );
    seen.observe(el);
    return () => seen.disconnect();
  }, [near]);
  const to = Math.min(from + 10, total);
  const left = `${total - from} more change${total - from === 1 ? "" : "s"}`;
  if (!near)
    return (
      <div ref={mark} className="box loading">
        {left}
      </div>
    );
  return (
    <Suspense fallback={<div className="box loading">Loading {left}…</div>}>
      <EntryChangeGroup hash={hash} from={from} to={to} />
      {to < total && <MoreChanges hash={hash} from={to} total={total} />}
    </Suspense>
  );
}

uses

used by