import { renderActivity } from "./activity-rail"; import { AnimatePresence, motion, useReducedMotion } from "motion/react"; import { Suspense, useEffect, useState } from "react"; import { CompactActivityContext } from "./shared"; import { defaultToolRegistry } from "./tool-renderers"; import type { ToolRegistry } from "./registry"; import { toolDisplayName } from "./tool-display-name"; import { ToolKindIcon } from "./tool-icon"; import { genericToolIconKind } from "./tool-presentation"; import { toolStepPhase } from "./tool-steps"; import type { ActivityItem } from "./types"; import { rollingActivityItem } from "./work-presentation"; import { useOpenGeniText } from "../messages/runtime"; /** One stable viewport; updates replace its content without moving the conversation. */ export function RollingActivity({ items, toolRegistry = defaultToolRegistry, previousItem, showCount = true, }: { items: ActivityItem[]; /** The standalone item visible immediately before this reel mounted. */ previousItem?: ActivityItem | undefined; toolRegistry?: ToolRegistry; /** Show "+N earlier"; off when an enclosing status line already counts steps. */ showCount?: boolean; }) { const t = useOpenGeniText(); const reduced = useReducedMotion(); const [mounted, setMounted] = useState(false); useEffect(() => setMounted(true), []); // Progress notes have their own line in the status row; the reel shows steps, advancing // with the event order so finishing a parallel tool never replays an older one. const selected = rollingActivityItem(items, previousItem, mounted); if (!selected) return null; const { item, earlierCount } = selected; const fallback = ( {item.kind === "tool-call" ? toolDisplayName(t, item.name, item.display, toolStepPhase(item.status)) : t("timeline.rollingActivity.working")} ); return ( {item.kind === "tool-call" ? toolDisplayName(t, item.name, item.display, toolStepPhase(item.status)) : item.kind === "reasoning" ? t("timeline.rollingActivity.thinking") : t("timeline.rollingActivity.working")} {showCount && earlierCount > 0 ? ( {`+${earlierCount} earlier`} ) : null} ); }