diff --git a/src/components/convert-chip.tsx b/src/components/convert-chip.tsx index 14a5703..21d3b9d 100644 --- a/src/components/convert-chip.tsx +++ b/src/components/convert-chip.tsx @@ -23,10 +23,6 @@ export function ConvertChip() { const { run, cancel } = useConvert(); const t = useT(); - // Only show in split mode — when only one pane is visible there's no - // divider to hang off, and the toolbar button is already obvious. - if (layoutMode !== "split") return null; - const agentInfo = agents.find((a) => a.id === agent); const model = agent ? agentModels[agent] ?? "default" : "default"; const canConvert = @@ -55,6 +51,7 @@ export function ConvertChip() { // Lives here (not in Toolbar) because the chip is the single source of // Convert truth after the toolbar button was removed. useEffect(() => { + if (layoutMode !== "split") return; const onKey = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === "Enter") { if (isRunning || !canConvert) return; @@ -64,7 +61,11 @@ export function ConvertChip() { }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); - }, [onClick, isRunning, canConvert]); + }, [layoutMode, onClick, isRunning, canConvert]); + + // Only show in split mode — when only one pane is visible there's no + // divider to hang off, and the toolbar button is already obvious. + if (layoutMode !== "split") return null; return (
+ window.setTimeout(() => { + const current = useStore.getState().tasks.find((t) => t.id === taskId); + if (current?.status !== "running" || current.stats.deltaCount > 0) return; + const waited = Math.round((Date.now() - startedAt) / 1000); + useStore.getState().pushLogFor(taskId, { + kind: "info", + elapsed: Date.now() - startedAt, + text: `仍在等待 ${req.agent} 的首段输出 (${waited}s)。Codex / Copilot 这类 CLI 有时会先完整生成,再一次性吐出 HTML;请先不要刷新页面或再次点击 Convert。`, + }); + }, ms), + ); + try { const res = await fetch("/api/convert", { method: "POST", @@ -160,6 +173,7 @@ export function useConvert() { }); useStore.getState().setStatusFor(taskId, "error"); } finally { + stillWaitingTimers.forEach((id) => window.clearTimeout(id)); if (controllers.get(taskId) === ctl) controllers.delete(taskId); } },