# TS Mobile UI / UX 重构设计规范 ## 1. 文档目标 本文档用于指导 TS Mobile Android 客户端下一阶段 UI / UX 重构。 重构目标不是简单地: - 修改颜色 - 增加圆角 - 增加动画 - 更换 Material 组件 - 美化现有页面 而是重新建立一套符合 TeamSpeak 使用模型的移动端信息架构。 核心目标: > 让用户始终清楚自己连接到了哪个服务器、当前处于哪个频道、频道里有哪些成员,以及当前语音和聊天状态。 ------ # 2. 核心产品模型 TeamSpeak 与普通聊天软件最大的区别之一,是: > 用户连接服务器后,会直接处于某个频道上下文中。 因此 TS Mobile 不应该建立: ```text 服务器 ↓ 进入频道 ``` 这样的用户流程。 正确模型: ```text 未连接 ↓ 连接服务器 ↓ 已连接 + 已进入频道 ↓ 服务器工作空间 ``` 连接成功后: ```text Server └── Current Channel ├── Chat ├── Members └── Voice ``` 因此: **Current Channel 是整个 App 最重要的上下文状态。** ------ # 3. 顶层状态模型 建议 UI 层只暴露三个主要状态: ```text Disconnected ↓ Connecting ↓ Connected ``` 其中: ### Disconnected 没有连接服务器。 显示: - Logo - Server Address - Nickname - Password - Recent Servers - Connect ### Connecting 连接服务器过程中。 这是连接流程中的 Loading 状态,而不是独立产品页面。 可以显示: ```text Connecting... server.example.com:9987 ``` ### Connected 连接成功后直接进入当前频道。 ```text Server Current Channel Chat / Channels Voice Members ``` 不应该存在: ```text Connected but no channel ``` 这样的普通 UI 状态。 ------ # 4. 产品信息架构 最终信息架构: ```text TS Mobile │ ├── Connection │ ├── Connect │ ├── Connecting │ └── Disconnected │ └── Server Space │ ├── Server Header │ ├── Current Channel │ ├── Chat │ ├── Channels │ ├── Channel Tree │ └── Channel Members │ ├── Voice │ └── Server Drawer ├── Server Info ├── Voice Settings ├── Notifications ├── Appearance └── Disconnect ``` ------ # 5. Server Space 连接成功后,整个 App 进入一个统一的: > Server Space 而不是分别进入: ```text ChannelScreen ChatScreen VoiceScreen ``` 这些功能都属于当前 Server Space。 推荐结构: ```text ┌────────────────────────────┐ │ Server Header │ ├────────────────────────────┤ │ │ │ │ │ Current Content │ │ │ │ │ ├────────────────────────────┤ │ Current Channel │ ├────────────────────────────┤ │ Chat Channels │ └────────────────────────────┘ ``` ------ # 6. Server Header Server Header 负责展示服务器上下文。 推荐: ```text ┌────────────────────────────┐ │ ☰ My Server ⋮ │ │ ● Connected · 12 online│ └────────────────────────────┘ ``` 包含: - Server Name - Connection Status - Online Count - Navigation / Drawer - More 不建议长期显示: ```text server.example.com:9987 ``` 服务器地址属于 Server Detail。 ------ # 7. Current Channel Context Bar 这是本次重构最重要的 UI 组件之一。 它不是普通 Card。 它是: > 当前通信上下文。 推荐: ```text ┌────────────────────────────┐ │ # General 12 │ │ ● ● ● ● +8 │ └────────────────────────────┘ ``` 显示: - Channel Name - Channel Type - Member Count - 少量成员头像 - 当前语音状态 例如: ```text # General 12 members ● ● ● ● +8 ``` 用户切换频道后: ```text # General ``` 直接变成: ```text # Gaming ``` 同时: - Chat 改变 - Members 改变 - Voice Context 改变 ------ # 8. Chat / Channels 导航 推荐保留底部双 Tab: ```text ┌────────────────────────────┐ │ │ │ Main Content │ │ │ ├────────────────────────────┤ │ # General 12 │ ├────────────────────────────┤ │ Chat Channels │ └────────────────────────────┘ ``` 但需要明确: > Chat / Channels 是视图,不是产品实体。 真正的实体关系: ```text Server └── Current Channel ├── Chat └── Members / Channel Tree ``` ------ # 9. Chat Chat 是当前频道的文字消息流。 推荐布局: ```text ┌────────────────────────────┐ │ # General 12 │ ├────────────────────────────┤ │ │ │ Alex │ │ Hello │ │ │ │ Tom │ │ Anyone playing? │ │ │ │ Alex │ │ Let's go │ │ │ ├────────────────────────────┤ │ + Message... ↑ │ └────────────────────────────┘ ``` ------ # 10. Chat 消息设计 不建议过度模仿: - WhatsApp - Telegram - Discord TeamSpeak 更适合: > 紧凑型实时频道消息流。 连续消息建议合并: ```text Alex Hello Anyone playing? Let's go ``` 而不是: ```text Alex Hello Alex Anyone playing? Alex Let's go ``` 这样可以明显减少垂直空间消耗。 ------ # 11. Chat 输入框 推荐: ```text ┌────────────────────────────┐ │ + Message... ↑ │ └────────────────────────────┘ ``` 输入区域保持较大的触控高度。 不要把: - Emoji - 文件 - 图片 - 语音 - 更多 - 格式化 全部放到一级 UI。 TeamSpeak 的文字聊天不是核心功能。 ------ # 12. Channels Channels 页面负责: > 浏览服务器结构 + 查看成员。 推荐: ```text CHANNELS ▼ Lobby 5 ● Alice ● Bob ▼ General 12 ● Tom ● Alex ● Mike ▶ Gaming 8 ▶ Music 3 ▶ AFK 2 ``` 频道节点应该保持紧凑。 ------ # 13. Channel Item 频道 Item 推荐包含: ```text [展开] [频道类型] [名称] [人数] ``` 例如: ```text ▼ 🎙 General 12 ``` 避免在频道 Item 内塞入过多状态。 详细信息通过: > Channel Detail 查看。 ------ # 14. Current Channel 与 Channel Tree 的关系 频道树中的当前频道应该具有明显但克制的选中状态。 例如: ```text ▶ Lobby ▼ General 12 ● Alex ● Tom ▶ Gaming 8 ``` 当前频道: ```text General ``` 可以使用: - Surface 提升 - Primary 色边 - Icon 高亮 但不要使用非常强烈的纯色块。 ------ # 15. Member Item 成员列表推荐: ```text [Avatar] Alex ● Online ``` 如果正在说话: ```text [Avatar] Alex ● Speaking ``` 但正常状态不要一直显示文字。 推荐使用: ```text Avatar + Status Indicator + Nickname ``` ------ # 16. Member 状态系统 至少定义: ```text Online Idle Away Muted Deafened Speaking Server Muted Disconnected ``` 其中: > Speaking 是最重要的实时状态。 可以通过: - Avatar Ring - 状态点 - 小型音量指示器 表达。 避免大面积动态动画。 ------ # 17. Member Action 成员操作统一进入 Action Menu。 推荐: ```text Alex Interaction Poke Information Copy Nickname Copy UID Management Move Kick from Channel Kick from Server ``` 危险操作单独处理。 例如: ```text Kick from Server ``` 需要二次确认。 ------ # 18. Voice Voice 不应该成为独立一级页面。 它属于: ```text Current Channel └── Voice ``` 因此: ```text Current Channel = General ``` 意味着: ```text Voice Context = General ``` 切换: ```text General → Gaming ``` Voice Context 同时切换。 ------ # 19. Voice UI 推荐将语音设计成一个状态组件。 ### Connected ```text ┌────────────────────────────┐ │ 🎙 General 12 │ │ ● Connected │ │ │ │ [ PTT ] │ │ │ │ Mic Speaker│ └────────────────────────────┘ ``` ### Speaking ```text ┌────────────────────────────┐ │ 🎙 General 12 │ │ │ │ [ SPEAKING ] │ │ │ └────────────────────────────┘ ``` PTT 是语音 UI 的核心操作。 ------ # 20. PTT 状态 PTT 至少存在: ```text Idle ↓ Pressed ↓ Speaking ``` 反馈必须: - 快 - 明确 - 稳定 - 低干扰 不建议加入复杂粒子效果或大面积动画。 ------ # 21. Server Drawer Server Drawer 的职责: > 管理当前服务器。 不是简单的服务器详情卡。 推荐: ```text ┌────────────────────────────┐ │ Server │ │ │ │ My Server │ │ ● Connected │ │ │ ├────────────────────────────┤ │ Server Info │ │ server.example.com:9987 │ │ 12 / 64 online │ ├────────────────────────────┤ │ Voice │ │ Notifications │ │ Appearance │ │ Settings │ ├────────────────────────────┤ │ │ │ Disconnect │ └────────────────────────────┘ ``` ------ # 22. Server Detail Server Detail 可以展示: ```text Server Name Address Port Version Online Users Max Users Connection Quality ``` 但这些信息不应该占用主界面。 ------ # 23. Connection Screen 连接页是唯一真正意义上的“未连接 UI”。 推荐: ```text TS Mobile Connect to your TeamSpeak server Server address ┌────────────────────────────┐ │ server.example.com │ └────────────────────────────┘ Port ┌────────────────────────────┐ │ 9987 │ └────────────────────────────┘ Nickname ┌────────────────────────────┐ │ Player │ └────────────────────────────┘ [ Connect ] Recent Servers ``` ------ # 24. Recent Servers 如果存在历史连接: ```text Recent Servers ┌────────────────────────────┐ │ My Server │ │ server.example.com:9987 │ │ › │ └────────────────────────────┘ ┌────────────────────────────┐ │ Community Server │ │ ts.example.net:9987 │ │ › │ └────────────────────────────┘ ``` 最近连接应该成为高频入口。 首次使用才重点展示完整 Connect Form。 ------ # 25. Connecting Connecting 不建议做成长期存在的独立页面。 推荐: ```text TS Mobile ◯ Connecting... server.example.com:9987 Cancel ``` 连接完成: ```text 直接进入 Server Space ``` 而不是: ```text Connecting → Connected → Select Channel ``` ------ # 26. Disconnect Disconnect 后: ```text Server Space ↓ Disconnected ↓ Connection Screen ``` 重新连接: ```text Connect ↓ Connecting ↓ Current Channel ``` ------ # 27. Channel Switch 用户点击频道: ```text General ``` 切换: ```text Gaming ``` 本质上只是: ```text currentChannelId ``` 发生变化。 UI 同步更新: ```text Current Channel Chat Members Voice ``` 不应该把它理解为: ```text Navigation → New Page ``` 而应该是: ```text Context → New Channel ``` ------ # 28. Bottom Sheet / Dialog / Drawer 职责 项目中已经存在多种 Sheet、Dialog、Card。 需要建立明确规则。 ### Page 用于主要任务。 ```text Connect Chat Channels ``` ### Drawer 用于全局导航和 Server 控制。 ```text Server Settings Disconnect ``` ### Bottom Sheet 用于当前上下文详情。 ```text Channel Detail Member Detail Voice Detail ``` ### Dialog 用于: ```text 确认 危险操作 输入 ``` 避免出现: ```text BottomSheet ↓ Dialog ↓ BottomSheet ``` 这种复杂交互链。 ------ # 29. Design Token 建议继续强化现有: ```text Color Shapes Theme Type UiTokens ``` 体系。 统一定义: ```text Spacing xs = 4dp sm = 8dp md = 12dp lg = 16dp xl = 24dp ``` ------ # 30. Radius 建议: ```text List Item 8~12dp Card 12~16dp Floating Card 16~20dp Bottom Sheet 24dp Avatar Circle ``` 不要所有组件统一 24dp。 圆角本身应该承担层级表达作用。 ------ # 31. 控件尺寸 建议建立固定 Control Token: ```text Small Button 40dp Normal Button 48dp Input 52dp List Item 52~56dp Avatar Small 32dp Avatar Medium 40dp Avatar Large 56dp ``` 避免大量: ```text 14.5dp 17dp 24.5dp ``` 这种局部修正值。 如果确实需要特殊值,应有明确视觉原因。 ------ # 32. Typography 推荐建立: ```text Title 16~20sp / Bold Body 14~16sp / Regular Secondary 12~14sp / Regular Caption 11~12sp / Regular ``` 移动端不要大量使用过小文字。 尤其: - Channel Name - Nickname - Message 必须优先保证可读性。 ------ # 33. Semantic Colors 不要让每个组件自己定义颜色。 统一语义: ```text Primary Accent Success Warning Error Muted Disabled Speaking ``` 例如: ```text Connected → Success Speaking → Accent Reconnecting → Warning Disconnected → Error ``` ------ # 34. 状态视觉规范 状态优先级: ```text Connected ↓ Current Channel ↓ Speaking ↓ Other User States ``` 越重要的状态,视觉反馈越明显。 但不要同时让多个状态都高亮。 ------ # 35. 动画规范 动画不应该成为 UI 主体。 优先: ```text 状态变化动画 ``` 而不是: ```text 页面切换动画 ``` 推荐: - Channel selected - Speaking - PTT pressed - Connection state - Reconnect banner 使用短时、低幅度动画。 ------ # 36. 视觉风格 最终建议采用: ```text Modern Flat Native Compact Readable Low Decoration ``` 不是: ```text Discord Clone ``` 也不是: ```text Material 3 Demo ``` 而是: > Modern Native Communication Client ------ # 37. 推荐视觉层级 整体控制为: ```text Background ↓ Surface ↓ Elevated Surface ↓ Primary Action ``` 例如: ```text Background 页面背景 Surface Chat / Channel List Elevated Surface Current Channel / Voice Primary Connect / PTT / Send ``` 不要给每一个组件增加独立背景。 ------ # 38. 主页面最终结构 最终推荐: ```text ┌─────────────────────────────┐ │ ☰ My Server ⋮ │ │ ● Connected · 12 online │ ├─────────────────────────────┤ │ │ │ # General 12 │ │ ● ● ● ● +8 │ │ │ ├─────────────────────────────┤ │ │ │ │ │ Chat Content │ │ │ │ │ ├─────────────────────────────┤ │ + Message... ↑ │ ├─────────────────────────────┤ │ Chat Channels │ └─────────────────────────────┘ ``` Channels: ```text ┌─────────────────────────────┐ │ ☰ My Server ⋮ │ │ ● Connected · 12 online │ ├─────────────────────────────┤ │ # General 12 │ ├─────────────────────────────┤ │ CHANNELS │ │ │ │ ▼ Lobby 5 │ │ ● Alice │ │ ● Bob │ │ │ │ ▼ General 12 │ │ ● Alex │ │ ● Tom │ │ │ │ ▶ Gaming 8 │ │ ▶ Music 3 │ │ ▶ AFK 2 │ ├─────────────────────────────┤ │ Chat Channels │ └─────────────────────────────┘ ``` ------ # 39. UI 组件层级 建议最终组件结构: ```text App │ └── ServerSpace │ ├── ServerHeader │ ├── CurrentChannelBar │ ├── Content │ ├── ChatView │ │ ├── MessageList │ │ └── MessageInput │ │ │ └── ChannelsView │ ├── ChannelTree │ └── MemberList │ ├── VoiceStatus │ ├── BottomNavigation │ └── ServerDrawer ``` ------ # 40. 推荐代码重构方向 现有代码已经有: ```text AppTopBar MessageInputBar VoiceCard VoiceControlBar ServerDetailCard ClientActionMenu ``` 下一阶段建议进一步抽象为: ```text ui/components/ │ ├── server/ │ ├── ServerHeader │ ├── ServerDrawer │ └── ServerStatus │ ├── channel/ │ ├── CurrentChannelBar │ ├── ChannelTree │ ├── ChannelItem │ └── ChannelDetail │ ├── client/ │ ├── ClientItem │ ├── ClientAvatar │ ├── ClientStatus │ └── ClientActionMenu │ ├── chat/ │ ├── MessageList │ ├── MessageItem │ └── MessageInput │ └── voice/ ├── VoiceStatus ├── PTTButton └── VoiceControl ``` 这样比继续按照 Screen 切组件更加容易维护。 ------ # 41. ViewModel 状态建议 UI 最终应该围绕一个核心 Server Space 状态: ```text ServerSpaceState connectionState server currentChannel channels clients chatMessages voiceState ``` 其中: ```text currentChannel ``` 是核心状态。 UI 不应该自己维护多个互相独立的: ```text selectedChannel voiceChannel chatChannel memberChannel ``` 否则很容易出现状态不同步。 应该: ```text currentChannelId ``` 作为统一来源。 ------ # 42. P0 重构优先级 ## P0-1 重新定义 Server Space。 目标: ```text Connected ↓ Current Channel ``` 作为整个 App 的核心模型。 ------ ## P0-2 重构: ```text CurrentChannelBar ``` 让它成为全局 Context Bar。 ------ ## P0-3 重新整理: ```text Chat Channels ``` 两个 Tab 的关系。 ------ ## P0-4 重构: ```text Voice PTT Voice Status ``` 让它们绑定 Current Channel。 ------ ## P0-5 统一: ```text Server Header Server Drawer ``` ------ # 43. P1 完成: ```text Channel Tree Member Item Member Detail Channel Detail Recent Servers Server Settings ``` 并统一 Sheet / Dialog / Drawer。 ------ # 44. P2 最后处理: ```text Animation Gesture Motion Micro Interaction Advanced Voice Feedback ``` ------ # 45. 最终设计原则 TS Mobile 的 UI 应该始终遵循以下五条原则: ## 1. Server 是工作空间 连接服务器以后,用户进入 Server Space。 ## 2. Current Channel 是核心上下文 所有通信行为围绕当前频道。 ## 3. Chat / Channels 是视图 它们不是两个独立产品页面。 ## 4. Voice / Members / Chat 都绑定 Current Channel 切换频道意味着整个通信上下文切换。 ## 5. UI 优先表达状态,而不是装饰 用户第一眼应该知道: ```text Server Current Channel Members Voice State Chat ``` 而不是看到: ```text 圆角 阴影 动画 渐变 装饰 ``` ------ # 46. 最终目标 最终用户打开 TS Mobile 后: ```text 第一次使用 ↓ 连接服务器 ↓ 直接进入服务器默认 / 当前频道 ↓ 看到当前频道 ↓ 可以聊天 ↓ 可以查看频道树 ↓ 可以看到成员 ↓ 可以进行语音通信 ``` 整个过程中不应该出现多余的: ```text 服务器主页 选择频道 进入频道 频道主页 聊天主页 语音主页 ``` 而应该保持一个稳定的模型: ```text Server + Current Channel + Current View ``` 其中: ```text Current View = Chat or Channels ``` 这是 TS Mobile 最适合移动端的 UI / UX 核心架构。 ------ # 47. 一句话定义 如果最终需要给这个 UI 架构定一句设计原则: > **TS Mobile 不是“服务器列表 + 聊天 + 频道 + 语音”的功能集合,而是一个以 Server 为工作空间、以 Current Channel 为核心上下文的移动 TeamSpeak 客户端。**