(null);
-
- const busy = thread?.busy ?? false;
- const messages = thread?.messages ?? [];
- const started = messages.length > 0;
-
- useEffect(() => {
- listRef.current?.scrollTo({ top: listRef.current.scrollHeight });
- }, [messages.length, busy]);
-
- const send = () => {
- const text = input.trim();
- if (!text || busy) return;
- sendChat(agentId, text, fromProject);
- setInput("");
- };
-
- return (
-
-
-
對話
- {started && (
-
- )}
-
-
- {started && (
-
- {messages.map((m, i) => (
-
- {m.text}
-
- ))}
- {busy &&
⋯ 執行中,過程看辦公室裡的小人
}
-
- )}
-
-
- );
-}
-
export function SidePanel() {
const selectedAgentId = useOfficeStore((s) => s.selectedAgentId);
const agent = useOfficeStore((s) => (s.selectedAgentId ? s.agents.get(s.selectedAgentId) : undefined));
@@ -186,7 +100,9 @@ export function SidePanel() {
)}
- {agent.role !== "subagent" && mode === "live" && }
+ {agent.role !== "subagent" && mode === "live" && (
+
+ )}
) : (
diff --git a/src/store/office-store.ts b/src/store/office-store.ts
index c92c74b..9d9d112 100644
--- a/src/store/office-store.ts
+++ b/src/store/office-store.ts
@@ -38,6 +38,8 @@ interface OfficeState {
mode: "sim" | "live";
/** side panel visibility (collapse to maximise the office view) */
panelOpen: boolean;
+ /** LIVE-mode chat expanded to a full-screen overlay */
+ chatFullscreen: boolean;
/** simulation clock, seconds */
clock: number;
@@ -47,6 +49,7 @@ interface OfficeState {
setSpeed: (s: number) => void;
setMode: (m: "sim" | "live") => void;
togglePanel: () => void;
+ setChatFullscreen: (v: boolean) => void;
clearWorld: () => void;
chatAppend: (agentId: string, msg: ChatMessage) => void;
@@ -124,9 +127,10 @@ export const useOfficeStore = create()((set, get) => ({
speed: 1,
mode: "sim",
panelOpen: savedPanel !== "0",
+ chatFullscreen: false,
clock: 0,
- selectAgent: (id) => set({ selectedAgentId: id }),
+ selectAgent: (id) => set({ selectedAgentId: id, chatFullscreen: id === null ? false : get().chatFullscreen }),
setTheme: (t) => {
savePref("office-theme", t);
set({ theme: t });
@@ -142,6 +146,7 @@ export const useOfficeStore = create()((set, get) => ({
savePref("office-panel", state.panelOpen ? "0" : "1");
return { panelOpen: !state.panelOpen };
}),
+ setChatFullscreen: (v) => set({ chatFullscreen: v }),
clearWorld: () =>
set({
agents: new Map(),
@@ -150,6 +155,7 @@ export const useOfficeStore = create()((set, get) => ({
events: [],
chats: new Map(),
selectedAgentId: null,
+ chatFullscreen: false,
}),
chatAppend: (agentId, msg) =>
diff --git a/src/styles.css b/src/styles.css
index 840133d..f4fb188 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -372,7 +372,88 @@
cursor: default;
}
-.chat-list {
+.chat-head-actions {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.chat-head .link-btn:disabled {
+ opacity: 0.4;
+ cursor: default;
+}
+
+/* ── full-screen chat overlay ── */
+
+.chat-full-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 60;
+ background: color-mix(in srgb, var(--bg) 82%, transparent);
+ backdrop-filter: blur(6px);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24px;
+ animation: card-in 0.2s ease-out;
+}
+
+.chat-full-card {
+ width: min(860px, 100%);
+ height: min(88vh, 900px);
+ display: flex;
+ flex-direction: column;
+ background: var(--bg-panel);
+ border: 1px solid var(--border);
+ border-radius: 16px;
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
+ overflow: hidden;
+ padding: 18px 20px 20px;
+}
+
+.chat-full-topbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ padding-bottom: 14px;
+ border-bottom: 1px solid var(--border);
+}
+
+.chat-full-who {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.chat-full-who svg {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: 10px;
+ flex-shrink: 0;
+}
+
+.chat-full-who h2 {
+ font-family: "Sora", system-ui, sans-serif;
+ font-size: 20px;
+ font-weight: 600;
+ margin-bottom: 4px;
+}
+
+.chat-full-who .model-tag {
+ margin-left: 8px;
+}
+
+/* the shared conversation fills the full-screen card */
+.chat-panel-full {
+ flex: 1;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+ margin-top: 14px;
+}
+
+.chat-panel-full .chat-list {
display: flex;
flex-direction: column;
gap: 6px;