import { Avatar } from "~/ui/Avatar";
import { EmptyState } from "~/ui/EmptyState";
import { RelativeTime } from "~/ui/RelativeTime";
import type { JsonValue } from "~/lib/types";
import { TextLink } from "~/ui/TextLink";
export type FeedItem = {
id: string;
actor: { name: string };
repo: { owner: string; name: string } | null;
kind: string;
data: { [key: string]: JsonValue };
createdAt: number;
};
function text(value: JsonValue | undefined): string {
return typeof value === "string" || typeof value === "number" ? String(value) : "";
}
/** One-line description of an activity row, e.g. "opened pull request #4 Fix parser". */
export function describeActivity(item: Pick<FeedItem, "kind" | "data">): string {
const { data } = item;
switch (item.kind) {
case "push":
return `pushed ${text(data.total)} commit(s) to ${text(data.ref)}`;
case "ref_created":
return `created ${text(data.refType)} ${text(data.ref)}`;
case "ref_deleted":
return `deleted ${text(data.refType)} ${text(data.ref)}`;
case "repo_created":
return "created repository";
case "repo_imported":
return `imported from ${text(data.source)}`;
case "repo_forked":
return `forked ${text(data.source)}`;
case "issue_opened":
return `opened issue #${text(data.number)} ${text(data.title)}`;
case "pull_opened":
return `opened pull request #${text(data.number)} ${text(data.title)}`;
case "pull_merged":