移动端聊天适配:全新组件与优化方案
团队已为基于WebView的应用实现了全面的移动端响应式设计,通过精简功能降低加载负担。新增了用于音频处理的RNNoiser库、定时消息功能,改进了输入框并扩展了格式化选项,降低了请求延迟,并优化了数据存储。所有改动均面向使用React Native和WebView的中高级开发者。
触控界面的自适应UI
开发了MobileBottomNav——一个极简的底部导航栏,包含五个标签页:服务器、聊天、看板、搜索和个人资料。该组件为无状态设计,仅通过onViewChange传递当前视图ID,不包含内部逻辑或API调用。
import { Icon } from '@shared/ui/Icon';
import { UserAvatar } from '@shared/ui/UserAvatar';
export function MobileBottomNav({
currentView,
onViewChange,
user
}) {
const tabs = [
{ id: 'general-chats', icon: 'groupChat', label: '服务器' },
{ id: 'direct-chats', icon: 'chat', label: '聊天' },
{ id: 'chat-board', icon: 'board', label: '看板' },
{ id: 'mobile-search', icon: 'search', label: '搜索' },
{ id: 'profile', label: '个人资料', isProfile: true },
];
return (
<nav className="mobile-bottom-nav">
{tabs.map(tab => (
<button
key={tab.id}
className={`mobile-bottom-nav-tab ${currentView === tab.id ? 'active' : ''}`}
onClick={() => onViewChange(tab.id)}
>
<span className="mobile-bottom-nav-icon">
{tab.isProfile ? (
<UserAvatar
avatar={user?.avatar}
userId={user?.user_id}
username={user?.username}
status={user?.status}
size={28}
showStatus={false}
className="mobile-bottom-nav-avatar"
/>
) : (
<Icon name={tab.icon} size={22} />
)}
</span>
<span className="mobile-bottom-nav-label">{tab.label}</span>
</button>
))}
</nav>
);
}
个人资料标签页使用UserAvatar替代图标,便于视觉识别。父组件根据接收的ID处理视图切换。
优化的服务器列表
针对触控交互,创建了MobileServersList以替代桌面端的LeftMenu。左侧面板以类似Discord的风格显示服务器图标,右侧面板显示所选服务器的主题。该组件复用useLeftMenu钩子处理业务逻辑:加载列表、WebSocket事件、创建服务器。这最大程度减少了代码重复,并消除了桌面布局带来的渲染延迟。
点击服务器时,右侧主题会更新而无需完全重新加载。点击主题即可打开聊天。
改进的输入框与扩展格式化功能
输入框适配了Mattermost格式,防止编辑器元素换行。功能包括:
- 粗体和斜体:标准的Markdown格式化。
- 代码块:支持语法高亮,便于插入代码片段。
- PlantUML图表:直接从文本标记生成UML图,嵌入消息中。
- 引用:使用>进行块级高亮。
- 链接:嵌入超链接。
- 列表:项目符号或编号列表。
- 投票:交互式投票功能。
这使得高级开发者无需借助外部工具即可交换技术内容。
上下文菜单与手势操作
底部菜单通过长按激活——复用现有组件并应用移动端样式(isMobile)。消息反应在自适应浮层中打开。右侧菜单通过CSS和条件逻辑针对移动设备进行了优化。
单独的“定时消息”部分汇总所有计划消息,便于快速查看调度器。
移动端用户个人资料
创建了专用的MobileProfilePage组件,包含用户卡片、状态和设置部分。
return (
<div className="mobile-profile-page">
<div className="mobile-profile-page-header">
<div className="mobile-profile-user-card">
<div className="mobile-profile-avatar">
{avatarUrl ? (
<img src={avatarUrl} alt={user.username} className="mobile-profile-avatar-img" />
) : (
<div className="mobile-profile-avatar-placeholder">{initials}</div>
)}
<span className={`status-icon ${user.status || 'offline'} mobile-profile-status"></span>
</div>
<div className="mobile-profile-info">
<div className="mobile-profile-username">{user.username}</div>
<div className="mobile-profile-handle">{user.handle || `@${user.username}`}</div>
</div>
</div>
</div>
<div className="mobile-profile-page-content">
<div className="mobile-profile-section">
<div className="mobile-profile-item" onClick={onOpenProfile}>
<span className="mobile-profile-item-icon"><Icon name="user" size={20} /></span>
<span className="mobile-profile-item-text">编辑个人资料</span>
<span className="mobile-profile-item-arrow"><Icon name="chevronRight" size={16} /></span>
</div>
{/* 其他项目类似 */}
</div>
{/* 状态和退出登录部分 */}
</div>
</div>
);
每个项目触发回调;组件不管理模态框或导航。
其他改进
- RNNoiser:集成以降低语音消息和通话中的噪音。
- 延迟:通过缓存和批处理优化请求。
- 数据存储:完全重构,考虑移动设备内存限制。
这些改动确保了在低端设备上的性能,同时不牺牲功能。
核心要点
- 完整的WebView响应式设计,为触控界面提供独立组件。
- 通过钩子复用业务逻辑,避免重复。
- 扩展输入功能,支持PlantUML和投票,适用于技术聊天。
- 定时消息集中展示,便于规划。
- UI组件采用无状态设计,确保渲染可预测。
— Editorial Team
暂无评论。