From 7fce018eeab7329a7f4f1c900b709ad9f9ee99fa Mon Sep 17 00:00:00 2001 From: csf Date: Fri, 9 Sep 2022 19:29:19 +0800 Subject: [PATCH 1/3] optimize closeConfirmDialog by using async onWindowCloseButton --- .../desktop/pages/file_manager_tab_page.dart | 21 ++++++- .../desktop/pages/port_forward_tab_page.dart | 3 +- .../lib/desktop/pages/remote_tab_page.dart | 21 ++++++- .../lib/desktop/widgets/tabbar_widget.dart | 59 ++++++++----------- 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/flutter/lib/desktop/pages/file_manager_tab_page.dart b/flutter/lib/desktop/pages/file_manager_tab_page.dart index 42c50b927..de874b42d 100644 --- a/flutter/lib/desktop/pages/file_manager_tab_page.dart +++ b/flutter/lib/desktop/pages/file_manager_tab_page.dart @@ -75,9 +75,7 @@ class _FileManagerTabPageState extends State { backgroundColor: MyTheme.color(context).bg, body: DesktopTab( controller: tabController, - onWindowCloseButton: () { - tabController.clear(); - }, + onWindowCloseButton: handleWindowCloseButton, tail: const AddButton().paddingOnly(left: 10), )), ), @@ -103,4 +101,21 @@ class _FileManagerTabPageState extends State { tabController.closeBy(peerId); } } + + Future handleWindowCloseButton() async { + final connLength = tabController.state.value.tabs.length; + if (connLength < 1) { + return true; + } else if (connLength == 1) { + final currentConn = tabController.state.value.tabs[0]; + handleTabCloseButton(currentConn.key); + return false; + } else { + final res = await closeConfirmDialog(); + if (res) { + tabController.clear(); + } + return res; + } + } } diff --git a/flutter/lib/desktop/pages/port_forward_tab_page.dart b/flutter/lib/desktop/pages/port_forward_tab_page.dart index 5dd69e8eb..dffe7856b 100644 --- a/flutter/lib/desktop/pages/port_forward_tab_page.dart +++ b/flutter/lib/desktop/pages/port_forward_tab_page.dart @@ -78,8 +78,9 @@ class _PortForwardTabPageState extends State { backgroundColor: MyTheme.color(context).bg, body: DesktopTab( controller: tabController, - onWindowCloseButton: () { + onWindowCloseButton: () async { tabController.clear(); + return true; }, tail: AddButton().paddingOnly(left: 10), )), diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart index e5caccd71..2f87c51fb 100644 --- a/flutter/lib/desktop/pages/remote_tab_page.dart +++ b/flutter/lib/desktop/pages/remote_tab_page.dart @@ -97,9 +97,7 @@ class _ConnectionTabPageState extends State { body: DesktopTab( controller: tabController, showTabBar: fullscreen.isFalse, - onWindowCloseButton: () { - tabController.clear(); - }, + onWindowCloseButton: handleWindowCloseButton, tail: AddButton().paddingOnly(left: 10), pageViewBuilder: (pageView) { WindowController.fromWindowId(windowId()) @@ -167,4 +165,21 @@ class _ConnectionTabPageState extends State { tabController.closeBy(peerId); } } + + Future handleWindowCloseButton() async { + final connLength = tabController.state.value.tabs.length; + if (connLength < 1) { + return true; + } else if (connLength == 1) { + final currentConn = tabController.state.value.tabs[0]; + handleTabCloseButton(currentConn.key); + return false; + } else { + final res = await closeConfirmDialog(); + if (res) { + tabController.clear(); + } + return res; + } + } } diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index fef5fbf1f..e812b3e7c 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -183,7 +183,7 @@ class DesktopTab extends StatelessWidget { final bool showClose; final Widget Function(Widget pageView)? pageViewBuilder; final Widget? tail; - final VoidCallback? onWindowCloseButton; + final Future Function()? onWindowCloseButton; final TabBuilder? tabBuilder; final LabelGetter? labelGetter; @@ -356,7 +356,7 @@ class WindowActionPanel extends StatelessWidget { final bool showMinimize; final bool showMaximize; final bool showClose; - final VoidCallback? onClose; + final Future Function()? onClose; const WindowActionPanel( {Key? key, @@ -434,7 +434,8 @@ class WindowActionPanel extends StatelessWidget { message: 'Close', icon: IconFont.close, onTap: () async { - action() { + final res = await onClose?.call() ?? true; + if (res) { if (mainTab) { windowManager.close(); } else { @@ -443,14 +444,6 @@ class WindowActionPanel extends StatelessWidget { WindowController.fromWindowId(windowId!).hide(); }); } - onClose?.call(); - } - - if (tabType != DesktopTabType.main && - state.value.tabs.length > 1) { - closeConfirmDialog(action); - } else { - action(); } }, isClose: true, @@ -458,30 +451,28 @@ class WindowActionPanel extends StatelessWidget { ], ); } +} - closeConfirmDialog(Function() callback) async { - final res = await gFFI.dialogManager.show((setState, close) { - submit() => close(true); - return CustomAlertDialog( - title: Row(children: [ - const Icon(Icons.warning_amber_sharp, - color: Colors.redAccent, size: 28), - const SizedBox(width: 10), - Text(translate("Warning")), - ]), - content: Text(translate("Disconnect all devices?")), - actions: [ - TextButton(onPressed: close, child: Text(translate("Cancel"))), - ElevatedButton(onPressed: submit, child: Text(translate("OK"))), - ], - onSubmit: submit, - onCancel: close, - ); - }); - if (res == true) { - callback(); - } - } +Future closeConfirmDialog() async { + final res = await gFFI.dialogManager.show((setState, close) { + submit() => close(true); + return CustomAlertDialog( + title: Row(children: [ + const Icon(Icons.warning_amber_sharp, + color: Colors.redAccent, size: 28), + const SizedBox(width: 10), + Text(translate("Warning")), + ]), + content: Text(translate("Disconnect all devices?")), + actions: [ + TextButton(onPressed: close, child: Text(translate("Cancel"))), + ElevatedButton(onPressed: submit, child: Text(translate("OK"))), + ], + onSubmit: submit, + onCancel: close, + ); + }); + return res == true; } // ignore: must_be_immutable From f6055130e47dd1530dac8ad0282d4d6f7f21b7d3 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 09:03:34 +0800 Subject: [PATCH 2/3] mv overlay.dart --- flutter/lib/common.dart | 2 +- flutter/lib/{mobile => common}/widgets/overlay.dart | 2 +- flutter/lib/models/chat_model.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename flutter/lib/{mobile => common}/widgets/overlay.dart (99%) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 73334baae..711bdadc6 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -14,7 +14,7 @@ import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:window_manager/window_manager.dart'; -import 'mobile/widgets/overlay.dart'; +import 'common/widgets/overlay.dart'; import 'models/model.dart'; import 'models/platform_model.dart'; diff --git a/flutter/lib/mobile/widgets/overlay.dart b/flutter/lib/common/widgets/overlay.dart similarity index 99% rename from flutter/lib/mobile/widgets/overlay.dart rename to flutter/lib/common/widgets/overlay.dart index b8fd8f653..d21bbde96 100644 --- a/flutter/lib/mobile/widgets/overlay.dart +++ b/flutter/lib/common/widgets/overlay.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_hbb/common.dart'; +import '../../mobile/pages/chat_page.dart'; import '../../models/chat_model.dart'; -import '../pages/chat_page.dart'; class DraggableChatWindow extends StatelessWidget { DraggableChatWindow( diff --git a/flutter/lib/models/chat_model.dart b/flutter/lib/models/chat_model.dart index 4bdf5826a..cad9a818f 100644 --- a/flutter/lib/models/chat_model.dart +++ b/flutter/lib/models/chat_model.dart @@ -4,8 +4,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_hbb/models/platform_model.dart'; import 'package:window_manager/window_manager.dart'; -import '../../mobile/widgets/overlay.dart'; import '../common.dart'; +import '../common/widgets/overlay.dart'; import 'model.dart'; class MessageBody { From 062a9d2635b8762ccacb2baf7f3d49586ba6d015 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 13 Sep 2022 09:29:19 +0800 Subject: [PATCH 3/3] update flutter desktop, chat page (in remote page) style --- flutter/lib/common/widgets/overlay.dart | 128 ++++++++++++++++-------- flutter/lib/models/chat_model.dart | 5 +- 2 files changed, 89 insertions(+), 44 deletions(-) diff --git a/flutter/lib/common/widgets/overlay.dart b/flutter/lib/common/widgets/overlay.dart index d21bbde96..0e0a6ce2d 100644 --- a/flutter/lib/common/widgets/overlay.dart +++ b/flutter/lib/common/widgets/overlay.dart @@ -1,15 +1,18 @@ import 'package:flutter/material.dart'; import 'package:flutter_hbb/common.dart'; +import '../../desktop/widgets/tabbar_widget.dart'; import '../../mobile/pages/chat_page.dart'; import '../../models/chat_model.dart'; class DraggableChatWindow extends StatelessWidget { - DraggableChatWindow( - {this.position = Offset.zero, + const DraggableChatWindow( + {Key? key, + this.position = Offset.zero, required this.width, required this.height, - required this.chatModel}); + required this.chatModel}) + : super(key: key); final Offset position; final double width; @@ -30,46 +33,84 @@ class DraggableChatWindow extends StatelessWidget { resizeToAvoidBottomInset: false, appBar: CustomAppBar( onPanUpdate: onPanUpdate, - appBar: Container( - color: MyTheme.accent50, - height: 50, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 15), - child: Text( - translate("Chat"), - style: TextStyle( - color: Colors.white, - fontFamily: 'WorkSans', - fontWeight: FontWeight.bold, - fontSize: 20), - )), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - IconButton( - onPressed: () { - chatModel.hideChatWindowOverlay(); - }, - icon: Icon(Icons.keyboard_arrow_down)), - IconButton( - onPressed: () { - chatModel.hideChatWindowOverlay(); - chatModel.hideChatIconOverlay(); - }, - icon: Icon(Icons.close)) - ], - ) - ], - ), - ), + appBar: isDesktop + ? _buildDesktopAppBar() + : _buildMobileAppBar(), ), body: ChatPage(chatModel: chatModel), ); }); } + + Widget _buildMobileAppBar() { + return Container( + color: MyTheme.accent50, + height: 50, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Text( + translate("Chat"), + style: const TextStyle( + color: Colors.white, + fontFamily: 'WorkSans', + fontWeight: FontWeight.bold, + fontSize: 20), + )), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + IconButton( + onPressed: () { + chatModel.hideChatWindowOverlay(); + }, + icon: const Icon(Icons.keyboard_arrow_down)), + IconButton( + onPressed: () { + chatModel.hideChatWindowOverlay(); + chatModel.hideChatIconOverlay(); + }, + icon: const Icon(Icons.close)) + ], + ) + ], + ), + ); + } + + Widget _buildDesktopAppBar() { + return Container( + color: MyTheme.accent50, + height: 35, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Text( + translate("Chat"), + style: const TextStyle( + color: Colors.white, + fontFamily: 'WorkSans', + fontWeight: FontWeight.bold), + )), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ActionIcon( + message: 'Close', + icon: IconFont.close, + onTap: chatModel.hideChatWindowOverlay, + isClose: true, + ) + ], + ) + ], + ), + ); + } } class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { @@ -86,7 +127,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { } @override - Size get preferredSize => new Size.fromHeight(kToolbarHeight); + Size get preferredSize => const Size.fromHeight(kToolbarHeight); } /// floating buttons of back/home/recent actions for android @@ -161,13 +202,15 @@ class DraggableMobileActions extends StatelessWidget { } class Draggable extends StatefulWidget { - Draggable( - {this.checkKeyboard = false, + const Draggable( + {Key? key, + this.checkKeyboard = false, this.checkScreenSize = false, this.position = Offset.zero, required this.width, required this.height, - required this.builder}); + required this.builder}) + : super(key: key); final bool checkKeyboard; final bool checkScreenSize; @@ -224,7 +267,6 @@ class _DraggableState extends State { final bottomHeight = MediaQuery.of(context).viewInsets.bottom; final currentVisible = bottomHeight != 0; - debugPrint(bottomHeight.toString() + currentVisible.toString()); // save if (!_keyboardVisible && currentVisible) { _saveHeight = _position.dy; diff --git a/flutter/lib/models/chat_model.dart b/flutter/lib/models/chat_model.dart index cad9a818f..e9952db1e 100644 --- a/flutter/lib/models/chat_model.dart +++ b/flutter/lib/models/chat_model.dart @@ -128,7 +128,10 @@ class ChatModel with ChangeNotifier { if (overlayState == null) return; final overlay = OverlayEntry(builder: (context) { return DraggableChatWindow( - position: Offset(20, 80), width: 250, height: 350, chatModel: this); + position: const Offset(20, 80), + width: 250, + height: 350, + chatModel: this); }); overlayState.insert(overlay); chatWindowOverlayEntry = overlay;