Commit c27d790
feat(compact): 毛绒球折叠入口 + 禁用自动变猫开关 + compact 对话条/历史区打磨 (#1672)
* feat(compact): 毛绒球折叠入口 + 禁用自动变猫开关 + compact 最短宽度降至 280
- 输入态/胶囊态左侧握把改为毛绒球:单击折叠为 minimized,长按拖动整个 surface(复用工具轮盘 origin-drag 手势区分点击/拖动);App.tsx 新增 onCompactMinimizeRequest 回调,宿主接 setChatSurfaceMode('minimized')
- 新增「自动变猫」开关(聊天设置侧面板):app-auto-goodbye 自管开关(独立 localStorage + user-disabled 抑制原因),8 语言 i18n
- compact 桌面端最短宽度 430→280(新增 COMPACT_SURFACE_DESKTOP_MIN_WIDTH,默认仍 430;并修 metrics 把拖窄宽度顶回 430 的隐患)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 毛绒球放大左移 + resize bar 加长 + 历史 handle 展开加长 + 回滚热区收窄
- 毛绒球折叠球半径 +20%(28→34,icon 26→31),左移紧贴对话框(padding-left 8→4)
- 顶部历史 resize bar 视觉条加长 100%(40→80px)
- 历史展开 handle(蓝色 toggle bar)展开态加长(is-open 时 handle 宽度上调)
- 回滚 fd138cd「resize bar 调尺寸热区联动浮现」,恢复 hover 整个历史区即浮现 resize bar
- 修默认宽度隐患:拆出 COMPACT_SURFACE_DEFAULT_WIDTH(430),getCurrentCompactSurfaceWidth fallback 用默认宽度而非 resize 下限(默认仍 430,resize 可到 280)
- 同步更新 App.test.tsx(毛绒球入口测试、resize 下限 280)与 test_react_chat_window_static.py(padding、热区回滚)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(compact): 去掉历史气泡拖拽,恢复文本可选(保留点击勾选)
彻底删除 compact 历史气泡「拖到桌宠 avatar」子系统的 React 侧实现,让历史对话气泡内文本可被鼠标正常选中复制;保留点击勾选(导出选择)与图片显示。
- CompactExportHistoryPanel.tsx: 删整套指针拖拽状态机(handlePointerDown/Move/finishPointer/startCompactHistoryDrag 等约 40 函数 + drag-layer 渲染),气泡只留 onClick/onKeyDown 勾选;气泡加 user-select:text / cursor:text
- App.tsx / message-schema.ts: 删 onCompactHistoryDrop/onCompactHistoryDragStateChange props + drop payload 构造链 + drag schema 类型
- app-react-chat-window.js: 删宿主侧 drop handler/setter(app-buttons.js 调用经 typeof 守卫安全降级 no-op)
- 删 12 个拖拽相关 vitest + 加 1 个「点击勾选 + 文本可选」用例;同步 message-schema.test / test_react_chat_window_static
- 注: Electron preload(lanlan_frd) drop 接收端 + app-buttons.js drop-sender 暂留为 dead code,待跨仓库单独清理(功能版取舍)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 毛绒球继续放大左移(41px / icon 37 / padding-left 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 历史区最大高度去掉对话条宽度上限,只受屏幕高度约束
getCompactHistorySlotMaxHeight 去掉 W×1.46 那条(纯视觉比例约束),只保留屏幕可用高度×0.78 − chrome 预留;删去 unused 的 COMPACT_HISTORY_SLOT_MAX_WIDTH_RATIO。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(compact): 历史区缩小改为「下端锚定、上端折叠裁剪」,消除每帧 reflow
拖 resize bar 缩小历史区时,原本每帧改 scroll 盒 height + scroll-content min-height:100% 跟变 → 内容每帧 reflow 重排(抖动)。改为:
- 拖动期间(anchor data-compact-export-history-resizing)把 scroll-content 布局高度锚定到最大高度(--compact-history-slot-max-height,App.tsx applyCompactHistorySlotHeightVar 设),缩小只裁可视窗口、不 reflow 内容;配合顶部 mask 渐隐做'上端折起',geometry-refresh 时钉底(scrollTop=底)锚定下端 → 卷帘从上往下收
- 稳态保持 min-height:100%(内容少时无空白可滚,零 regression);拖动结束回落 100% 单次 reflow 贴合
- Electron 穿透区由 getBoundingClientRect 实测 + clip 自动跟随,无需改 preload
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 去掉历史气泡随机偏移/旋转/宽度,改规整统一宽度
getCompactHistoryBubbleTone 不再按 hash 生成随机宽度比例 / stagger-x 水平偏移 / rotate 旋转(强迫症友好);气泡宽度统一为 calc(100% - 48px)(比对话条窄约 48px),stagger-x=0、rotate=0。仅保留按分组的垂直间距 gap-before。删去 unused 的 widthSteps/offsetSteps/baseOffset/signedOffset/rotateSteps;同步更新 spacing tokens 用例断言。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 修历史区底部气泡阴影被裁 + 缩小高度切换跳变
气泡 box-shadow(0 7px 18px,下沿约 25px)不占盒模型,被 scroll 盒 overflow 裁(底部仅 4px padding);且稳态 min-height:100% 与拖动期 min-height:max 切换改变了底部气泡相对裁剪边的位置 → resize 起手/松手各跳一次。
修:scroll-content 加 padding-bottom: var(--compact-history-bubble-shadow-reserve, 26px)(落在可滚动内容盒,border-box 下计入 min-height,稳态盒高仍恰为 100%、不引入多余可滚区),最下方气泡下方始终留够阴影空间;稳态/拖动期同一常量 → 切换无跳变、稳态阴影完整不裁、气泡不再上浮。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 历史区宽度收窄到对话条宽 + 回退无效的气泡阴影 padding
- 历史区 anchor 宽度从 对话条宽×1.36 改为 ×1.0(用户要改的是历史区容器太宽,不是气泡;气泡 max-ratio 维持 calc(100%-48px) 不动,自然落回比输入框窄约 48px)
- 回退上一版给 scroll-content 加的 padding-bottom:那个诊断方向错了——实测既没解决底部气泡阴影被裁,反而把截断线与输入框间距拉大、更丑。底部阴影截断 + 缩小跳变(min-height 切换)仍待用实测 inspect 真正裁切元素后再修,不再纯推理。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 历史区贴近输入框(留白 34→10) + 修底部气泡阴影被裁
- anchor bottom 间距 34px→10px:历史区底边贴近输入框,去掉「离输入框太远」的大留白
- scroll 盒(容器)加 padding-bottom 26px 给最下方气泡 box-shadow(下沿~25px)留空间:padding 区在 scrollport 内、不被 overflow-y:auto 裁,阴影完整。关键是落在 scroll 盒「容器」本身——上一版加在子元素 scroll-content 的 padding-bottom 会被 Chromium 排除出可滚区、钉底后仍贴裁剪边而无效(这是上次诊断错的真因)。border-box 下不增 scroll 盒总高(=region)、只让出底部内容区,不增整体留白。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 修底部气泡阴影截断 + 展开经过新气泡抖动
实测对照(vite dev + 浏览器测量盒模型/scrollHeight)定位两个真因:
1. 阴影截断:flex/grid column 滚动容器的「末端 padding」会被 Chromium 排除出可滚区(scrollHeight 不含它),所以之前给 scroll 盒加 padding-bottom 一直无效(实测 flex 下加不加 scrollHeight 都是 1049,block 下才 1075)。改 .compact-export-history-scroll display:flex→block——底部对齐/缩小不 reflow 由子元素 scroll-content 的 flex+min-height:100%+margin-top:auto 负责(实测 block 下不变),底部 padding 进可滚区、最下气泡 box-shadow 完整漏出。anchor bottom 10→6 外边界更贴输入框,净留白不增(阴影落在底部 padding 区、非新增空白)。
2. 展开抖动:每帧无条件钉底(scrollTop=scrollHeight-clientHeight)在增高方向冗余、与正被揭出的上方新气泡重排打架 → 抖。改方向化钉底:记录上帧 clientHeight,只在缩小(变小)时钉底锚回下端,增高/不变交给浏览器自然 clamp。已修好的折叠(缩小)下端锚定不变。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 历史区底边到输入框间距 6px→2px,贴近输入框
间距来源已查明:就是 anchor 的 bottom 外边距(历史区底边钉在输入框顶上方的固定距离)。controls 导出按钮区是 controlsOpen 条件渲染、平时不占;scrollbar-hit 是 absolute 不占流;scroll 盒底部 padding 是给气泡阴影留的区(阴影占 25px)。故主间距=anchor bottom,减到 2px 后气泡阴影底到输入框约 3px。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 历史区到输入框再压紧 10px(scroll padding-bottom 26→16)
实测(浏览器量盒模型 + canvas 量 box-shadow 衰减)定位上次「没变化」的真因:用户看到的间距是最下气泡「实体方块底」到输入框 ~28px、由 scroll padding-bottom 主导(给 box-shadow 漏出留的空间);anchor bottom 只控「裁剪边」到输入框那 2px,肉眼分不出 6/2,所以改它几乎无感。box-shadow 0 7px 18px 数学下沿 25px,但 canvas 实测视觉可见下沿仅 ~13px(清晰段 ~9px)。故 padding-bottom 26→16:气泡实体底 28→18px(明显紧 10px),裁剪净空 15.9px 仍包住阴影可见段、阴影不被裁(上轮成果保留)。anchor bottom 维持 2px(再压到 0 会与输入框视觉粘连、收益≈0)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 处理 Codex/CodeRabbit review 三处
- [P1] chatWindowPropsSchema 增补 onCompactMinimizeRequest:之前只加了 App.tsx 的 TS 类型,hosted path 走 parseChatWindowProps(zod)会 strip 掉它,真实 Electron 里毛绒球点击拿到 undefined。
- [P2] loadCompactSurfaceStoredWidth desktop 下限 COMPACT_SURFACE_MAX_WIDTH(430)→COMPACT_SURFACE_DESKTOP_MIN_WIDTH:之前改 metrics/clampForSide 漏了这个 loader,导致拖到 280~429 的存量宽度复原时被顶回 430。
- [P2] CSS .compact-export-history-anchor max-height 去掉 width*1.46、改 78vh,与 JS getCompactHistorySlotMaxHeight(只受屏高)对齐,避免窄宽+高屏时 hit region 被 anchor 裁出死区。
build + vitest 168 + python 44 全绿。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(compact): 历史气泡划词复制时不再误触发导出勾选(Codex P2)
气泡是 user-select:text(故意覆盖 role=button 的 none,支持划词复制),但 export 模式下 onClick 又 toggle 勾选。拖选文字 mouseup 会再冒出一次 click,导致划词复制被误判为勾选。handleClick 在 toggle 前加折叠选区 guard:存在非空非折叠选区时跳过,单击(选区折叠)照常勾选;键盘 Enter/Space 路径不受影响。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Hongzhi Wen <cartabio.coder1@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent a4624fb commit c27d790
19 files changed
Lines changed: 607 additions & 3491 deletions
File tree
- frontend/react-neko-chat/src
- static
- locales
- tests/unit
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Lines changed: 92 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
65 | 157 | | |
66 | 158 | | |
67 | 159 | | |
| |||
0 commit comments