TF-3334 Use queue to handle multiple refresh changes mailbox from incoming websocket

This commit is contained in:
dab246
2024-12-23 12:24:50 +07:00
committed by Dat H. Pham
parent 6063f4b832
commit dfd622d7ec
19 changed files with 707 additions and 154 deletions
@@ -5,6 +5,7 @@ import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
import 'package:debounce_throttle/debounce_throttle.dart';
import 'package:fcm/model/type_name.dart';
import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
@@ -18,6 +19,7 @@ import 'package:tmail_ui_user/features/push_notification/presentation/controller
import 'package:tmail_ui_user/features/push_notification/presentation/extensions/state_change_extension.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/listener/email_change_listener.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/listener/mailbox_change_listener.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/utils/fcm_utils.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
@@ -36,6 +38,7 @@ class WebSocketController extends PushBaseController {
Timer? _webSocketPingTimer;
StreamSubscription? _webSocketSubscription;
AppLifecycleListener? _appLifecycleListener;
Debouncer<StateChange?>? _stateChangeDebouncer;
@override
void handleFailureViewState(Failure failure) {
@@ -105,8 +108,9 @@ class WebSocketController extends PushBaseController {
_webSocketSubscription?.cancel();
_webSocketChannel = null;
_webSocketPingTimer?.cancel();
_stateChangeDebouncer?.cancel();
}
void _handleWebSocketConnectionSuccess(WebSocketConnectionSuccess success) {
log('WebSocketController::_handleWebSocketConnectionSuccess(): $success');
_cleanUpWebSocketResources();
@@ -117,6 +121,7 @@ class WebSocketController extends PushBaseController {
_pingWebSocket();
}
_listenToWebSocket();
_initStateChangeDeouncerTimer();
}
void _handleWebSocketConnectionRetry() {
@@ -150,14 +155,7 @@ class WebSocketController extends PushBaseController {
try {
final stateChange = StateChange.fromJson(data);
final mapTypeState = stateChange.getMapTypeState(accountId!);
mappingTypeStateToAction(
mapTypeState,
accountId!,
emailChangeListener: EmailChangeListener.instance,
mailboxChangeListener: MailboxChangeListener.instance,
session!.username,
session: session);
_stateChangeDebouncer?.value = stateChange;
} catch (e) {
logError('WebSocketController::_listenToWebSocket(): Data is not StateChange');
}
@@ -173,4 +171,31 @@ class WebSocketController extends PushBaseController {
},
);
}
void _initStateChangeDeouncerTimer() {
_stateChangeDebouncer = Debouncer<StateChange?>(
const Duration(milliseconds: FcmUtils.durationMessageComing),
initialValue: null,
);
_stateChangeDebouncer?.values.listen(_handleStateChange);
}
void _handleStateChange(StateChange? stateChange) {
try {
if (stateChange == null || accountId == null || session == null) return;
final mapTypeState = stateChange.getMapTypeState(accountId!);
mappingTypeStateToAction(
mapTypeState,
accountId!,
emailChangeListener: EmailChangeListener.instance,
mailboxChangeListener: MailboxChangeListener.instance,
session!.username,
session: session,
);
} catch (e) {
logError('WebSocketController::_handleStateChange:Exception = $e');
}
}
}