fix
This commit is contained in:
parent
671f925232
commit
4d0b21aa73
@ -560,7 +560,6 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
|||||||
///礼物上飘动画
|
///礼物上飘动画
|
||||||
_floatingGiftListener(Msg msg) {
|
_floatingGiftListener(Msg msg) {
|
||||||
final rtcProvider = Provider.of<RtcProvider>(context, listen: false);
|
final rtcProvider = Provider.of<RtcProvider>(context, listen: false);
|
||||||
rtcProvider.scheduleRoomRocketStatusRefreshForGift();
|
|
||||||
if (!rtcProvider.shouldShowRoomVisualEffects) {
|
if (!rtcProvider.shouldShowRoomVisualEffects) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -304,6 +304,12 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
Duration(seconds: 5),
|
Duration(seconds: 5),
|
||||||
Duration(seconds: 10),
|
Duration(seconds: 10),
|
||||||
];
|
];
|
||||||
|
static const List<Duration> _roomRocketEntryReadyFallbackDelays = [
|
||||||
|
Duration(milliseconds: 300),
|
||||||
|
Duration(milliseconds: 900),
|
||||||
|
Duration(milliseconds: 1800),
|
||||||
|
Duration(milliseconds: 3200),
|
||||||
|
];
|
||||||
static const int _roomPasswordNotTrueErrorCode = 9005;
|
static const int _roomPasswordNotTrueErrorCode = 9005;
|
||||||
|
|
||||||
static const Duration _micListPollingInterval = Duration(seconds: 2);
|
static const Duration _micListPollingInterval = Duration(seconds: 2);
|
||||||
@ -345,6 +351,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
Timer? _roomRocketLaunchAnimationTimer;
|
Timer? _roomRocketLaunchAnimationTimer;
|
||||||
Timer? _roomRocketGiftRefreshTimer;
|
Timer? _roomRocketGiftRefreshTimer;
|
||||||
final List<Timer> _roomRocketPostLaunchRefreshTimers = [];
|
final List<Timer> _roomRocketPostLaunchRefreshTimers = [];
|
||||||
|
final List<Timer> _roomRocketEntryReadyFallbackTimers = [];
|
||||||
Timer? _roomRedPacketPresenceTimer;
|
Timer? _roomRedPacketPresenceTimer;
|
||||||
Future<void>? _rtcEnginePrewarmTask;
|
Future<void>? _rtcEnginePrewarmTask;
|
||||||
Future<void>? _pendingRoomSwitchRtcLeaveTask;
|
Future<void>? _pendingRoomSwitchRtcLeaveTask;
|
||||||
@ -492,6 +499,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
_roomRocketLaunchAnimationTimer = null;
|
_roomRocketLaunchAnimationTimer = null;
|
||||||
_roomRocketGiftRefreshTimer?.cancel();
|
_roomRocketGiftRefreshTimer?.cancel();
|
||||||
_roomRocketGiftRefreshTimer = null;
|
_roomRocketGiftRefreshTimer = null;
|
||||||
|
_cancelRoomRocketEntryReadyFallbacks();
|
||||||
_cancelRoomRocketPostLaunchStatusRefresh();
|
_cancelRoomRocketPostLaunchStatusRefresh();
|
||||||
}
|
}
|
||||||
_roomVisualEffectsEnabled = enabled;
|
_roomVisualEffectsEnabled = enabled;
|
||||||
@ -503,7 +511,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
if (visible) {
|
if (visible) {
|
||||||
final roomId = (currenRoom?.roomProfile?.roomProfile?.id ?? "").trim();
|
final roomId = (currenRoom?.roomProfile?.roomProfile?.id ?? "").trim();
|
||||||
if (roomId.isNotEmpty) {
|
if (roomId.isNotEmpty) {
|
||||||
rtmProvider?.handleVoiceRoomReadyForRocketRewards(roomId);
|
_scheduleRoomRocketEntryReadyFallback(roomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2600,6 +2608,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
setRoomVisualEffectsEnabled(true);
|
setRoomVisualEffectsEnabled(true);
|
||||||
if (shouldOpenRoomPage) {
|
if (shouldOpenRoomPage) {
|
||||||
VoiceRoomRoute.openVoiceRoom(context!);
|
VoiceRoomRoute.openVoiceRoom(context!);
|
||||||
|
setVoiceRoomRouteVisible(true);
|
||||||
}
|
}
|
||||||
unawaited(
|
unawaited(
|
||||||
_bootstrapEnteredVoiceRoomSession(
|
_bootstrapEnteredVoiceRoomSession(
|
||||||
@ -2700,7 +2709,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
roomId: roomId,
|
roomId: roomId,
|
||||||
);
|
);
|
||||||
_loadRoomSecondaryData();
|
_loadRoomSecondaryData();
|
||||||
rtmProvider?.handleVoiceRoomReadyForRocketRewards(roomId);
|
_scheduleRoomRocketEntryReadyFallback(roomId);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
||||||
return;
|
return;
|
||||||
@ -2822,6 +2831,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
roomRocketStatus = res;
|
roomRocketStatus = res;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
_scheduleRoomRocketAssetPreload(roomId, res, afterRoomEntry: true);
|
_scheduleRoomRocketAssetPreload(roomId, res, afterRoomEntry: true);
|
||||||
|
_scheduleRoomRocketEntryReadyFallback(roomId);
|
||||||
})
|
})
|
||||||
.catchError((e) {});
|
.catchError((e) {});
|
||||||
_loadRoomRocketRewardPopups(roomId);
|
_loadRoomRocketRewardPopups(roomId);
|
||||||
@ -2944,6 +2954,42 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _scheduleRoomRocketEntryReadyFallback(String roomId) {
|
||||||
|
final normalizedRoomId = roomId.trim();
|
||||||
|
if (normalizedRoomId.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_notifyRoomRocketEntryReadyIfCurrent(normalizedRoomId);
|
||||||
|
for (final delay in _roomRocketEntryReadyFallbackDelays) {
|
||||||
|
final timer = Timer(delay, () {
|
||||||
|
_roomRocketEntryReadyFallbackTimers.removeWhere(
|
||||||
|
(item) => !item.isActive,
|
||||||
|
);
|
||||||
|
_notifyRoomRocketEntryReadyIfCurrent(normalizedRoomId);
|
||||||
|
});
|
||||||
|
_roomRocketEntryReadyFallbackTimers.add(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _notifyRoomRocketEntryReadyIfCurrent(String roomId) {
|
||||||
|
final normalizedRoomId = roomId.trim();
|
||||||
|
final currentRoomId =
|
||||||
|
currenRoom?.roomProfile?.roomProfile?.id?.trim() ?? "";
|
||||||
|
if (normalizedRoomId.isEmpty ||
|
||||||
|
currentRoomId != normalizedRoomId ||
|
||||||
|
!_voiceRoomRouteVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rtmProvider?.handleVoiceRoomReadyForRocketRewards(normalizedRoomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cancelRoomRocketEntryReadyFallbacks() {
|
||||||
|
for (final timer in _roomRocketEntryReadyFallbackTimers) {
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
_roomRocketEntryReadyFallbackTimers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void scheduleRoomRocketPostLaunchStatusRefresh({String? roomId}) {
|
void scheduleRoomRocketPostLaunchStatusRefresh({String? roomId}) {
|
||||||
final resolvedRoomId =
|
final resolvedRoomId =
|
||||||
(roomId ?? currenRoom?.roomProfile?.roomProfile?.id ?? "").trim();
|
(roomId ?? currenRoom?.roomProfile?.roomProfile?.id ?? "").trim();
|
||||||
@ -3033,7 +3079,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
builder:
|
builder:
|
||||||
(_) => RoomRocketPagEffectOverlay(
|
(_) => RoomRocketPagEffectOverlay(
|
||||||
resource: animationUrl,
|
resource: animationUrl,
|
||||||
topAvatarUrl: _roomRocketTop1AvatarUrl(),
|
topAvatarUrl: _roomRocketTop1AvatarUrl(launch.safeLevel),
|
||||||
onCompleted: () {
|
onCompleted: () {
|
||||||
SmartDialog.dismiss(tag: _roomRocketPagLaunchDialogTag);
|
SmartDialog.dismiss(tag: _roomRocketPagLaunchDialogTag);
|
||||||
_roomRocketLaunchAnimationTimer?.cancel();
|
_roomRocketLaunchAnimationTimer?.cancel();
|
||||||
@ -3054,8 +3100,12 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String? _roomRocketTop1AvatarUrl() {
|
String? _roomRocketTop1AvatarUrl(int level) {
|
||||||
final kings = roomRocketStatus?.rocketKings ?? const [];
|
final levelKings = roomRocketStatus?.rocketKingsForLevel(level) ?? const [];
|
||||||
|
final kings =
|
||||||
|
levelKings.isNotEmpty
|
||||||
|
? levelKings
|
||||||
|
: roomRocketStatus?.rocketKings ?? const [];
|
||||||
if (kings.isEmpty) {
|
if (kings.isEmpty) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -3374,9 +3424,6 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
final exitRtmProvider = rtmProvider;
|
final exitRtmProvider = rtmProvider;
|
||||||
final navigationContext = context;
|
final navigationContext = context;
|
||||||
try {
|
try {
|
||||||
exitRtmProvider?.msgAllListener = null;
|
|
||||||
exitRtmProvider?.msgChatListener = null;
|
|
||||||
exitRtmProvider?.msgGiftListener = null;
|
|
||||||
SCGiftVapSvgaManager().stopPlayback();
|
SCGiftVapSvgaManager().stopPlayback();
|
||||||
setRoomVisualEffectsEnabled(false);
|
setRoomVisualEffectsEnabled(false);
|
||||||
SCHeartbeatUtils.cancelTimer();
|
SCHeartbeatUtils.cancelTimer();
|
||||||
@ -3412,9 +3459,6 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
final isPreviewOnlyExit = _currentRoomIsEntryPreview;
|
final isPreviewOnlyExit = _currentRoomIsEntryPreview;
|
||||||
final exitRtmProvider = rtmProvider;
|
final exitRtmProvider = rtmProvider;
|
||||||
try {
|
try {
|
||||||
exitRtmProvider?.msgAllListener = null;
|
|
||||||
exitRtmProvider?.msgChatListener = null;
|
|
||||||
exitRtmProvider?.msgGiftListener = null;
|
|
||||||
SCGiftVapSvgaManager().stopPlayback();
|
SCGiftVapSvgaManager().stopPlayback();
|
||||||
setRoomVisualEffectsEnabled(false);
|
setRoomVisualEffectsEnabled(false);
|
||||||
SCHeartbeatUtils.cancelTimer();
|
SCHeartbeatUtils.cancelTimer();
|
||||||
|
|||||||
@ -135,6 +135,7 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
static const int _roomRocketRegionBroadcastRecentTtlMs = 90000;
|
static const int _roomRocketRegionBroadcastRecentTtlMs = 90000;
|
||||||
static const int _roomRocketRewardPendingTtlMs = 120000;
|
static const int _roomRocketRewardPendingTtlMs = 120000;
|
||||||
static const int _roomRocketRewardProbeTtlMs = 120000;
|
static const int _roomRocketRewardProbeTtlMs = 120000;
|
||||||
|
static const int _roomRocketLaunchCountdownRetainMs = 10000;
|
||||||
static const Duration _createRoomGroupTimeout = Duration(seconds: 12);
|
static const Duration _createRoomGroupTimeout = Duration(seconds: 12);
|
||||||
static const List<Duration> _roomRocketRewardPopupRetryDelays = [
|
static const List<Duration> _roomRocketRewardPopupRetryDelays = [
|
||||||
Duration(milliseconds: 700),
|
Duration(milliseconds: 700),
|
||||||
@ -262,6 +263,12 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
final _pendingRoomRocketRewardPopups =
|
final _pendingRoomRocketRewardPopups =
|
||||||
<String, _PendingRoomRocketRewardPopup>{};
|
<String, _PendingRoomRocketRewardPopup>{};
|
||||||
final Map<String, int> _recentRoomRocketRewardProbeTimes = <String, int>{};
|
final Map<String, int> _recentRoomRocketRewardProbeTimes = <String, int>{};
|
||||||
|
final Map<String, int> _roomRocketLaunchCountdownDueTimes = <String, int>{};
|
||||||
|
final Map<String, String> _roomRocketLaunchCountdownKeysByRoom =
|
||||||
|
<String, String>{};
|
||||||
|
final _pendingRoomRocketCountdownLaunches =
|
||||||
|
<String, RoomRocketLaunchBroadcastMessage>{};
|
||||||
|
final Map<String, Timer> _roomRocketLaunchEffectTimers = <String, Timer>{};
|
||||||
Timer? _roomRocketRewardPopupRetryTimer;
|
Timer? _roomRocketRewardPopupRetryTimer;
|
||||||
Timer? _roomRocketRoomReadyRewardRetryTimer;
|
Timer? _roomRocketRoomReadyRewardRetryTimer;
|
||||||
int get currentLuckGiftBurstPlaybackToken => _luckGiftPushPlaybackToken;
|
int get currentLuckGiftBurstPlaybackToken => _luckGiftPushPlaybackToken;
|
||||||
@ -1163,6 +1170,7 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addMsg(Msg msg) {
|
addMsg(Msg msg) {
|
||||||
|
_scheduleRoomRocketStatusRefreshForGiftMessage(msg);
|
||||||
final mergedGiftMsg = _mergeGiftMessageIfNeeded(msg);
|
final mergedGiftMsg = _mergeGiftMessageIfNeeded(msg);
|
||||||
if (mergedGiftMsg != null) {
|
if (mergedGiftMsg != null) {
|
||||||
msgAllListener?.call(mergedGiftMsg);
|
msgAllListener?.call(mergedGiftMsg);
|
||||||
@ -1249,6 +1257,33 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _scheduleRoomRocketStatusRefreshForGiftMessage(Msg msg) {
|
||||||
|
if (msg.type != SCRoomMsgType.gift &&
|
||||||
|
msg.type != SCRoomMsgType.luckGiftAnimOther) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final currentContext = context;
|
||||||
|
if (currentContext == null || !currentContext.mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final rtcProvider = Provider.of<RealTimeCommunicationManager>(
|
||||||
|
currentContext,
|
||||||
|
listen: false,
|
||||||
|
);
|
||||||
|
final currentRoomId =
|
||||||
|
(rtcProvider.currenRoom?.roomProfile?.roomProfile?.id ?? '').trim();
|
||||||
|
if (currentRoomId.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final messageRoomId = msg.type == SCRoomMsgType.gift ? msg.msg?.trim() : '';
|
||||||
|
if (messageRoomId != null &&
|
||||||
|
messageRoomId.isNotEmpty &&
|
||||||
|
messageRoomId != currentRoomId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rtcProvider.scheduleRoomRocketStatusRefreshForGift(roomId: currentRoomId);
|
||||||
|
}
|
||||||
|
|
||||||
void _cacheRoomRedPacketMessage(Msg msg) {
|
void _cacheRoomRedPacketMessage(Msg msg) {
|
||||||
try {
|
try {
|
||||||
final decoded = jsonDecode(msg.msg ?? '');
|
final decoded = jsonDecode(msg.msg ?? '');
|
||||||
@ -1985,6 +2020,7 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
publishRegionBroadcast: true,
|
publishRegionBroadcast: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
_rememberRoomRocketLaunchCountdown(launch);
|
||||||
_markRoomRocketRewardProbe(launch.roomId);
|
_markRoomRocketRewardProbe(launch.roomId);
|
||||||
_publishRoomRocketRegionBroadcastIfNeeded(launch);
|
_publishRoomRocketRegionBroadcastIfNeeded(launch);
|
||||||
}
|
}
|
||||||
@ -2002,6 +2038,7 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
if (!launch.isValid) {
|
if (!launch.isValid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_rememberRoomRocketLaunchCountdown(launch);
|
||||||
|
|
||||||
var isCurrentRoom = false;
|
var isCurrentRoom = false;
|
||||||
var isCurrentVisibleRoom = false;
|
var isCurrentVisibleRoom = false;
|
||||||
@ -2092,14 +2129,22 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
final pending = _pendingRoomRocketRewardPopups[normalizedRoomId];
|
final pending = _pendingRoomRocketRewardPopups[normalizedRoomId];
|
||||||
final hasProbe =
|
final hasProbe =
|
||||||
_recentRoomRocketRewardProbeTimes[normalizedRoomId] != null;
|
_recentRoomRocketRewardProbeTimes[normalizedRoomId] != null;
|
||||||
if (pending == null && !hasProbe) {
|
final hasLaunch =
|
||||||
|
_pendingRoomRocketCountdownLaunches[normalizedRoomId] != null;
|
||||||
|
if (pending == null && !hasProbe && !hasLaunch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_isCurrentVisibleVoiceRoom(normalizedRoomId)) {
|
if (!_isCurrentVisibleVoiceRoom(normalizedRoomId)) {
|
||||||
_scheduleRoomRocketReadyRewardRetry(normalizedRoomId, attempt);
|
_scheduleRoomRocketReadyRewardRetry(normalizedRoomId, attempt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pending == null && attempt == 0) {
|
final resumedLaunch = _resumeRoomRocketLaunchForCurrentRoom(
|
||||||
|
normalizedRoomId,
|
||||||
|
);
|
||||||
|
if (pending == null && !hasProbe) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!resumedLaunch && pending == null && attempt == 0) {
|
||||||
_scheduleRoomRocketReadyRewardRetry(normalizedRoomId, attempt);
|
_scheduleRoomRocketReadyRewardRetry(normalizedRoomId, attempt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2180,15 +2225,218 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
_recentRoomRocketRewardProbeTimes.clear();
|
_recentRoomRocketRewardProbeTimes.clear();
|
||||||
_roomRocketRoomReadyRewardRetryTimer?.cancel();
|
_roomRocketRoomReadyRewardRetryTimer?.cancel();
|
||||||
_roomRocketRoomReadyRewardRetryTimer = null;
|
_roomRocketRoomReadyRewardRetryTimer = null;
|
||||||
|
_clearRoomRocketLaunchCountdownState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _rememberRoomRocketLaunchCountdown(
|
||||||
|
RoomRocketLaunchBroadcastMessage launch,
|
||||||
|
) {
|
||||||
|
if (!launch.isValid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final now = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
_pruneRoomRocketLaunchCountdowns(now);
|
||||||
|
final key = _roomRocketLaunchCountdownKey(launch);
|
||||||
|
final existingDueAt = _roomRocketLaunchCountdownDueTimes[key];
|
||||||
|
final dueAt =
|
||||||
|
existingDueAt != null && existingDueAt > now
|
||||||
|
? existingDueAt
|
||||||
|
: now + _roomRocketLaunchCountdownDelay(launch).inMilliseconds;
|
||||||
|
_roomRocketLaunchCountdownDueTimes[key] = dueAt;
|
||||||
|
_roomRocketLaunchCountdownKeysByRoom[launch.roomId] = key;
|
||||||
|
_pendingRoomRocketCountdownLaunches[launch.roomId] = launch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _scheduleRoomRocketLaunchEffectsAfterCountdown(
|
||||||
|
RoomRocketLaunchBroadcastMessage launch,
|
||||||
|
) {
|
||||||
|
if (!launch.isValid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_rememberRoomRocketLaunchCountdown(launch);
|
||||||
|
final key = _roomRocketLaunchCountdownKey(launch);
|
||||||
|
final delay = _roomRocketLaunchCountdownRemaining(launch.roomId);
|
||||||
|
final dueAt =
|
||||||
|
_roomRocketLaunchCountdownDueTimes[key] ??
|
||||||
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
|
_roomRocketLaunchEffectTimers[key]?.cancel();
|
||||||
|
_roomRocketLaunchEffectTimers[key] = Timer(delay, () {
|
||||||
|
_roomRocketLaunchEffectTimers.remove(key);
|
||||||
|
if (_roomRocketLaunchCountdownDueTimes[key] != dueAt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_roomRocketLaunchCountdownDueTimes.remove(key);
|
||||||
|
if (_roomRocketLaunchCountdownKeysByRoom[launch.roomId] == key) {
|
||||||
|
_roomRocketLaunchCountdownKeysByRoom.remove(launch.roomId);
|
||||||
|
}
|
||||||
|
final pendingLaunch =
|
||||||
|
_pendingRoomRocketCountdownLaunches.remove(launch.roomId) ?? launch;
|
||||||
|
_playRoomRocketLaunchEffectsAndReward(pendingLaunch);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _playRoomRocketLaunchEffectsAndReward(
|
||||||
|
RoomRocketLaunchBroadcastMessage launch,
|
||||||
|
) {
|
||||||
|
_clearRoomRocketLaunchCountdownForRoom(launch.roomId);
|
||||||
|
if (!_isCurrentVisibleVoiceRoom(launch.roomId)) {
|
||||||
|
_markRoomRocketRewardProbe(launch.roomId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final currentContext = context;
|
||||||
|
if (currentContext == null || !currentContext.mounted) {
|
||||||
|
_markRoomRocketRewardProbe(launch.roomId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final rtcProvider = Provider.of<RealTimeCommunicationManager>(
|
||||||
|
currentContext,
|
||||||
|
listen: false,
|
||||||
|
);
|
||||||
|
final shouldFetchReward =
|
||||||
|
_pendingRoomRocketRewardPopups.containsKey(launch.roomId) ||
|
||||||
|
_recentRoomRocketRewardProbeTimes.containsKey(launch.roomId);
|
||||||
|
final pending = _pendingRoomRocketRewardPopups.remove(launch.roomId);
|
||||||
|
_recentRoomRocketRewardProbeTimes.remove(launch.roomId);
|
||||||
|
rtcProvider.handleRoomRocketLaunchBroadcast(launch);
|
||||||
|
if (shouldFetchReward) {
|
||||||
|
unawaited(
|
||||||
|
_showRoomRocketRewardPopupDialog(
|
||||||
|
launch.roomId,
|
||||||
|
initialRoomRecords:
|
||||||
|
pending?.initialRoomRecords ??
|
||||||
|
const <SCRoomRocketRewardRecordRes>[],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _resumeRoomRocketLaunchForCurrentRoom(String roomId) {
|
||||||
|
final normalizedRoomId = roomId.trim();
|
||||||
|
final launch = _pendingRoomRocketCountdownLaunches[normalizedRoomId];
|
||||||
|
if (launch == null || !_isCurrentVisibleVoiceRoom(normalizedRoomId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final currentContext = context;
|
||||||
|
if (currentContext == null || !currentContext.mounted) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final rtcProvider = Provider.of<RealTimeCommunicationManager>(
|
||||||
|
currentContext,
|
||||||
|
listen: false,
|
||||||
|
);
|
||||||
|
final remaining = _roomRocketLaunchCountdownRemaining(normalizedRoomId);
|
||||||
|
if (remaining > Duration.zero) {
|
||||||
|
_addRoomRocketLaunchNoticeIfNeeded(
|
||||||
|
rtcProvider: rtcProvider,
|
||||||
|
launch: launch,
|
||||||
|
secondsOverride: _roomRocketRemainingSeconds(remaining),
|
||||||
|
);
|
||||||
|
_scheduleRoomRocketLaunchEffectsAfterCountdown(launch);
|
||||||
|
} else {
|
||||||
|
_playRoomRocketLaunchEffectsAndReward(launch);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _roomRocketRemainingSeconds(Duration duration) {
|
||||||
|
final seconds = (duration.inMilliseconds / 1000).ceil();
|
||||||
|
return seconds.clamp(1, 60).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
Duration _roomRocketLaunchCountdownRemaining(String roomId) {
|
||||||
|
final normalizedRoomId = roomId.trim();
|
||||||
|
if (normalizedRoomId.isEmpty) {
|
||||||
|
return Duration.zero;
|
||||||
|
}
|
||||||
|
final now = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
_pruneRoomRocketLaunchCountdowns(now);
|
||||||
|
final key = _roomRocketLaunchCountdownKeysByRoom[normalizedRoomId];
|
||||||
|
final dueAt = key == null ? null : _roomRocketLaunchCountdownDueTimes[key];
|
||||||
|
if (dueAt == null || dueAt <= now) {
|
||||||
|
return Duration.zero;
|
||||||
|
}
|
||||||
|
return Duration(milliseconds: dueAt - now);
|
||||||
|
}
|
||||||
|
|
||||||
|
Duration _roomRocketLaunchCountdownDelay(
|
||||||
|
RoomRocketLaunchBroadcastMessage launch,
|
||||||
|
) {
|
||||||
|
final seconds = launch.durationSeconds <= 0 ? 10 : launch.durationSeconds;
|
||||||
|
return Duration(seconds: seconds.clamp(0, 60).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
String _roomRocketLaunchCountdownKey(
|
||||||
|
RoomRocketLaunchBroadcastMessage launch,
|
||||||
|
) {
|
||||||
|
final launchKey = _roomRocketLaunchNoticeKey(launch);
|
||||||
|
if (launchKey.isNotEmpty) {
|
||||||
|
return launchKey;
|
||||||
|
}
|
||||||
|
return 'rocket_launch_countdown|${launch.roomId}';
|
||||||
|
}
|
||||||
|
|
||||||
|
void _pruneRoomRocketLaunchCountdowns(int now) {
|
||||||
|
final expiredKeys = <String>{};
|
||||||
|
_roomRocketLaunchCountdownDueTimes.removeWhere((key, dueAt) {
|
||||||
|
final expired = now - dueAt > _roomRocketLaunchCountdownRetainMs;
|
||||||
|
if (expired) {
|
||||||
|
expiredKeys.add(key);
|
||||||
|
}
|
||||||
|
return expired;
|
||||||
|
});
|
||||||
|
if (expiredKeys.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_roomRocketLaunchCountdownKeysByRoom.removeWhere(
|
||||||
|
(_, key) => expiredKeys.contains(key),
|
||||||
|
);
|
||||||
|
_pendingRoomRocketCountdownLaunches.removeWhere(
|
||||||
|
(roomId, _) => !_roomRocketLaunchCountdownKeysByRoom.containsKey(roomId),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _clearRoomRocketLaunchCountdownState() {
|
||||||
|
_roomRocketLaunchCountdownDueTimes.clear();
|
||||||
|
_roomRocketLaunchCountdownKeysByRoom.clear();
|
||||||
|
_pendingRoomRocketCountdownLaunches.clear();
|
||||||
|
for (final timer in _roomRocketLaunchEffectTimers.values) {
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
_roomRocketLaunchEffectTimers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _clearRoomRocketLaunchCountdownForRoom(String roomId) {
|
||||||
|
final normalizedRoomId = roomId.trim();
|
||||||
|
final key = _roomRocketLaunchCountdownKeysByRoom.remove(normalizedRoomId);
|
||||||
|
if (key != null) {
|
||||||
|
_roomRocketLaunchCountdownDueTimes.remove(key);
|
||||||
|
_roomRocketLaunchEffectTimers.remove(key)?.cancel();
|
||||||
|
}
|
||||||
|
_pendingRoomRocketCountdownLaunches.remove(normalizedRoomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleCurrentVisibleRoomRocketLaunch({
|
void _handleCurrentVisibleRoomRocketLaunch({
|
||||||
required RealTimeCommunicationManager rtcProvider,
|
required RealTimeCommunicationManager rtcProvider,
|
||||||
required RoomRocketLaunchBroadcastMessage launch,
|
required RoomRocketLaunchBroadcastMessage launch,
|
||||||
bool publishRegionBroadcast = false,
|
bool publishRegionBroadcast = false,
|
||||||
|
}) {
|
||||||
|
if (_addRoomRocketLaunchNoticeIfNeeded(
|
||||||
|
rtcProvider: rtcProvider,
|
||||||
|
launch: launch,
|
||||||
|
publishRegionBroadcast: publishRegionBroadcast,
|
||||||
|
)) {
|
||||||
|
_scheduleRoomRocketLaunchEffectsAfterCountdown(launch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _addRoomRocketLaunchNoticeIfNeeded({
|
||||||
|
required RealTimeCommunicationManager rtcProvider,
|
||||||
|
required RoomRocketLaunchBroadcastMessage launch,
|
||||||
|
bool publishRegionBroadcast = false,
|
||||||
|
int? secondsOverride,
|
||||||
}) {
|
}) {
|
||||||
if (!_isCurrentVisibleVoiceRoom(launch.roomId)) {
|
if (!_isCurrentVisibleVoiceRoom(launch.roomId)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
final launchKey = _roomRocketLaunchNoticeKey(launch);
|
final launchKey = _roomRocketLaunchNoticeKey(launch);
|
||||||
final looseLaunchKey = _roomRocketLaunchLooseKey(launch);
|
final looseLaunchKey = _roomRocketLaunchLooseKey(launch);
|
||||||
@ -2199,26 +2447,27 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
_recentRoomRocketLaunchTimes.containsKey(launchKey)) ||
|
_recentRoomRocketLaunchTimes.containsKey(launchKey)) ||
|
||||||
(looseLaunchKey.isNotEmpty &&
|
(looseLaunchKey.isNotEmpty &&
|
||||||
_recentRoomRocketLaunchLooseTimes.containsKey(looseLaunchKey));
|
_recentRoomRocketLaunchLooseTimes.containsKey(looseLaunchKey));
|
||||||
if (!alreadyHandled && launchKey.isNotEmpty) {
|
if (alreadyHandled || launchKey.isEmpty) {
|
||||||
_recentRoomRocketLaunchTimes[launchKey] = now;
|
return false;
|
||||||
if (looseLaunchKey.isNotEmpty) {
|
|
||||||
_recentRoomRocketLaunchLooseTimes[looseLaunchKey] = now;
|
|
||||||
}
|
|
||||||
addMsg(
|
|
||||||
_buildRoomRocketLaunchNoticeMsg(
|
|
||||||
_firstNonBlank([
|
|
||||||
rtcProvider.currenRoom?.roomProfile?.roomProfile?.roomAccount,
|
|
||||||
launch.roomAccount,
|
|
||||||
]),
|
|
||||||
launch,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (publishRegionBroadcast) {
|
|
||||||
_publishRoomRocketRegionBroadcastIfNeeded(launch);
|
|
||||||
}
|
|
||||||
rtcProvider.handleRoomRocketLaunchBroadcast(launch);
|
|
||||||
}
|
}
|
||||||
unawaited(_showRoomRocketRewardPopupDialog(launch.roomId));
|
_recentRoomRocketLaunchTimes[launchKey] = now;
|
||||||
|
if (looseLaunchKey.isNotEmpty) {
|
||||||
|
_recentRoomRocketLaunchLooseTimes[looseLaunchKey] = now;
|
||||||
|
}
|
||||||
|
addMsg(
|
||||||
|
_buildRoomRocketLaunchNoticeMsg(
|
||||||
|
_firstNonBlank([
|
||||||
|
rtcProvider.currenRoom?.roomProfile?.roomProfile?.roomAccount,
|
||||||
|
launch.roomAccount,
|
||||||
|
]),
|
||||||
|
launch,
|
||||||
|
secondsOverride: secondsOverride,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (publishRegionBroadcast) {
|
||||||
|
_publishRoomRocketRegionBroadcastIfNeeded(launch);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _publishRoomRocketRegionBroadcastIfNeeded(
|
void _publishRoomRocketRegionBroadcastIfNeeded(
|
||||||
@ -2453,9 +2702,12 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
|
|
||||||
Msg _buildRoomRocketLaunchNoticeMsg(
|
Msg _buildRoomRocketLaunchNoticeMsg(
|
||||||
String groupId,
|
String groupId,
|
||||||
RoomRocketLaunchBroadcastMessage launch,
|
RoomRocketLaunchBroadcastMessage launch, {
|
||||||
) {
|
int? secondsOverride,
|
||||||
final seconds = launch.durationSeconds <= 0 ? 10 : launch.durationSeconds;
|
}) {
|
||||||
|
final seconds =
|
||||||
|
secondsOverride ??
|
||||||
|
(launch.durationSeconds <= 0 ? 10 : launch.durationSeconds);
|
||||||
return Msg(
|
return Msg(
|
||||||
groupId: groupId,
|
groupId: groupId,
|
||||||
msg: seconds.toString(),
|
msg: seconds.toString(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user