返回首页

移动端响应式聊天:React 组件

文章描述聊天移动版的关键更新:使用 MobileBottomNav 的响应式 UI、重构输入支持 PlantUML 和投票、RNNoiser 用于声音。WebView 优化的组件代码和架构解决方案。

移动聊天:新 UI 和代码优化
Advertisement 728x90

移动端聊天适配:全新组件与优化方案

团队已为基于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处理视图切换。

Google AdInline article slot

优化的服务器列表

针对触控交互,创建了MobileServersList以替代桌面端的LeftMenu。左侧面板以类似Discord的风格显示服务器图标,右侧面板显示所选服务器的主题。该组件复用useLeftMenu钩子处理业务逻辑:加载列表、WebSocket事件、创建服务器。这最大程度减少了代码重复,并消除了桌面布局带来的渲染延迟。

点击服务器时,右侧主题会更新而无需完全重新加载。点击主题即可打开聊天。

改进的输入框与扩展格式化功能

输入框适配了Mattermost格式,防止编辑器元素换行。功能包括:

Google AdInline article slot
  • 粗体和斜体:标准的Markdown格式化。
  • 代码块:支持语法高亮,便于插入代码片段。
  • PlantUML图表:直接从文本标记生成UML图,嵌入消息中。
  • 引用:使用>进行块级高亮。
  • 链接:嵌入超链接。
  • 列表:项目符号或编号列表。
  • 投票:交互式投票功能。

这使得高级开发者无需借助外部工具即可交换技术内容。

上下文菜单与手势操作

底部菜单通过长按激活——复用现有组件并应用移动端样式(isMobile)。消息反应在自适应浮层中打开。右侧菜单通过CSS和条件逻辑针对移动设备进行了优化。

单独的“定时消息”部分汇总所有计划消息,便于快速查看调度器。

Google AdInline article slot

移动端用户个人资料

创建了专用的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

Advertisement 728x90

继续阅读