gui: 设备命令/能力完整实现 + 二进制分块 + 消息ID去重 + 交互优化

设备命令执行对齐服务端 cmd_type 契约:
- onDeviceMsg 解析 msg.cmd_type: homeagent->能力分发 / shell->白名单执行
- 统一回执 sendCmdResult(兼容双参), 全链路回执修复
- 修复 pi-lens auto-fix 把 trayLastCmd 改 const 导致的 TypeError(命令未执行/无回执根因)

homeagent 能力:
- screensue: 独立窗口显示文字/HTML, 可配默认屏幕(displays:list IPC), 支持时长参数 "screensue [秒] 内容", 默认常驻
- camerasue: 抓拍单张 jpeg(base64文本); camerasue <N秒>=录像 mp4(libx264), 二进制分块经设备通道回传
- speakeruse: 接收服务端二进制音频(WS 0x2), 聚合后播放(aplay/paplay/ffplay/afplay/SoundPlayer)

二进制分块协议(设备<->网关):
- 录像(设备->网关): cmd_data_start/0x2帧/cmd_data_end
- 音频(网关->设备): cmd_speech_start/0x2帧/cmd_speech_end
- 设备端 WS 读写侧都支持 0x2 帧; N/A 服务端 readFrame 需配套(已发群)

消息重放/交互:
- sendChat 带 client_msg_id 唯一ID(服务端可去重), 超时明确提示勿重复发送
- 托盘菜单: 信息项 enabled(不再灰字)+200ms防抖+连接缓存, 首建立即弹出
- 托盘显示连接/设备桥/远控活动状态

UI:
- 设备页本机卡片: 设备通道配置(网关/ws_token/screensue屏幕/cmdrun目录/沙箱)
- 设备列表经 webui 反代 /api/v1/device/online 拉取
- 连接管理移除 device 类型(设备独立为 GUI 组件), toggleConnType/saveConnForm 清理
- 字体对比度提升(text-muted/secondary重调色), 内联小字 10/11px->12/13px

preload: 新增 displays.list IPC
This commit is contained in:
2026-08-20 09:07:41 +08:00
parent 768c73889e
commit c29abe9569
4 changed files with 980 additions and 250 deletions

View File

@ -45,8 +45,8 @@
--bg-input: rgba(13, 18, 34, 0.75);
--bg-hover: rgba(255, 255, 255, 0.06);
--text-primary: #eef1f8;
--text-secondary: #a7b0c4;
--text-muted: #77809a;
--text-secondary: #b8c1d6;
--text-muted: #93a0b8;
--border-color: rgba(255, 255, 255, 0.09);
--accent: #ff7fac;
--accent-bg: rgba(255, 127, 172, 0.14);
@ -98,8 +98,8 @@
--bg-input: rgba(255, 224, 233, 0.55);
--bg-hover: rgba(255, 127, 172, 0.08);
--text-primary: #3b2030;
--text-secondary: #7a5c6b;
--text-muted: #a48a96;
--text-secondary: #6b4b5c;
--text-muted: #8f6f7d;
--border-color: rgba(201, 36, 98, 0.14);
--accent: #c92462;
--accent-bg: #ffe4e9;
@ -290,7 +290,7 @@ body {
transition:
background 0.2s,
color 0.2s;
font-size: 14px;
font-size: 15px;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
user-select: none;
@ -707,13 +707,13 @@ body.maximized .tb-max svg {
transform: translateY(-1px);
}
.card h2 {
font-size: 15px;
font-size: 16px;
font-weight: 600;
margin-bottom: 12px;
color: var(--text-primary);
}
.card h3 {
font-size: 13px;
font-size: 14px;
font-weight: 600;
color: var(--text-secondary);
margin: 16px 0 8px;
@ -901,7 +901,7 @@ select {
border-radius: var(--radius-sm);
padding: 8px 12px;
color: var(--text-primary);
font-size: 13px;
font-size: 14px;
width: 100%;
margin-bottom: 10px;
outline: none;
@ -923,9 +923,9 @@ textarea {
}
label {
display: block;
font-size: 11px;
font-size: 13px;
color: var(--text-secondary);
margin-bottom: 3px;
margin-bottom: 4px;
font-weight: 500;
}
pre {
@ -1597,10 +1597,10 @@ code {
margin-bottom: 16px;
}
.settings-tabs span {
padding: 6px 14px;
font-size: 13px;
padding: 7px 16px;
font-size: 14px;
cursor: pointer;
color: var(--text-muted);
color: var(--text-secondary);
border-radius: var(--radius-pill);
border: 1px solid transparent;
transition: all 0.15s;
@ -1619,18 +1619,18 @@ code {
}
.settings-key {
font-family: var(--font-mono);
font-size: 11px;
color: var(--text-muted);
margin-bottom: 2px;
font-size: 13px;
color: var(--text-secondary);
margin-bottom: 3px;
}
.kv-row {
display: flex;
padding: 6px 0;
padding: 7px 0;
border-bottom: 1px solid var(--kv-border);
font-size: 13px;
font-size: 14px;
}
.kv-row .key {
color: var(--text-muted);
color: var(--text-secondary);
width: 180px;
flex-shrink: 0;
}
@ -1716,8 +1716,8 @@ code {
vertical-align: 1px;
}
.conn-item .conn-url {
font-size: 11px;
color: var(--text-muted);
font-size: 12px;
color: var(--text-secondary);
margin-top: 2px;
}
.conn-item .conn-actions {