191 lines · 7.0 KB
import { Link } from "@tanstack/react-router";
import { describeActivity } from "~/components/ActivityFeed";
import { Panel } from "~/ui/Panel";
import { RelativeTime } from "~/ui/RelativeTime";
import { TextLink } from "~/ui/TextLink";
import type { getContributions } from "~/fns/contributions";

type Detail = NonNullable<NonNullable<Awaited<ReturnType<typeof getContributions>>>["detail"]>;
type Activity = Detail["activity"]["items"][number];

const SHORT_SHA = 7;
const DATE_FORMAT = new Intl.DateTimeFormat(undefined, {
  weekday: "long",
  month: "long",
  day: "numeric",
  year: "numeric",
  timeZone: "UTC",
});

function plural(count: number, word: string): string {
  return `${count} ${word}${count === 1 ? "" : "s"}`;
}

/** Issue and pull request activity links to the thread; everything else to the repository. */
function ActivityLink({ item }: { item: Activity }) {
  const number = typeof item.data.number === "number" ? item.data.number : null;
  const isPull = item.kind.startsWith("pull_") || item.data.isPull === true;
  const params = { owner: item.repo.owner, repo: item.repo.name };
  const label = describeActivity(item);
  if (number !== null && isPull) {
    return (
      <TextLink to="/$owner/$repo/pull/$number" params={{ ...params, number: String(number) }}>
        {label}
      </TextLink>
    );
  }
  if (number !== null && (item.kind.startsWith("issue_") || item.kind === "comment")) {
    return (
      <TextLink to="/$owner/$repo/issues/$number" params={{ ...params, number: String(number) }}>
        {label}