diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index fcd3e81..bf3a54a 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -502,7 +502,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 11; + CURRENT_PROJECT_VERSION = 12; DEVELOPMENT_TEAM = S9X2AJ2US9; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -511,7 +511,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.3.0; + MARKETING_VERSION = 1.3.1; PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -693,7 +693,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 11; + CURRENT_PROJECT_VERSION = 12; DEVELOPMENT_TEAM = F33K8VUZ62; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -702,7 +702,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.3.0; + MARKETING_VERSION = 1.3.1; PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -722,7 +722,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 11; + CURRENT_PROJECT_VERSION = 12; DEVELOPMENT_TEAM = F33K8VUZ62; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -731,7 +731,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.3.0; + MARKETING_VERSION = 1.3.1; PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/lib/modules/room/voice_room_page.dart b/lib/modules/room/voice_room_page.dart index 4293b05..3251041 100644 --- a/lib/modules/room/voice_room_page.dart +++ b/lib/modules/room/voice_room_page.dart @@ -52,6 +52,7 @@ class VoiceRoomPage extends StatefulWidget { class _VoiceRoomPageState extends State with SingleTickerProviderStateMixin { + static const int _chatTabCount = 3; static const Duration _luckyGiftComboWindow = Duration(seconds: 3); static const Duration _luckyGiftQueueDrainWindow = Duration(seconds: 3); static const int _maxLuckyGiftTrackedAnimations = 5; @@ -65,7 +66,6 @@ class _VoiceRoomPageState extends State static const Duration _giftVisualBatchDedupeWindow = Duration(seconds: 4); late TabController _tabController; - final List _pages = [AllChatPage(), ChatPage(), GiftChatPage()]; late StreamSubscription _subscription; final RoomGiftSeatFlightController _giftSeatFlightController = RoomGiftSeatFlightController(); @@ -80,7 +80,7 @@ class _VoiceRoomPageState extends State @override void initState() { super.initState(); - _tabController = TabController(length: _pages.length, vsync: this); + _tabController = TabController(length: _chatTabCount, vsync: this); _enableRoomVisualEffects(); _tabController.addListener(_handleTabChange); _subscription = eventBus.on().listen(( @@ -277,6 +277,7 @@ class _VoiceRoomPageState extends State @override Widget build(BuildContext context) { + final chatRoomKey = _chatRoomKey(context); return PopScope( canPop: false, onPopInvokedWithResult: (bool didPop, Object? result) { @@ -334,7 +335,7 @@ class _VoiceRoomPageState extends State children: [ Column( children: [ - _buildChatView(), + _buildChatView(chatRoomKey), const RoomBottomWidget(showGiftComboButton: false), ], ), @@ -373,7 +374,7 @@ class _VoiceRoomPageState extends State } ///消息 - Widget _buildChatView() { + Widget _buildChatView(String chatRoomKey) { return Expanded( child: Stack( alignment: AlignmentDirectional.bottomEnd, @@ -418,7 +419,7 @@ class _VoiceRoomPageState extends State SCGlobalConfig.businessLogicStrategy .getVoiceRoomTabDividerColor(), controller: _tabController, - tabs: List.generate(_pages.length, _buildImageTab), + tabs: List.generate(_chatTabCount, _buildImageTab), ), Expanded( child: Container( @@ -436,7 +437,7 @@ class _VoiceRoomPageState extends State removeTop: true, child: TabBarView( controller: _tabController, - children: _pages, + children: _buildChatPages(chatRoomKey), ), ), ), @@ -449,6 +450,28 @@ class _VoiceRoomPageState extends State ); } + String _chatRoomKey(BuildContext context) { + final roomProfile = + context.read().currenRoom?.roomProfile?.roomProfile; + final roomId = roomProfile?.id?.trim() ?? ""; + final groupId = roomProfile?.roomAccount?.trim() ?? ""; + return "$roomId|$groupId"; + } + + List _buildChatPages(String chatRoomKey) { + return [ + KeyedSubtree( + key: ValueKey("all_chat_$chatRoomKey"), + child: const AllChatPage(), + ), + KeyedSubtree(key: ValueKey("chat_$chatRoomKey"), child: ChatPage()), + KeyedSubtree( + key: ValueKey("gift_chat_$chatRoomKey"), + child: const GiftChatPage(), + ), + ]; + } + Widget _buildImageTab(int index) { return Tab( height: 32.w, diff --git a/lib/services/audio/rtm_manager.dart b/lib/services/audio/rtm_manager.dart index e2a9334..3c434b7 100644 --- a/lib/services/audio/rtm_manager.dart +++ b/lib/services/audio/rtm_manager.dart @@ -1048,6 +1048,9 @@ class RealTimeMessagingManager extends ChangeNotifier { lastMsgID: null, ); final messages = result.data ?? const []; + if (!_isCurrentVoiceRoomGroup(normalizedGroupId)) { + return; + } for (final message in messages.reversed) { _addRoomHistoryMessage(normalizedGroupId, message); } @@ -1722,6 +1725,11 @@ class RealTimeMessagingManager extends ChangeNotifier { ''; } + bool _isCurrentVoiceRoomGroup(String groupId) { + final currentGroupId = _currentVoiceRoomGroupId(); + return currentGroupId.isNotEmpty && currentGroupId == groupId.trim(); + } + bool _shouldRouteUntrackedRoomRedPacketBroadcast( String groupId, V2TimMessage message, @@ -1956,8 +1964,11 @@ class RealTimeMessagingManager extends ChangeNotifier { ///红包触发飘屏 var fData = data["data"]; final payload = _broadcastPayloadMap(fData); - final packetId = _payloadText(payload['packetId']); final packetRoomId = _payloadText(payload["roomId"]); + if (isRegionBroadcastGroup && + !_isDelayedRoomRedPacketPayload(fData)) { + return; + } if (!_isSameRoomRedPacketRegion(fData)) { return; } @@ -2554,6 +2565,7 @@ class RealTimeMessagingManager extends ChangeNotifier { Future sendRoomRedPacketBroadcast( Map payload, { String roomGroupId = '', + bool includeRegionBroadcast = false, }) async { if (payload.isEmpty) { return; @@ -2564,13 +2576,15 @@ class RealTimeMessagingManager extends ChangeNotifier { targetGroupIds.add(normalizedRoomGroupId); } - var regionGroupId = roomRedPacketBroadcastGroupId?.trim() ?? ''; - if (regionGroupId.isEmpty) { - await syncRoomRedPacketBroadcastGroup(); - regionGroupId = roomRedPacketBroadcastGroupId?.trim() ?? ''; - } - if (regionGroupId.isNotEmpty) { - targetGroupIds.add(regionGroupId); + if (includeRegionBroadcast) { + var regionGroupId = roomRedPacketBroadcastGroupId?.trim() ?? ''; + if (regionGroupId.isEmpty) { + await syncRoomRedPacketBroadcastGroup(); + regionGroupId = roomRedPacketBroadcastGroupId?.trim() ?? ''; + } + if (regionGroupId.isNotEmpty) { + targetGroupIds.add(regionGroupId); + } } if (targetGroupIds.isEmpty) { @@ -2620,6 +2634,18 @@ class RealTimeMessagingManager extends ChangeNotifier { return _isSameRegionBroadcastPayload(payload); } + bool _isDelayedRoomRedPacketPayload(dynamic payload) { + final map = _broadcastPayloadMap(payload); + final packetMode = _payloadText(map['packetMode']).toUpperCase(); + if (packetMode == 'DELAYED') { + return true; + } + if (packetMode == 'IMMEDIATE') { + return false; + } + return _payloadText(map['claimStartTime']).isNotEmpty; + } + bool _isSameRegionBroadcastPayload(dynamic payload) { final map = _broadcastPayloadMap(payload); final packetRegion = map['regionCode']?.toString().trim(); diff --git a/lib/shared/data_sources/sources/local/floating_screen_manager.dart b/lib/shared/data_sources/sources/local/floating_screen_manager.dart index 187054d..f897aad 100644 --- a/lib/shared/data_sources/sources/local/floating_screen_manager.dart +++ b/lib/shared/data_sources/sources/local/floating_screen_manager.dart @@ -584,6 +584,9 @@ class OverlayManager { if (message.isRegionBroadcast) { return _shouldDisplayRegionBroadcastMessage(context, message); } + if (message.type == 4) { + return _isCurrentRoomFloatingMessage(context, message); + } if (SCGlobalConfig.isFloatingBroadcastRoomOnly) { return _isCurrentRoomFloatingMessage(context, message); } diff --git a/lib/ui_kit/widgets/room/red_packet/room_red_packet_send_panel.dart b/lib/ui_kit/widgets/room/red_packet/room_red_packet_send_panel.dart index cb3f8b4..5a27833 100644 --- a/lib/ui_kit/widgets/room/red_packet/room_red_packet_send_panel.dart +++ b/lib/ui_kit/widgets/room/red_packet/room_red_packet_send_panel.dart @@ -664,7 +664,8 @@ class _RoomRedPacketSendPanelState extends State { currentUser?.userNickname ?? result.userName ?? 'Lucky Pack'; final senderAvatar = currentUser?.userAvatar ?? result.userAvatar ?? ''; final claimStartTime = (result.claimStartTime ?? '').trim(); - if (_isDelayedRedPacketResult(result) && claimStartTime.isEmpty) { + final isDelayedPacket = _isDelayedRedPacketResult(result); + if (isDelayedPacket && claimStartTime.isEmpty) { debugPrint( '[RoomRedPacket][SendFallback] skip delayed local UI because server ' 'claimStartTime is empty packetId=$packetId', @@ -718,6 +719,7 @@ class _RoomRedPacketSendPanelState extends State { rtmProvider.sendRoomRedPacketBroadcast( payload, roomGroupId: roomProfile?.roomAccount ?? '', + includeRegionBroadcast: isDelayedPacket, ), ); OverlayManager().addMessage( @@ -730,7 +732,8 @@ class _RoomRedPacketSendPanelState extends State { toUserId: packetId, coins: result.totalAmount ?? _selectedAmount, number: result.totalCount ?? _selectedCount, - broadcastScope: SCFloatingMessage.broadcastScopeRegion, + broadcastScope: + isDelayedPacket ? SCFloatingMessage.broadcastScopeRegion : '', priority: 1000, ), ); diff --git a/pubspec.yaml b/pubspec.yaml index a60a2f8..37c5e1f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.3.0+11 +version: 1.3.1+12 environment: