import { i18n } from "@lingui/core";
import { t } from "@lingui/core/macro";
import { Trans, useLingui } from "@lingui/react/macro";
import type { RunActivityRow } from "@rakazo/contracts";
import { runChatTitle } from "@rakazo/core";
import { isNeedsYouStatus, runActivityLabel } from "../lib/agent-activity";
import { useRunActivity } from "../lib/run-activity";
function statusTone(status: RunActivityRow["status"]): string {
if (status === "failed") return "text-destructive";
if (status === "cancelled") return "text-muted-foreground";
if (status === "completed") return "text-success";
if (isNeedsYouStatus(status)) return "text-warning";
return "text-foreground";
}
type ActivityListProps = {
onOpenRun: (run: RunActivityRow) => void;
};
export function ActivityList({ onOpenRun }: ActivityListProps) {
const { active: activeRuns, recent: recentRuns, loaded } = useRunActivity();
const loading = !loaded;
if (loading) {
return (
Loading activity…
);
}
if (activeRuns.length === 0 && recentRuns.length === 0) {
return (
No recent activity
);
}
return (
{activeRuns.length > 0 ? (
Now
{activeRuns.map((run) => (
onOpenRun(run)} />
))}
) : null}
{recentRuns.length > 0 ? (
0 ? "mt-2" : undefined}>
Recent
{recentRuns.map((run) => (
onOpenRun(run)} />
))}
) : null}
);
}
export function ActivityRow({ run, onOpen }: { run: RunActivityRow; onOpen: () => void }) {
const { t } = useLingui();
const title = runChatTitle(run);
const label = statusLabel(run.status);
const activityLabel = t`${title}, ${label}`;
const tone = statusTone(run.status);
return (
);
}
function formatRelativeTime(iso: string, now = new Date()): string {
const date = new Date(iso);
if (Number.isNaN(date.getTime())) return "";
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
if (seconds < 45) return t`just now`;
const minutes = Math.floor(seconds / 60);
if (minutes < 60) return t`${minutes}m ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return t`${hours}h ago`;
const days = Math.floor(hours / 24);
if (days < 7) return t`${days}d ago`;
return date.toLocaleDateString(i18n.locale || "en", { month: "short", day: "numeric" });
}
function statusLabel(status: RunActivityRow["status"]): string {
if (isNeedsYouStatus(status)) return t`Needs you`;
return runActivityLabel(status);
}