From c268a0ab145fabff8c08ab3a2736b54cfd730a7d Mon Sep 17 00:00:00 2001 From: 21pages Date: Sat, 21 Oct 2023 15:25:01 +0800 Subject: [PATCH] show reconnect timeout and dismiss all dialog when show reconnecting Signed-off-by: 21pages --- flutter/lib/common.dart | 82 ++++++++++++++++++++++++++++------- flutter/lib/models/model.dart | 5 ++- 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 834b3bec3..0ab790720 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -958,7 +958,7 @@ class CustomAlertDialog extends StatelessWidget { void msgBox(SessionID sessionId, String type, String title, String text, String link, OverlayDialogManager dialogManager, - {bool? hasCancel, ReconnectHandle? reconnect}) { + {bool? hasCancel, ReconnectHandle? reconnect, int? reconnectTimeout}) { dialogManager.dismissAll(); List buttons = []; bool hasOk = false; @@ -998,22 +998,21 @@ void msgBox(SessionID sessionId, String type, String title, String text, dialogManager.dismissAll(); })); } - if (reconnect != null && title == "Connection Error") { + if (reconnect != null && + title == "Connection Error" && + reconnectTimeout != null) { // `enabled` is used to disable the dialog button once the button is clicked. final enabled = true.obs; - final button = Obx( - () => dialogButton( - 'Reconnect', - isOutline: true, - onPressed: enabled.isTrue - ? () { - // Disable the button - enabled.value = false; - reconnect(dialogManager, sessionId, false); - } - : null, - ), - ); + final button = Obx(() => _ReconnectCountDownButton( + second: reconnectTimeout, + onPressed: enabled.isTrue + ? () { + // Disable the button + enabled.value = false; + reconnect(dialogManager, sessionId, false); + } + : null, + )); buttons.insert(0, button); } if (link.isNotEmpty) { @@ -2745,3 +2744,56 @@ parseParamScreenRect(Map params) { } return screenRect; } + +class _ReconnectCountDownButton extends StatefulWidget { + _ReconnectCountDownButton({ + Key? key, + required this.second, + required this.onPressed, + }) : super(key: key); + final VoidCallback? onPressed; + final int second; + + @override + State<_ReconnectCountDownButton> createState() => + _ReconnectCountDownButtonState(); +} + +class _ReconnectCountDownButtonState extends State<_ReconnectCountDownButton> { + late int _countdownSeconds = widget.second; + + Timer? _timer; + + @override + void initState() { + super.initState(); + _startCountdownTimer(); + } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); + } + + void _startCountdownTimer() { + _timer = Timer.periodic(Duration(seconds: 1), (timer) { + if (_countdownSeconds <= 0) { + timer.cancel(); + } else { + setState(() { + _countdownSeconds--; + }); + } + }); + } + + @override + Widget build(BuildContext context) { + return dialogButton( + '${translate('Reconnect')} (${_countdownSeconds}s)', + onPressed: widget.onPressed, + isOutline: true, + ); + } +} diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 433d3c2d4..0d257eaf0 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -512,7 +512,9 @@ class FfiModel with ChangeNotifier { String link, bool hasRetry, OverlayDialogManager dialogManager, {bool? hasCancel}) { msgBox(sessionId, type, title, text, link, dialogManager, - hasCancel: hasCancel, reconnect: reconnect); + hasCancel: hasCancel, + reconnect: reconnect, + reconnectTimeout: hasRetry ? _reconnects : null); _timer?.cancel(); if (hasRetry) { _timer = Timer(Duration(seconds: _reconnects), () { @@ -528,6 +530,7 @@ class FfiModel with ChangeNotifier { bool forceRelay) { bind.sessionReconnect(sessionId: sessionId, forceRelay: forceRelay); clearPermissions(); + dialogManager.dismissAll(); dialogManager.showLoading(translate('Connecting...'), onCancel: closeConnection); }