feat(desktop): 团队视图加「卡通办公室」皮肤(手绘 SVG 贴纸风)
多智能体协调演成办公室:协调者在白板前统筹(白板即思考/综合流), 专家在工位敲键盘,完成打✓、失败挂!、派发走虚线。 风格对齐 ai-office-react(粗描边+平涂+大头身),但用手写 SVG 而非 PixiJS+Spine:零外部素材、无 Spine 运行时授权问题、几 KB 进包。 先试过 three.js 真 3D,低模程序化角色出来是玩具味,已弃并卸干净依赖。 数据与「卡片看板」同源(deriveTeam),换皮不换数据,后端零改动。 动效=状态编码(敲键盘/思考流/辉光),守 prefers-reduced-motion。 顺带修一个真 bug:并发时间轴复盘卡在 running 的旧任务时,未收口工位 会一路量到 Date.now(),跨度爆表(实测 32103562.4s)。抽 teamNow(): 直播用此刻、复盘用最后一个事件时间戳;两个皮肤共用,+3 单测。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useState } from "react";
|
||||
import { Activity, FileText, History, Users, Wrench } from "lucide-react";
|
||||
import { ExecTrace } from "../components/ExecTrace";
|
||||
import { TeamView } from "../components/TeamView";
|
||||
import { OfficeView } from "../components/OfficeView";
|
||||
import { Markdown } from "../components/Markdown";
|
||||
import { ChartView } from "../components/ChartView";
|
||||
import { extractChartBlocks, hasChart } from "../lib/chartspec";
|
||||
@@ -33,6 +34,7 @@ export function RunsView({ run }: { run: RunState }) {
|
||||
const [replay, setReplay] = useState<RunState>(emptyRun);
|
||||
const [evalRes, setEvalRes] = useState<EvalResult | null>(null);
|
||||
const [tab, setTab] = useState<DetailTab>("trace");
|
||||
const [teamSkin, setTeamSkin] = useState<"office" | "board">("office"); // 团队视图皮肤:卡通办公室 / 卡片看板
|
||||
|
||||
useEffect(() => {
|
||||
let alive = true;
|
||||
@@ -139,7 +141,23 @@ export function RunsView({ run }: { run: RunState }) {
|
||||
) : activeTab === "trace" ? (
|
||||
<ExecTrace events={cur.exec} phase={cur.phase} />
|
||||
) : activeTab === "team" ? (
|
||||
<TeamView events={cur.exec} output={cur.output} phase={cur.phase} />
|
||||
<div className="flex h-full min-h-0 flex-col gap-2">
|
||||
<div className="flex shrink-0 items-center gap-1 self-start rounded-md border border-line p-0.5">
|
||||
{(["office", "board"] as const).map((k) => (
|
||||
<button key={k} onClick={() => setTeamSkin(k)}
|
||||
className={cn("rounded px-2 py-0.5 text-[11px] transition", teamSkin === k ? "bg-ink-800 text-slate-100" : "text-slate-500 hover:text-slate-300")}>
|
||||
{k === "office" ? "办公室" : "看板"}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="min-h-0 flex-1">
|
||||
{teamSkin === "office" ? (
|
||||
<OfficeView events={cur.exec} output={cur.output} phase={cur.phase} />
|
||||
) : (
|
||||
<TeamView events={cur.exec} output={cur.output} phase={cur.phase} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : activeTab === "tools" ? (
|
||||
<ToolCalls run={cur} />
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user