From 5e27ea942427be6973488d08a8bb65d9aba05015 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 22 May 2026 14:40:49 +0800 Subject: [PATCH] =?UTF-8?q?ui:=20"+=20=E6=96=B0=E5=BB=BA=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?"=E6=8C=89=E9=92=AE=E4=BB=8E=20header=20=E6=8C=AA=E5=88=B0?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E9=9D=A2=E6=9D=BF=20pane-head?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 语义更贴(任务面板的动作);顶栏减负只剩身份区(brand/who/logout);两种模式 DOM 一致,顺手删了 embedInit 里动态 insertBefore 那段。文案保留完整"+ 新建任务", 样式加 small 跟周边对齐高度,保留 primary 红底显眼。 Co-Authored-By: Claude Opus 4.7 (1M context) --- PROGRESS.md | 1 + web/static/dev.html | 10 +--------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 4e93bf4..fe04442 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -23,6 +23,7 @@ ### 2026-05-22 +- **"+ 新建任务"按钮从 header 挪到任务面板 pane-head**:`web/static/dev.html` `#hd-new` 节点直接在 HTML 里挪到 `#pane-left` 第一行 `.pane-head`(spacer 之后、`#filter-status` 之前),加 `small` 跟周边按钮对齐高度,保持 `primary` 红底显眼。语义更贴(新建任务 = 任务面板的动作);顶栏减负只剩身份区(brand / 用户名 / 退出登录);两种模式 DOM 一致,顺手删了 `embedInit` 里动态 `insertBefore` 那段。`@media phone` 段那条 `#hd-new` 紧凑覆盖照常生效。 - **dev SPA 加 iframe embed 模式(`?embed=1&parent_origin=...`)**:`web/static/dev.html` 加 embed 模式 — 父页面 iframe 嵌入时藏左上 brand / 顶栏 `#hd-who` / 退出登录按钮(桌面段整层 header `display:none`,移动段保留 header 给 `.mobile-tabs` 切换用),JS `embedInit` 把 `#hd-new`("+ 新建任务")从 header 节点移到任务面板 pane-head(spacer 之后、`#filter-status` 之前,加 `small` class 跟周边按钮对齐高度)。postMessage 协议:iframe 启动发 `{type:"zcbot-ready"}` 给父端,父端调自家后端用 `PLATFORM_KEY` 走 zcbot 已有的 `POST /v1/auth/login` 拿 JWT,通过 `{type:"zcbot-token", token, user_id, user_name?}` 推回 iframe;iframe 写 localStorage + `enterApp()`。401 时改写 `logout()` 不再 `location.reload()`,而是发 `{type:"zcbot-401"}` 通知父端重换 token,期间显灰底等待层(`#embed-waiting` spinner + 文案);新加 css class `body.embed-mode` / `body.embed-mode.embed-waiting` 控制可见性。**安全要点**:`event.origin` 双向校验(白名单 = URL 参数 `parent_origin`),缺参数直接显错误占位拒收;`PLATFORM_KEY` 留在 platform 后端绝不下发浏览器。`web/EMBED.md` 写给 platform 工程的对接手册(URL / 协议 / Node/Python 后端示例 / 父端前端示例 / CORS / CSP frame-ancestors 收紧建议 / 调试 + 故障兜底表)。否决:(a) URL 参数直接传 token —— Referer / 浏览器历史泄漏面;(b) 同源 + 共享 localStorage —— 用户明确说不同源;(c) 拆 dev.html 进 platform SPA route —— 工作量爆炸。 - **dev SPA chat-input 支持 Ctrl+V 粘贴文件上传 + chat-hint 反馈**:`web/static/dev.html` 给 `#chat-input` 加 `paste` 监听 —— `e.clipboardData.files` 非空时 `preventDefault` + 复用现有 `uploadFiles(files)` 走 `/v1/files/upload` 落到 `state.filesPath`(与拖拽到右 pane 同通路);纯文本粘贴走默认不拦。`uploadFiles` 改返回 bool(成功 true / 失败 false,原 alert 行为不变);粘贴 handler 通过 `chat-hint` 广播 "上传中:…" → "已粘贴:"(4s 后回前一个 hint,同 `optimizePrompt` 救回范式,不破坏 streaming/optimizing 期间的状态)。失败仍走 alert,hint 立即恢复。placeholder 提示加 `Ctrl+V 可粘贴文件`。常见场景:截图后直接 Ctrl+V 入对话区当作素材上传,免去切窗口走右 pane 拖拽。 - **dev SPA 文件预览弹框让出 chat-form 高度(打开期间输入区仍可点可打字)**:`web/static/dev.html` 给 `#file-preview-modal` 加 `bottom: var(--preview-bottom-inset, 0)` —— 默认 0 行为不变,`openFilePreview` 时 JS 量 `#chat-form.offsetHeight`(隐藏走 `offsetParent` 判空 → 0,无活动任务恢复全屏)写到弹框元素 inline style 上;`.card` 加 `max-height: calc(100vh - var(...) - 32px)` 让卡片随容器收缩不溢出,手机段同理用 `100dvh`。`closeFilePreview` `removeProperty` 清掉避免下次冗余。弹框遮罩本身物理上不覆盖底部输入区 → chat-form 自然可点击/打字,Esc 与点遮罩关闭逻辑不动。否决:(a) 整窗 `pointer-events: none` + card 收回 —— 遮罩物理还在覆盖,视觉仍遮挡;(b) 弹框抽进 `#pane-mid` 内 absolute —— 弹框来源含 `#pane-right` 文件列表和聊天 chip,挂 mid 内会限制弹框只能在 mid 列,且 `#pane-mid` 多层 flex 嵌套要重排;(c) 硬编一个常量 `bottom: 140px` —— chat-form 高度依据 textarea 用户拖拽变化(min 60 但可拉高),JS 量一次足够准。 diff --git a/web/static/dev.html b/web/static/dev.html index 7980b12..eb0cc1e 100644 --- a/web/static/dev.html +++ b/web/static/dev.html @@ -730,7 +730,6 @@
-
@@ -746,6 +745,7 @@ 任务 +