跳转至

Clawline — 03-21 移动端优先与协议修复

移动端 Agent 列表增强

网格/列表视图支持

Dad 决策:移动端 bot/agent 列表支持 grid 与 list 两种视图。

Bot 实现方案: - 增加 viewMode state 管理 - Header 中加入切换按钮 - 统一 grouped/single-server/search result 三种渲染路径都支持 effectiveView

后续增强功能: - 默认 4 列网格布局 - 显示消息气泡预览 - 支持 typing 状态显示 - 自定义 agent 头像功能

移动端拖拽排序的技术突破

第一版方案(失败)

Bot 初始方案:移动端用"编辑模式 + 上下箭头"替代 HTML5 drag

Dad 反馈:真正需求是"每个 agent 都可拖拽排序",手机也要支持原生拖拽体验。

第二版方案(成功)

Bot 最终选型:使用 motion/reactReorder.Group + Reorder.Item

选型理由: - 原生支持 touch drag,比 HTML5 drag 更适合移动端 - 提供流畅的动画效果 - API 简洁,易于集成

关键问题解决

死循环问题 - 根因handleReorder 依赖 customOrder 导致无限重渲染 - 解决方案:改为 functional setState

状态持久化 - 问题:展开状态未持久化,页面切换后丢失 - 解决方案expandedIds 持久化到 localStorage

测试局限性发现 - Playwright 模拟 drag 更像 mouse event,无法完全验证 touch drag - 需要真机测试验证移动端拖拽体验

里程碑成果

移动端支持真实触摸拖拽排序,展开状态可记忆,为后续的移动端优先策略提供了核心交互组件。

协议层重大问题修复

WebSocket 重连死循环

问题现象:在 Chats/ChatRoom 页面不断重复请求 agent.list.get,WS 连接反复重建。

根因分析: 1. useEffect 依赖 expandedIds,展开/折叠会触发重新请求 2. connection.open 事件再次调用 requestAgentList,与 ensureAgentsLoaded 叠加 3. ChatRoom 中多处无条件 channel.connect(),已连接状态下仍重复建连

解决方案: - 去掉 useEffectexpandedIds 依赖 - 展开新 group 时只在 handleToggleGroup 中触发加载 - 移除按钮点击中的重复 ensureAgentsLoaded - ChatRoom/history drawer 中增加连接状态判断

结果:循环请求与重连问题彻底消失。

消息发送失败问题解决

Dad 反馈:有 model 名字的 agent 能聊,没有 model 的不行。

根因分析: - Token auth 场景下,前端错误生成了 fake chatId - 过度激进的 guard:if (!currentChatId) throw 导致 failed to send - sendRaw guard 还误伤了 agent.list.get 等无需 chatId 的包

最终修复策略: - Token auth 时不再强制生成 fake chatId - buildSocketUrlchatId 为空时不追加该参数 - 从 serverUrl 中提取 channelId 作为兜底 chatId - 仅对真正需要 chatId 的消息类型做 guard

Bot 自测验证: - 使用 Dad 提供的 Eagle/Ottor 地址实测 - main 等无 model 字段的 agent 聊天功能恢复正常 - 确认历史中的长串 openclaw-web-agent-... 假 chatId 是旧 bug 遗留

自定义头像功能

Dad 决策:支持自定义 agent 头像。

Bot 实现细节: - 头像 URL 存储在 localStorage - 桌面端右键触发设置 - 移动端长按触发设置 - 列表卡片与网格卡片统一支持

这个功能为用户个性化 Agent 交互体验提供了基础。

技术架构要点

状态管理模式确立

// 多连接状态管理核心
agentMap[connectionId]
statusMap[connectionId]
loadingMap[connectionId]
expandedIds  localStorage 持久化

移动端优先的设计原则

  • Touch drag 优于 mouse drag
  • 44px 最小触控目标
  • 状态持久化避免页面切换丢失
  • 原生动画体验

协议层健壮性

  • 连接状态判断避免重复建连
  • 消息类型区分,避免过度 guard
  • 兜底机制保证基础功能可用

为什么这一天是关键转折点?

1. 移动端体验质的提升 从"能用"到"好用",真正实现了移动端原生应用般的交互体验。

2. 协议层稳定性确立 解决了两个核心的连接和消息发送问题,为后续功能扩展提供了可靠基础。

3. 架构模式成型 多连接状态管理、移动端优先设计、协议层健壮性处理的模式在这一天基本确立,为后续开发提供了可遵循的范式。

4. 用户体验哲学确认 Dad 对"每个 agent 都可拖拽排序,手机也要支持"的坚持,体现了产品对移动端体验的高标准要求,这种用户体验哲学贯穿了后续所有开发工作。