+
+
+
+
+
+
+
+
+
- 查看会话 / 添加项目 / 删除(保留磁盘数据)
@@ -55,9 +69,8 @@
任务
-
+
+
-
-
管理定时任务与自定义任务类型(内置类型只读)
@@ -115,9 +128,8 @@
Rant
-
+
+
-
-
-
-
-
-
-
- `;
}
diff --git a/emrg/gui/test/app-commands.test.js b/emrg/gui/test/app-commands.test.js
index 3051089..bb772ca 100644
--- a/emrg/gui/test/app-commands.test.js
+++ b/emrg/gui/test/app-commands.test.js
@@ -219,7 +219,7 @@ test("P4:/rant 无参数打开 Rant 面板 + 新建表单(rant 14:10:14 P6
await vm.runInContext("App.handleCommand({ type: 'command', cmd: '/rant', args: [] })", ctx);
await tick();
const panel = els["panel-rants"];
- assert.ok(panel && !panel.classList.contains("hidden"), "rants panel should be open");
+ assert.ok(panel && panel.classList.contains("active"), "rants workspace view should be active");
assert.ok(els["rant-form"] && !els["rant-form"].classList.contains("hidden"), "rant form should be open");
});
@@ -231,7 +231,7 @@ test("P4:/rant 直接跟内容快速提交(不打开面板)", async () =>
await tick();
await vm.runInContext("App.handleCommand({ type: 'command', cmd: '/rant', args: ['希望支持主题切换'] })", ctx);
const panel = els["panel-rants"];
- assert.ok(!(panel && !panel.classList.contains("hidden")), "direct rant submit should not open panel");
+ assert.ok(!(panel && panel.classList.contains("active")), "direct rant submit should not open panel");
});
test("P4:/trigger 无参数打开任务面板", async () => {
@@ -242,7 +242,7 @@ test("P4:/trigger 无参数打开任务面板", async () => {
await tick();
await vm.runInContext("App.handleCommand({ type: 'command', cmd: '/trigger', args: [] })", ctx);
const panel = els["panel-tasks"];
- assert.ok(panel && !panel.classList.contains("hidden"), "tasks panel should be open");
+ assert.ok(panel && panel.classList.contains("active"), "tasks workspace view should be active");
});
test("P4:/trigger 直接触发(不打开对话框)", async () => {
diff --git a/emrg/gui/test/renderer.smoke.test.js b/emrg/gui/test/renderer.smoke.test.js
index a489890..0e21c4c 100644
--- a/emrg/gui/test/renderer.smoke.test.js
+++ b/emrg/gui/test/renderer.smoke.test.js
@@ -116,12 +116,12 @@ function makeEl(id) {
}
const ELEMENT_IDS = [
- "chat-view", "input", "send-btn", "stop-btn", "conv-list", "open-sessions", "open-sessions-label", "status-dot", "settings-btn",
+ "workspace", "input", "send-btn", "stop-btn", "conv-list", "open-sessions", "open-sessions-label", "status-dot", "settings-btn",
"open-session-dialog", "open-session-list", "open-session-title", "open-session-desc", "open-session-new", "open-session-cancel", "open-session-new-session",
"new-session-dialog", "new-session-list", "new-session-new", "new-session-cancel",
"conn-banner", "empty-state", "model-switcher", "model-switcher-label", "brand-star", "new-chat-btn", "open-chat-btn",
"side-nav", "nav-sessions", "nav-projects", "nav-tasks", "nav-rants", "nav-settings",
- "panel-sessions", "panel-projects", "panel-tasks", "panel-rants", "panel-settings",
+ "panel-projects", "panel-tasks", "panel-rants", "panel-settings",
"project-list", "project-add-btn",
"rant-filter-tabs", "rant-filter-all", "rant-filter-pending", "rant-filter-inprogress", "rant-filter-completed",
"rant-list", "rant-new-btn", "rant-form", "rant-form-project", "rant-form-message", "rant-form-cancel", "rant-form-submit",
@@ -129,7 +129,7 @@ const ELEMENT_IDS = [
"settings-body-model", "settings-body-workdir", "settings-body-github", "settings-body-appearance", "settings-body-language", "settings-body-about",
"settings-cancel", "settings-save", "set-api-key", "set-base-url", "set-project-dir", "set-model", "pick-dir-btn", "theme-options", "welcome-dialog", "welcome-api-key", "welcome-base-url",
"welcome-model", "welcome-project-dir", "welcome-pick-btn", "welcome-save", "confirm-dialog",
- "confirm-title", "confirm-message", "confirm-cancel", "confirm-ok", "main",
+ "confirm-title", "confirm-message", "confirm-cancel", "confirm-ok", "main", "composer-wrap",
"rename-dialog", "rename-input", "rename-cancel", "rename-ok", "ctx-menu",
"model-list", "add-model-btn", "model-form", "model-form-name", "model-form-id",
"model-form-vision", "model-form-save", "model-form-cancel", "back-to-bottom",
@@ -302,8 +302,8 @@ test("流式 delta 追加 + 工具行 running→done 状态流转", async () =>
EMRG_Chat.handleToolEnd({ tool_call_id: "t1", tool_name: "read", content: "file contents", elapsed: 0.3 });
EMRG_Chat.handleDone({ request_id: "rid-1" });
return {
- chatChildren: $("chat-view").children.length,
- toolRowClass: $("chat-view").children[1] ? $("chat-view").children[1].className : "none",
+ chatChildren: $("workspace").children.length,
+ toolRowClass: $("workspace").children[1] ? $("workspace").children[1].className : "none",
};
})()`, ctx);
assert.strictEqual(r.chatChildren, 2, "用户流 + 工具行 2 个节点");
@@ -324,7 +324,7 @@ test("rant 21:57:10:交替文本/工具按顺序交错展示(每段文本独
EMRG_Chat.handleToolStart({ request_id: "rid-1", tool_call_id: "t2", tool_name: "bash" });
EMRG_Chat.handleToolEnd({ tool_call_id: "t2", tool_name: "bash", content: "out2", elapsed: 0.2 });
EMRG_Chat.handleDelta([{ request_id: "rid-1", content: "文本段3" }]);
- const children = $("chat-view").children;
+ const children = $("workspace").children;
const kinds = [];
const texts = [];
const isToolRow = (c) =>
@@ -342,8 +342,8 @@ test("rant 21:57:10:交替文本/工具按顺序交错展示(每段文本独
// done 后该 rid 的所有文本段都应渲染(typing 移除)
EMRG_Chat.handleDone({ request_id: "rid-1" });
let typingAfter = 0;
- for (let i = 0; i < $("chat-view").children.length; i++) {
- const c = $("chat-view").children[i];
+ for (let i = 0; i < $("workspace").children.length; i++) {
+ const c = $("workspace").children[i];
if (c.className.includes("typing")) typingAfter++;
}
return {
@@ -367,7 +367,7 @@ test("rant 21:08:工具完成后 spinner 停止(元素移除,不再转圈
App.state.sessionId = "s1";
App.state.ownStreamRequestId = "rid-1";
EMRG_Chat.handleToolStart({ request_id: "rid-1", tool_call_id: "t1", tool_name: "read" });
- const row = $("chat-view").children[1]; // children[0] 是助手文本节点,[1] 是工具行
+ const row = $("workspace").children[1]; // children[0] 是助手文本节点,[1] 是工具行
const spinnerBefore = (row.querySelector(".tool-spinner") !== null);
EMRG_Chat.handleToolEnd({ tool_call_id: "t1", tool_name: "read", content: "ok", elapsed: 0.3 });
const spinnerAfter = (row.querySelector(".tool-spinner") !== null);
@@ -385,7 +385,7 @@ test("rant 21:09:文本段被工具封存后 typing 光标移除(只留最
App.state.sessionId = "s1";
App.state.ownStreamRequestId = "rid-1";
EMRG_Chat.handleDelta([{ request_id: "rid-1", content: "第一段" }]);
- const firstNode = $("chat-view").children[0];
+ const firstNode = $("workspace").children[0];
const firstBody = firstNode.querySelector(".msg-body") || firstNode;
const typingBefore = firstBody.classList.contains("typing");
EMRG_Chat.handleToolStart({ request_id: "rid-1", tool_call_id: "t1", tool_name: "read" });
@@ -403,7 +403,7 @@ test("rant 21:10:done 渲染剥离 ✦ 前缀(标题/列表/代码围栏不
App.state.sessionId = "s1";
App.state.ownStreamRequestId = "rid-1";
EMRG_Chat.handleDelta([{ request_id: "rid-1", content: "# 标题\\n- 列表项\\n\\n\\u0060\\u0060\\u0060python\\nprint(1)\\n\\u0060\\u0060\\u0060" }]);
- const node = $("chat-view").children[0];
+ const node = $("workspace").children[0];
const body = node.querySelector(".msg-body") || node;
// 模拟真实 DOM:body 内先有 ✦ 标记 span(textContent 含前缀)
body.textContent = "✦ " + body.textContent;
@@ -436,7 +436,7 @@ test("rant 14:11:首条消息后欢迎屏立即隐藏(append 同步 updateEm
EMRG_Chat.addUserMessage("hello");
return {
emptyHidden: $("empty-state").classList.contains("hidden"),
- msgCount: $("chat-view").children.length,
+ msgCount: $("workspace").children.length,
};
})()`, ctx);
assert.strictEqual(r.msgCount, 1, "消息应已追加");
@@ -466,7 +466,7 @@ test("rant 21:00:28:块投影——流式中标题即时渲染,稳定块缓
},
};
EMRG_Chat.handleDelta([{ request_id: "rid-1", content: "# 标题" }]);
- const body = $("chat-view").children[0].querySelector(".msg-body");
+ const body = $("workspace").children[0].querySelector(".msg-body");
const stream = body.querySelector(".md-stream");
const live1 = stream.children[stream.children.length - 1]; // 尾部 live 块
const h2WhileStreaming = live1.className.includes("live") && live1.innerHTML.includes("");
@@ -503,7 +503,7 @@ test("rant 21:00:28:代码块围栏未闭合纯文本不高亮,闭合后转
},
};
EMRG_Chat.handleDelta([{ request_id: "rid-1", content: "before\\n\\\`\\\`\\\`python\\nprint(1)" }]);
- const body = $("chat-view").children[0].querySelector(".msg-body");
+ const body = $("workspace").children[0].querySelector(".msg-body");
const live = body.querySelector(".md-stream");
const liveDiv = live.children[live.children.length - 1]; // 尾部 live 块(单类选择器 mock 限制)
const unclosedPlain = liveDiv.className.includes("live") && liveDiv.innerHTML.startsWith("
@@ -146,8 +158,7 @@
设置
+
@@ -249,26 +260,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/emrg/gui/renderer/js/app.js b/emrg/gui/renderer/js/app.js
index 7e4ecbf..6e6cdcf 100644
--- a/emrg/gui/renderer/js/app.js
+++ b/emrg/gui/renderer/js/app.js
@@ -41,8 +41,8 @@ const App = (() => {
// B3(rant 21:59:11):每会话输入框草稿(浏览器 tab 式状态保留)——切换会话保存旧
// sid 草稿、恢复新 sid 草稿;发送成功即清除该 sid 草稿
drafts: new Map(), // sid → 草稿文本
- // rant 14:10:14 P1:侧边栏面板导航(null=无面板打开;sessions/projects/tasks/rants/settings)
- activePanel: null,
+ // rant 18:55:09 v0.2:工作区视图导航(null/undefined=会话视图;projects/tasks/rants/settings=面板视图)
+ activeView: null,
};
// P3 slice 1:会话条目访问器(get-or-create)。无 sid/未激活 → 归入当前激活会话。
@@ -438,7 +438,7 @@ const App = (() => {
// /trigger:任务面板(rant 14:10:14 P3:替代 tasks-dialog;点击行立即触发)
async function openTasksPanel() {
- if (state.activePanel !== "tasks") switchPanel("tasks");
+ if (state.activeView !== "tasks") switchView("tasks");
try {
await Dialogs.loadTaskMeta();
await Dialogs.renderTaskList();
@@ -449,7 +449,7 @@ const App = (() => {
// 项目面板(rant 14:10:14 P5:打开即加载项目列表)
async function openProjectsPanel() {
- if (state.activePanel !== "projects") switchPanel("projects");
+ if (state.activeView !== "projects") switchView("projects");
try {
await Dialogs.renderProjectList();
} catch (e) {
@@ -459,7 +459,7 @@ const App = (() => {
// Rant 面板(rant 14:10:14 P4:打开即加载 rant 列表)
async function openRantsPanel() {
- if (state.activePanel !== "rants") switchPanel("rants");
+ if (state.activeView !== "rants") switchView("rants");
try {
await Dialogs.renderRantList();
} catch (e) {
@@ -547,25 +547,34 @@ const App = (() => {
// ── 会话 ─────────────────────────────────
// P3 slice 2:每会话一个 .session-view 容器(浏览器 tab 效果——切换 display 保留状态)
function ensureSessionView(sid) {
- if (!sid) return $("chat-view");
+ if (!sid) return $("workspace");
// 在 wrapper 内按 dataset.sid 查找既有容器(不依赖 getElementById——测试沙箱对
// 未知 id 返回新 mock,且 mock 的 .id 不入 attributes;dataset 双端一致)
- let view = [...$("chat-view").children].find((c) => c.dataset?.sid === sid);
+ let view = [...$("workspace").children].find((c) => c.dataset?.sid === sid);
if (!view) {
- view = el("div", { class: "session-view", id: "chat-view-" + sid, dataset: { sid } });
- $("chat-view").appendChild(view);
+ view = el("div", { class: "session-view", id: "session-view-" + sid, dataset: { sid } });
+ $("workspace").appendChild(view);
}
Chat.registerContainer(sid, view); // 幂等:重复注册覆盖同一元素
return view;
}
+ // rant 18:55:09 v0.2:工作区视图互斥(激活会话视图 → 同步隐藏所有面板视图 + 清导航高亮)
function activateSessionView(sid) {
+ for (const p of VIEWS) {
+ const btn = $(`nav-${p}`);
+ if (btn) btn.classList.toggle("active", false);
+ const panel = $(`panel-${p}`);
+ if (panel) panel.classList.remove("active");
+ }
const view = ensureSessionView(sid);
- for (const child of $("chat-view").children) {
+ for (const child of $("workspace").children) {
if (child.classList) child.classList.remove("active");
}
view.classList.add("active");
Chat.scrollToBottom(sid);
+ setWorkspaceChrome("sessions"); // 恢复输入区 + 成果面板
+ state.activeView = "sessions";
return view;
}
@@ -633,25 +642,70 @@ const App = (() => {
}
}
- // ── 侧边栏导航(rant 14:10:14 P1:5 入口面板框架,P2-P5 填充内容)──
- const SIDE_PANELS = ["sessions", "projects", "tasks", "rants", "settings"];
+ // ── 工作区视图导航(rant 18:55:09 v0.2:面板 → 工作区视图;sessions=会话视图)──
+ const VIEWS = ["sessions", "projects", "tasks", "rants", "settings"];
- /** 切换侧边栏面板:点同一项关闭,点其他项切换;高亮当前导航。 */
- function switchPanel(name) {
- if (!SIDE_PANELS.includes(name)) return;
- const isOpen = state.activePanel === name;
- for (const p of SIDE_PANELS) {
+ /** 切换工作区视图:点当前激活项关闭回会话视图,点其他项切换;高亮当前导航(DOM 显隐 .active 互斥,状态保留)。 */
+ function switchView(name) {
+ if (!VIEWS.includes(name)) return;
+ const isOpen = state.activeView === name;
+ for (const p of VIEWS) {
const btn = $(`nav-${p}`);
- const panel = $(`panel-${p}`);
if (btn) btn.classList.toggle("active", false);
- if (panel) panel.classList.add("hidden");
}
- state.activePanel = isOpen ? null : name;
- if (!isOpen) {
+ if (!isOpen && name !== "sessions") {
+ // 打开面板视图:隐藏全部会话视图 + 全部面板视图(互斥——显式清面板,不依赖 DOM 树),激活目标面板
+ state.activeView = name;
+ for (const child of $("workspace").children) {
+ if (child.classList) child.classList.remove("active");
+ }
+ for (const p of VIEWS) {
+ const v = $(`panel-${p}`);
+ if (v) v.classList.remove("active");
+ }
+ const view = $(`panel-${name}`);
+ if (view) view.classList.add("active");
const btn = $(`nav-${name}`);
- const panel = $(`panel-${name}`);
if (btn) btn.classList.add("active");
+ setWorkspaceChrome("panel"); // 隐藏输入区 + 成果面板 + 空状态
+ } else {
+ // 点当前激活项(toggle 关闭)/ 点 💬 会话 → 回会话视图
+ showSessionsView();
+ }
+ }
+
+ /** 回会话视图:激活当前 sid 的会话视图(无会话 → 仅恢复工作区 chrome) */
+ function showSessionsView() {
+ state.activeView = "sessions";
+ if (state.sessionId) {
+ activateSessionView(state.sessionId);
+ } else {
+ for (const child of $("workspace").children) {
+ if (child.classList) child.classList.remove("active");
+ }
+ setWorkspaceChrome("sessions");
+ }
+ updateEmptyState();
+ }
+
+ /** 工作区外围 chrome(输入区 + 空状态 + 成果面板 + 拖拽手柄)按视图模式显隐:panel 隐藏,sessions 恢复。 */
+ function setWorkspaceChrome(mode) {
+ const composer = $("composer-wrap");
+ const empty = $("empty-state");
+ const panel = $("result-panel");
+ const resizer = $("result-resizer");
+ if (mode === "panel") {
+ composer.classList.add("hidden");
+ empty.classList.add("hidden");
+ if (panel) panel.classList.add("hidden");
+ if (resizer) resizer.classList.add("hidden");
+ // HTML 预览(WebContentsView)随面板隐藏(main 侧比对路径;无预览时 no-op)
+ try { if (window.emrg && typeof window.emrg.closePreview === "function") window.emrg.closePreview({}); } catch { /* ignore */ }
+ } else {
+ composer.classList.remove("hidden");
if (panel) panel.classList.remove("hidden");
+ if (resizer) resizer.classList.remove("hidden");
+ updateEmptyState();
}
}
@@ -773,7 +827,7 @@ const App = (() => {
await window.emrg.deleteSession({ sessionId: sid });
// P3 slice 2:删除会话 → 释放其容器(若已打开)
Chat.unregisterContainer(sid);
- const view = [...$("chat-view").children].find((c) => c.dataset?.sid === sid);
+ const view = [...$("workspace").children].find((c) => c.dataset?.sid === sid);
if (view) view.remove();
if (state.sessionId === sid) {
const remaining = state.sessions.filter((s) => s.session_id !== sid);
@@ -807,7 +861,7 @@ const App = (() => {
try {
await window.emrg.closeSession({ sessionId: sid });
Chat.unregisterContainer(sid); // 释放容器(若已打开)
- const view = [...$("chat-view").children].find((c) => c.dataset?.sid === sid);
+ const view = [...$("workspace").children].find((c) => c.dataset?.sid === sid);
if (view) view.remove();
if (state.sessionId === sid) {
// 关闭激活会话 → 切到剩余打开会话中最近激活的,否则新建
@@ -1432,7 +1486,7 @@ const App = (() => {
hideBanner();
// P3 finalize:重连成功 → 清全部会话断线标记 + 容器 .disconnected 类
for (const entry of state.sessionsBySid.values()) entry.disconnected = false;
- for (const child of $("chat-view").children) {
+ for (const child of $("workspace").children) {
if (child.classList && child.classList.contains("disconnected")) child.classList.remove("disconnected");
}
if (data.server_id) state.serverId = data.server_id;
@@ -1459,19 +1513,19 @@ const App = (() => {
function bindUi() {
$("send-btn").addEventListener("click", sendMessage);
$("stop-btn").addEventListener("click", () => window.emrg.cancel().catch(() => {}));
- // rant 14:10:14 P1:侧边栏导航点击切换面板
- for (const p of SIDE_PANELS) {
+ // rant 18:55:09 v0.2:侧边栏导航点击 → 工作区视图切换(data-view)
+ for (const p of VIEWS) {
$(`nav-${p}`)?.addEventListener("click", () => {
- switchPanel(p);
- // P2:面板打开时加载对应数据(settings 走 showSettings 刷新全部;tasks/projects/rants 走各自加载)
- if (p === "settings" && state.activePanel === "settings") {
+ switchView(p);
+ // 面板视图打开时加载对应数据(settings 走 showSettings 刷新全部;tasks/projects/rants 走各自加载)
+ if (p === "settings" && state.activeView === "settings") {
loadEvolutionSummary();
Dialogs.showSettings();
- } else if (p === "tasks" && state.activePanel === "tasks") {
+ } else if (p === "tasks" && state.activeView === "tasks") {
openTasksPanel();
- } else if (p === "projects" && state.activePanel === "projects") {
+ } else if (p === "projects" && state.activeView === "projects") {
openProjectsPanel();
- } else if (p === "rants" && state.activePanel === "rants") {
+ } else if (p === "rants" && state.activeView === "rants") {
openRantsPanel();
}
});
@@ -1487,7 +1541,7 @@ const App = (() => {
Dialogs.showSettings();
});
Dialogs.initLangButtons(); // rant 21:19:设置语言选择器
- $("settings-cancel").addEventListener("click", () => switchPanel("settings")); // P2:取消=关闭设置面板
+ $("settings-cancel").addEventListener("click", () => switchView("settings")); // P2:取消=关闭设置视图
$("settings-save").addEventListener("click", Dialogs.saveSettings);
$("pick-dir-btn").addEventListener("click", async () => {
const dir = await window.emrg.pickProjectDir();
@@ -1583,7 +1637,7 @@ const App = (() => {
}
});
- const chatView = $("chat-view");
+ const chatView = $("workspace");
const updateBackToBottom = () => {
const btn = $("back-to-bottom");
const atBottom = chatView.scrollTop + chatView.clientHeight >= chatView.scrollHeight - 40;
@@ -1679,7 +1733,7 @@ const App = (() => {
closeOpenSession, // P4 slice 2:关闭打开会话(保留数据)
showOpenSessionsMenu, // P4 slice 2:打开会话右键菜单
activateSessionView, // P3 slice 2:激活会话容器(display 切换;导出供测试)
- switchPanel, // rant 14:10:14 P1:侧边栏面板切换(导出供测试)
+ switchView, // rant 18:55:09 v0.2:工作区视图切换(导出供测试)
switchSettingsTab, // rant 14:10:14 P2:设置面板 tab 切换(导出供测试)
openTasksPanel, // rant 14:10:14 P3:任务面板打开 + 加载(导出供测试)
openProjectsPanel, // rant 14:10:14 P5:项目面板打开 + 加载(导出供测试)
diff --git a/emrg/gui/renderer/js/chat.js b/emrg/gui/renderer/js/chat.js
index c28f117..86759ba 100644
--- a/emrg/gui/renderer/js/chat.js
+++ b/emrg/gui/renderer/js/chat.js
@@ -7,10 +7,10 @@
const Chat = (() => {
// P3(rant 15:07:19):会话级状态隔离——每会话一份 groupNodes/toolRows/doneRids。
// sid=null 为旧版单会话桶(无 sid 事件/旧调用方 → 行为与改造前完全一致)。
- // 容器路由:registerContainer(sid, el) 后该 sid 渲染进独立容器;未注册 → 默认 $("chat-view")
+ // 容器路由:registerContainer(sid, el) 后该 sid 渲染进独立容器;未注册 → 默认 $("workspace")
// (P4 openSessions 前实际只存在一个激活会话,容器切换随 P4 落地)。
const sessionState = new Map(); // sid|null → { groupNodes, toolRows, doneRids }
- const containers = new Map(); // sid → 容器元素(P4 起每会话一个 chat-view)
+ const containers = new Map(); // sid → 容器元素(P4 起每会话一个 .session-view)
function st(sid) {
const key = sid || null;
@@ -25,7 +25,7 @@ const Chat = (() => {
if (containers.has(sid)) return containers.get(sid);
const active = App.state?.sessionId;
if (active && containers.has(active)) return containers.get(active);
- return $("chat-view");
+ return $("workspace");
}
/** P4 起:为新打开的会话注册独立容器;关闭时 unregister 清引用 */
@@ -43,7 +43,7 @@ const Chat = (() => {
/** 复制代码按钮(设计 §3.3):事件委托在聊天区,CSP 无内联 handler */
function initCodeCopy() {
- const cv = $("chat-view");
+ const cv = $("workspace");
cv.addEventListener("click", (e) => {
const btn = e.target.closest(".code-copy");
if (!btn) return;
diff --git a/emrg/gui/renderer/js/dialogs.js b/emrg/gui/renderer/js/dialogs.js
index ab6f501..0799805 100644
--- a/emrg/gui/renderer/js/dialogs.js
+++ b/emrg/gui/renderer/js/dialogs.js
@@ -240,8 +240,8 @@ const Dialogs = (() => {
} catch (e) {
Chat.addSystemMessage(_t("settings.readFailed", { msg: e.message }));
}
- // rant 14:10:14 P2:设置改为面板(不再弹窗);已在面板内(nav 打开后刷新)则不再 toggle
- if (App.state.activePanel !== "settings") App.switchPanel("settings");
+ // rant 18:55:09 v0.2:设置改为工作区视图(不再弹窗);已在视图内(nav 打开后刷新)则不再 toggle
+ if (App.state.activeView !== "settings") App.switchView("settings");
}
async function saveSettings() {
diff --git a/emrg/gui/renderer/js/markdown.js b/emrg/gui/renderer/js/markdown.js
index af76f2d..c38fb96 100644
--- a/emrg/gui/renderer/js/markdown.js
+++ b/emrg/gui/renderer/js/markdown.js
@@ -34,7 +34,7 @@ function codeRenderer(code, infostring, escaped) {
const codeHtml = highlighted
? `${highlighted}`
: `${escaped ? code : escapeHtml(code)}`;
- // 复制按钮:事件委托在 chat-view(CSP 禁内联 handler);code 文本经 escapeHtml 防注入
+ // 复制按钮:事件委托在聊天区(CSP 禁内联 handler);code 文本经 escapeHtml 防注入
return `${codeHtml}