xiaoshuai
|
2a641b1eff
|
feat(serial): USB 页面下线, 改成串口映射 + 串口助手
## USB 整体下线
把 USB 功能真删掉, 不是只藏 UI:
- 删 `src/main/remote/usb.ts` + `src/renderer/src/components/remote/UsbPanel.vue`
- 删 `usb` (node-usb) 和 `node-hid` 两个依赖 —— 查过, 本来就没被真正用起来
- `asarUnpack` 去掉 node-usb/usb/node-hid 的规则
- ChatView 的 tab 由 "USB" 改成 "串口"
## 串口映射 + 串口助手 (新)
`src/main/remote/serial.ts` (取代 usb.ts) 只做串口, 一个文件两件事:
- **串口映射**: 把一端的真实串口映射成另一端可用的虚拟串口
(Linux/macOS 用 socat 建 PTY 配对, Windows 用 com0com 建 COM 对)。
方向做成 "我用对方的" / "对方用我的" 两种, 两边都能发起。
- **串口助手**: 不建虚拟口时, 应用自己当助手 —— 字节流直接显示,
能发文本/HEX, 能追加 LF, 能循环发送, 能清屏/存日志。
`src/renderer/src/components/remote/SerialPanel.vue` (新) 把两者做在一个面板里:
设备表 (串口 / VID:PID / 产品 / 制造商)、串口参数 (波特率/数据位/停止位/校验)、
TX/RX 时间戳 + hex + ascii 视图、虚拟口路径横幅 (可一键复制)。
## 串口助手要能调 Linux
Linux 上调串口最常见的两个坑, 都做成产品功能:
- **没权限**: 诊断 dialout 组 + socat + 串口列表, 一键提权修复
(`sudo usermod -aG dialout $USER`, 提示要重新登录才生效)。
"设备没插" 和 "没权限" 分开报错, 不再混成一句 "打开失败"。
- **缺 socat**: 建虚拟口前先探 socat, 没有就弹安装指引 (apt/dnf),
免得 attach 做到一半才失败。
平台化文案也分开了: Linux 提示 dialout, Windows 提示设备管理器, macOS 提示隐私授权。
## 线上格式一个字节没动 (兼容性关键)
局域网里常有一台机器跑旧版本, 所以:
- `PROTOCOL_VERSION` 仍然 = 1
- WS 帧类型仍然叫 `'usb'`
- 只把内部类型改名 (`SerialDeviceInfo` / `SerialAttachConfig` / ...)
代价: 混版本时已下线的 USB 字节桥不可用。换来: 新旧版本聊天照常,
串口映射也照常, 不会因为升协议被踢下线。**别手贱顺手改对** (AGENTS.md 坑 #10)。
## 其它
- 主进程 `output` 事件带方向 (rx/tx), 助手才能分清"我发的"和"设备回的";
客户端自己发出的字节不回显成 rx (无回环, S5 用例守住)
- 虚拟串口 (vcom) 模式下 app 不读内部端, 避免和 socat 抢数据
- `src/main/permissions.ts` 重写成串口专用, 删掉 USB/HID 相关诊断与修复
- 保留 `src/main/remote/vcom.ts` (socat/com0com 配对) 不动, 与 serial.ts 分离
## 验证
- npm run typecheck ✅
- npm run selftest ✅ 79 通过 / 0 失败 (USB 用例整体换成 S1-S9 串口用例)
- npm run build ✅
- npm run package:linux ✅ 新 deb (84MB)
- npm run selftest:package ✅ 4/4 (改成校验 serialport 原生绑定已解包)
真机 (CDP 驱动真实窗口) 验证过: 串口 tab 能打开, 设备表列到 32 个 /dev/ttyS*,
助手区 + hex 区在, 波特率/数据位/停止位/校验/循环发送/清屏/保存日志 按钮齐全,
方向切换会换设备列表 (我用对方的 = 对方设备, 对方用我的 = 本机设备)。
|
2026-10-21 18:04:55 +08:00 |
|
xiaoshuai
|
2b63bf7d0b
|
feat(image): 图片直接显示 + 右键复制图片; 修未读角标不清
## 图片直显 + 右键复制
以前图片消息基本只能看到 "[图片] xxx.png" 的文件卡片, 而且右键没有"复制"。
根因有两层:
1. `asImage` 从来没被设成 true —— 用"发送文件"选中的图片是当**普通文件**发的,
对方只能看到文件卡片。
2. 拖拽/粘贴的图走 `sendBuffer`, 只在 <200KB 时才带 `thumbDataUrl`,
大图没有缩略图 -> 渲染层 fallback 成文件卡片。
改法:
- 缩略图随消息体走 (`body.thumbDataUrl`): **发送方生成一次, 对方直接拿来显示**,
对端不用再解码, 老版本对端也看得到图。
- 缩略图用 Electron 的 `nativeImage` 生成 (`src/main/image.ts`), 不引 sharp/jimp:
宽度上限 480, **PNG 优先 (保透明 —— 截图转 JPEG 会变黑底)**, PNG 超 60KB 才退 JPEG,
然后按"降质量 -> 缩尺寸"的阶梯找一档够小的。
阈值/编码选择/选图源抽到 `src/main/image-core.ts` (纯逻辑, 不 import electron, 可单测)。
源文件 >20MB 不生成 —— nativeImage 解码会把整张图铺成 RGBA 内存。
- 拖拽/选中的图片改走 `sendFile(asImage: true)` (有真实路径, 流式上传),
只有粘贴的图片才走 `sendBuffer` (整图 base64 进 WS 帧, 大图撑爆带宽)。
- 右键"复制图片" -> `image:copy` IPC -> `clipboard.writeImage`, 写的是**原图**
(本地文件优先, 退回 dataBase64), 不是气泡里那个缩略图。
- 缩略图缺失时 (老消息/老版本对端) 渲染层退到 `image:thumb` 现场生成,
失败才显示文件卡片。点开看大图用 `image:dataUrl` 读本地原图。
## 修未读角标不清
用户正看着某个会话, dock/任务栏角标的数字却不消。
根因: `App.vue` 的 `message:received` 里先判 `if (!savedPath) return` (等文件落地再算未读),
而**文字消息没有 savedPath** —— 正好在"清未读"之前就 return 了。
文件/图片消息因为第二帧带 savedPath 才碰巧能清掉, 所以只有文字消息暴露这个 bug。
改法:
- 决策抽成纯函数 `src/renderer/src/utils/unread.ts` 的 `unreadActionForIncoming()`
(`clear` / `wait` / `count`): **先判 isActive -> 清未读 + 回已读回执, 再判 savedPath**。
- 侧边栏**重复点同一个设备**时 activePeerId 不变, watch 不触发 -> 显式清一次。
- 主进程 `device:delete` 清了 unread 但忘了 `updateBadge()` -> 角标残留, 补上。
## 验证
- npm run typecheck ✅
- npm run build ✅
- npm run selftest ✅ 76 通过 / 0 失败 (新增 I1-I8 图片 + U1-U4 角标)
- npm run selftest:sync ✅ 全部通过
- npm run selftest:image ✅ 真 Electron 下验 nativeImage (新增命令)
- npm run package:linux ✅ 新 deb
- npm run selftest:package ✅ 4/4
真机 (CDP 驱动真实窗口) 验证过: 图片气泡内联显示 (640x420, fallback 0 个),
右键菜单含"复制图片", 点下去系统剪贴板里是 **640x420 原图** (不是缩略图)。
|
2026-10-21 14:52:37 +08:00 |
|