- Task 15 UI:6 项原创特色(说话者流光 / 柔性网格 / 自视频浮窗 / 静音氛围色 / 入会滑入 / NetworkBadge 3 条波浪)+ 说话者双源探测(RTP audioLevel + WebAudio RMS)+ 主持人四件套(静音/开麦/转让/踢出) - 新增 SelfVideoFloat 浮窗组件 + 4 份 design-system 页面文档(home / preview / room / invite) - 媒体回归补丁(手工联调触发): * 后端 signal_service 在 OnRoomJoin 追加 pushExistingRoomState → 向新加入者补发历史 producers + 历史成员 audio/video 状态 * 新增 Redis Hash memberStateKey 持久化成员 audio/video enabled,OnMemberStateChanged 落盘、cleanupUserResources 清理 * 前端 _broadcastSelfState 在本地音视频开关末尾同步 state.changed;_afterJoined 先 getRoom 再 room.join 修复后入者成员状态时序;_onMemberStateChanged 占位兜底 * _cleanupRemoteProducer 改为按 producerId 精准清理(修复 "关音频误关视频") * _onRoomEnded + createAndEnter/joinAndEnter 强化 reset(修复重入会看不到自己画面) * mediasoup-client ensureSend/RecvTransport 引入 in-flight Promise 锁防并发重复建连 - 文档同步:CURRENT_STATUS.md / Task 15 plan / phase2e-2 implementation plan Made-with: Cursor
3.2 KiB
3.2 KiB
Meeting Invite (邀请弹窗) Page Overrides
PROJECT: EchoChat Generated: 2026-04-24 (via Task 15 UI 打磨) Page Type: Bottom Sheet / Center Modal — Share Meeting Component:
frontend/src/components/meeting/InviteDialog.vue
⚠️ Rules in this file override
design-system/echochat/MASTER.md.
Page Layout
- 容器类型: 居中 Modal(桌面端)/ 底部 BottomSheet(移动端
<= 750px) - 遮罩:
rgba(0, 0, 0, 0.55)+ backdrop blur8px - 容器:
- 桌面:
520rpx × auto,#FFFFFF,圆角24rpx,阴影0 24rpx 48rpx rgba(0,0,0,0.35) - 移动:
100vw,顶部圆角24rpx 24rpx 0 0
- 桌面:
- Z-index: 200(同 MemberPanel 同级,因是互斥显示)
内容分区
1. 头部
- 关闭按钮(右上角
56rpx圆形按钮)+ 标题 "邀请成员加入" - 副标题:会议标题 + 会议号格式化
xxx-xxx-xxx
2. 分享方式 3 选项(并列)
| 选项 | 图标 | 说明 | 操作 |
|---|---|---|---|
| 复制链接 | link 24px |
带 Token 链接,含密码(若有) | 复制到剪贴板 + toast |
| 复制会议号 | hash 24px |
纯会议号(需对方手动输入密码) | 复制 + toast |
| 邀请联系人 | user-plus 24px |
打开联系人选择器(复用 Phase 2a 组件) | 打开抽屉 |
- 布局: 水平排列,每项尺寸
144rpx × 144rpx;图标上方居中,文案下方居中 - Hover / Active: 卡片背景
#F3F4F6→#E5E7EB;scale(0.98)on active
3. 信息展示
- 邀请链接区: 单行滚动 input(readonly)+ 右侧 "复制" 按钮
- 背景
#F8FAFC,圆角12rpx,高72rpx
- 背景
- 密码提示: 若会议有密码,额外展示
Password:标签 + 密码 pill(可点击复制) - 过期时间: 小字提示 "链接 24 小时内有效"(若后端返回过期时间)
Color Palette
| 用途 | Hex |
|---|---|
| 背景 | #FFFFFF |
| 选项卡片 | #F8FAFC |
| 选项悬停 | #F3F4F6 |
| 主 CTA | #2563EB |
| 文本主 | #1E293B |
| 辅助文本 | #64748B |
| Toast 成功 | #10B981 |
Typography
| 层级 | Size | Weight |
|---|---|---|
| 标题 | 32rpx |
600 |
| 副标题 | 24rpx |
400 |
| 选项名 | 26rpx |
500 |
| 输入框 | 26rpx |
400,monospace for code |
Motion
- 打开:
- 桌面: 遮罩 fade-in
180ms+ 容器scale(0.96) → 1 + opacity 0 → 1,220ms cubic-bezier(0.2,0.8,0.2,1) - 移动: 底部滑入
translateY(100%) → 0,260ms
- 桌面: 遮罩 fade-in
- 关闭: 反向播放,时长
160ms - 复制成功 toast: 顶部滑入
translateY(-20px) → 0停留1.2s再滑出
Interactions
- 复制链接:
clipboard.writeText(joinLink)→ 成功显示 toast "链接已复制";失败显示Modal文本兜底- 含密码的链接形如
https://echochat.app/#/pages/meeting/join?code=123456789&token=xxx
- 复制会议号:
- 复制无密码纯 9 位数(不含分隔符)
- 联系人选择器:
- 打开
ContactPicker组件(复用 Phase 2a) - 选中后
POST /api/v1/meeting/rooms/:code/invite发送邀请 - 成功后局部 toast,选择器不关闭方便批量邀请
- 打开
- ESC / 点击遮罩: 关闭