diff --git a/lib/services/audio/rtm_manager.dart b/lib/services/audio/rtm_manager.dart index 046faf7..f77ead7 100644 --- a/lib/services/audio/rtm_manager.dart +++ b/lib/services/audio/rtm_manager.dart @@ -1152,6 +1152,9 @@ class RealTimeMessagingManager extends ChangeNotifier { notifyListeners(); return; } + if (msg.type == SCRoomMsgType.roomRedPacket) { + _cacheRoomRedPacketMessage(msg); + } if (msg.type == SCRoomMsgType.roomRedPacket && _hasRoomRedPacketMessage(msg)) { debugPrint( @@ -1203,6 +1206,19 @@ class RealTimeMessagingManager extends ChangeNotifier { } } + void _cacheRoomRedPacketMessage(Msg msg) { + try { + final decoded = jsonDecode(msg.msg ?? ''); + if (decoded is Map) { + RoomRedPacketPendingCache.instance.upsertPayload(decoded); + } else if (decoded is Map) { + RoomRedPacketPendingCache.instance.upsertPayload( + decoded.map((key, value) => MapEntry(key.toString(), value)), + ); + } + } catch (_) {} + } + Msg _buildRoomRedPacketMsg(String groupId, dynamic data) { final payload = data is Map diff --git a/lib/ui_kit/widgets/room/red_packet/room_red_packet_open_dialog.dart b/lib/ui_kit/widgets/room/red_packet/room_red_packet_open_dialog.dart index 942a5dc..cf428dd 100644 --- a/lib/ui_kit/widgets/room/red_packet/room_red_packet_open_dialog.dart +++ b/lib/ui_kit/widgets/room/red_packet/room_red_packet_open_dialog.dart @@ -188,10 +188,16 @@ class RoomRedPacketOpenDialog extends StatefulWidget { ? data.withFallbackProfile(packets[existingIndex]) : data; if (existingIndex >= 0) { + final nextData = + insertAtStart + ? mergedData + : packets[existingIndex].withFallbackProfile(data); if (insertAtStart) { packets ..removeAt(existingIndex) - ..insert(0, mergedData); + ..insert(0, nextData); + } else { + packets[existingIndex] = nextData; } return; } diff --git a/lib/ui_kit/widgets/room/room_play_widget.dart b/lib/ui_kit/widgets/room/room_play_widget.dart index fabb902..32667c0 100644 --- a/lib/ui_kit/widgets/room/room_play_widget.dart +++ b/lib/ui_kit/widgets/room/room_play_widget.dart @@ -345,6 +345,13 @@ void _addVisiblePacket( }) { final normalizedPacket = RoomRedPacketOpenDialog.withLocalClaimState(packet); final packetId = normalizedPacket.packetId.trim(); + if (packetId.isNotEmpty && + RoomRedPacketOpenDialog.isClaimedLocally(packetId)) { + if (authoritative) { + hiddenPacketIds?.add(packetId); + } + return; + } if (packetId.isNotEmpty && RoomRedPacketOpenDialog.isUnavailableLocally(packetId)) { if (authoritative) { @@ -373,6 +380,12 @@ void _addVisiblePacket( } if (packetId.isNotEmpty && packets.any((item) => item.packetId.trim() == packetId)) { + final existingIndex = packets.indexWhere( + (item) => item.packetId.trim() == packetId, + ); + packets[existingIndex] = packets[existingIndex].withFallbackProfile( + normalizedPacket, + ); return; } packets.add(normalizedPacket); diff --git a/需求进度.md b/需求进度.md index f230123..9e34ea4 100644 --- a/需求进度.md +++ b/需求进度.md @@ -557,6 +557,7 @@ - 已收口红包发送记录页状态展示:不再显示 `Pending/等待中`,后端 `ACTIVE/PENDING` 等中间态统一展示为已发出;只保留已退回、已领完、已发出三类状态,并补齐多语言的“已领完”文案。 - 已收口房间外红包领取层触发:红包飘屏 `GO` 只有在目标房间页面当前可见时才直接打开领取层,否则先进房;同语区或房间 IM 收到即时红包时,也只有当前可见房间匹配目标 `roomId` 才自动弹领取层,避免首页、房间列表、我的页直接弹抢红包。 - 已按最新反馈修正领取记录头像和跨房进房:领取记录空头像不再回退成红包图标,统一走项目默认头像;红包飘窗 `GO` 跨房点击直接进目标房间,不再弹进入房间二次确认。 +- 已修正延时红包多入口数据不一致:公屏红包消息会同步写入待领缓存,右侧入口和领取弹层遇到同一 `packetId` 会合并接口列表、缓存和聊天 payload 的倒计时字段,避免飘屏 `GO`/右侧入口丢失倒计时;领取成功后右侧入口会优先按本地已领状态隐藏,避免接口刷新滞后导致残留。 ## 已知问题 - 已接入语音房表情包素材第一版:桌面 `表情素材` 中的 `fluent_emoji` 与 `monkey` gif 已纳入项目资源,底部聊天入口改为图稿里的短白色胶囊并移除内部输入图标,右侧新增独立表情按钮;同一个房间输入弹层现在可从表情按钮直接打开表情包面板,原 unicode emoji 面板已替换为本地 gif 表情。发送逻辑同步按最新规则分流:用户在麦上发表情时只在自己麦位播放,不进入聊天列表;用户未上麦发表情时进入房间聊天框展示,不触发麦位动画。