From 91829c73f384251c104d8911d24061d72c1ae22d Mon Sep 17 00:00:00 2001 From: xxrl <837951112@qq.com> Date: Sun, 18 Sep 2022 17:38:16 +0800 Subject: [PATCH 01/16] fix chinese version of doc_mac_permission url --- src/lang/cn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 738595aa9..920013be3 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -272,7 +272,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Overwrite", "覆盖"), ("This file exists, skip or overwrite this file?", "这个文件/文件夹已存在,跳过/覆盖?"), ("Quit", "退出"), - ("doc_mac_permission", "https://rustdesk.com/docs/zh-cn/manual/mac/#启用权限"), + ("doc_mac_permission", "https://rustdesk.com/docs/zh-cn/manual/mac#%E5%90%AF%E7%94%A8%E6%9D%83%E9%99%90"), ("Help", "帮助"), ("Failed", "失败"), ("Succeeded", "成功"), From 429d72c9c343539ea7d02babae4b00942fc00dca Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 10:05:53 +0800 Subject: [PATCH 02/16] refactor: change binary name to rustdesk --- flutter/linux/CMakeLists.txt | 2 +- flutter/macos/Runner/Configs/AppInfo.xcconfig | 2 +- flutter/windows/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flutter/linux/CMakeLists.txt b/flutter/linux/CMakeLists.txt index 9a4e0527b..9391ed97e 100644 --- a/flutter/linux/CMakeLists.txt +++ b/flutter/linux/CMakeLists.txt @@ -4,7 +4,7 @@ project(runner LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. -set(BINARY_NAME "flutter_hbb") +set(BINARY_NAME "rustdesk") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID set(APPLICATION_ID "com.carriez.flutter_hbb") diff --git a/flutter/macos/Runner/Configs/AppInfo.xcconfig b/flutter/macos/Runner/Configs/AppInfo.xcconfig index 3c862dee9..bf05a4caa 100644 --- a/flutter/macos/Runner/Configs/AppInfo.xcconfig +++ b/flutter/macos/Runner/Configs/AppInfo.xcconfig @@ -5,7 +5,7 @@ // 'flutter create' template. // The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = flutter_hbb +PRODUCT_NAME = rustdesk // The application's bundle identifier PRODUCT_BUNDLE_IDENTIFIER = com.carriez.flutterHbb diff --git a/flutter/windows/CMakeLists.txt b/flutter/windows/CMakeLists.txt index 89f0925f3..c6192b584 100644 --- a/flutter/windows/CMakeLists.txt +++ b/flutter/windows/CMakeLists.txt @@ -4,7 +4,7 @@ project(flutter_hbb LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. -set(BINARY_NAME "flutter_hbb") +set(BINARY_NAME "rustdesk") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. From ef80dab48e8177d1091adbe15db03e4fbd73659d Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 10:14:14 +0800 Subject: [PATCH 03/16] opt: remove drag to resize widget on macOS --- .../lib/desktop/pages/desktop_tab_page.dart | 48 +++---- .../desktop/pages/file_manager_tab_page.dart | 30 +++-- .../desktop/pages/port_forward_tab_page.dart | 36 +++--- .../lib/desktop/pages/remote_tab_page.dart | 117 +++++++++--------- 4 files changed, 123 insertions(+), 108 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_tab_page.dart b/flutter/lib/desktop/pages/desktop_tab_page.dart index fde543a89..725babdd8 100644 --- a/flutter/lib/desktop/pages/desktop_tab_page.dart +++ b/flutter/lib/desktop/pages/desktop_tab_page.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/consts.dart'; @@ -35,28 +37,30 @@ class _DesktopTabPageState extends State { Widget build(BuildContext context) { RxBool fullscreen = false.obs; Get.put(fullscreen, tag: 'fullscreen'); - return Obx(() => DragToResizeArea( - resizeEdgeSize: fullscreen.value ? 1.0 : 8.0, - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MyTheme.color(context).border!)), - child: Overlay(initialEntries: [ - OverlayEntry(builder: (context) { - gFFI.dialogManager.setOverlayState(Overlay.of(context)); - return Scaffold( - backgroundColor: MyTheme.color(context).bg, - body: DesktopTab( - controller: tabController, - tail: ActionIcon( - message: 'Settings', - icon: IconFont.menu, - onTap: onAddSetting, - isClose: false, - ), - )); - }) - ]), - ))); + final tabWidget = Container( + decoration: BoxDecoration( + border: Border.all(color: MyTheme.color(context).border!)), + child: Overlay(initialEntries: [ + OverlayEntry(builder: (context) { + gFFI.dialogManager.setOverlayState(Overlay.of(context)); + return Scaffold( + backgroundColor: MyTheme.color(context).bg, + body: DesktopTab( + controller: tabController, + tail: ActionIcon( + message: 'Settings', + icon: IconFont.menu, + onTap: onAddSetting, + isClose: false, + ), + )); + }) + ]), + ); + return Obx(() => Platform.isMacOS + ? tabWidget + : DragToResizeArea( + resizeEdgeSize: fullscreen.value ? 1.0 : 8.0, child: tabWidget)); } void onAddSetting() { diff --git a/flutter/lib/desktop/pages/file_manager_tab_page.dart b/flutter/lib/desktop/pages/file_manager_tab_page.dart index de874b42d..bfaf33327 100644 --- a/flutter/lib/desktop/pages/file_manager_tab_page.dart +++ b/flutter/lib/desktop/pages/file_manager_tab_page.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:io'; import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:flutter/material.dart'; @@ -66,20 +67,23 @@ class _FileManagerTabPageState extends State { @override Widget build(BuildContext context) { - return SubWindowDragToResizeArea( - windowId: windowId(), - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MyTheme.color(context).border!)), - child: Scaffold( - backgroundColor: MyTheme.color(context).bg, - body: DesktopTab( - controller: tabController, - onWindowCloseButton: handleWindowCloseButton, - tail: const AddButton().paddingOnly(left: 10), - )), - ), + final tabWidget = Container( + decoration: BoxDecoration( + border: Border.all(color: MyTheme.color(context).border!)), + child: Scaffold( + backgroundColor: MyTheme.color(context).bg, + body: DesktopTab( + controller: tabController, + onWindowCloseButton: handleWindowCloseButton, + tail: const AddButton().paddingOnly(left: 10), + )), ); + return Platform.isMacOS + ? tabWidget + : SubWindowDragToResizeArea( + windowId: windowId(), + child: tabWidget, + ); } void onRemoveId(String id) { diff --git a/flutter/lib/desktop/pages/port_forward_tab_page.dart b/flutter/lib/desktop/pages/port_forward_tab_page.dart index e4aac06fe..f142508de 100644 --- a/flutter/lib/desktop/pages/port_forward_tab_page.dart +++ b/flutter/lib/desktop/pages/port_forward_tab_page.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:io'; import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:flutter/material.dart'; @@ -74,23 +75,26 @@ class _PortForwardTabPageState extends State { @override Widget build(BuildContext context) { - return SubWindowDragToResizeArea( - windowId: windowId(), - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MyTheme.color(context).border!)), - child: Scaffold( - backgroundColor: MyTheme.color(context).bg, - body: DesktopTab( - controller: tabController, - onWindowCloseButton: () async { - tabController.clear(); - return true; - }, - tail: AddButton().paddingOnly(left: 10), - )), - ), + final tabWidget = Container( + decoration: BoxDecoration( + border: Border.all(color: MyTheme.color(context).border!)), + child: Scaffold( + backgroundColor: MyTheme.color(context).bg, + body: DesktopTab( + controller: tabController, + onWindowCloseButton: () async { + tabController.clear(); + return true; + }, + tail: AddButton().paddingOnly(left: 10), + )), ); + return Platform.isMacOS + ? tabWidget + : SubWindowDragToResizeArea( + windowId: windowId(), + child: tabWidget, + ); } void onRemoveId(String id) { diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart index 4d4c7e6e1..2bef85b60 100644 --- a/flutter/lib/desktop/pages/remote_tab_page.dart +++ b/flutter/lib/desktop/pages/remote_tab_page.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:io'; import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:flutter/material.dart'; @@ -86,63 +87,65 @@ class _ConnectionTabPageState extends State { @override Widget build(BuildContext context) { final RxBool fullscreen = Get.find(tag: 'fullscreen'); - return Obx(() => SubWindowDragToResizeArea( - resizeEdgeSize: fullscreen.value ? 1.0 : 8.0, - windowId: windowId(), - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MyTheme.color(context).border!)), - child: Scaffold( - backgroundColor: MyTheme.color(context).bg, - body: DesktopTab( - controller: tabController, - showTabBar: fullscreen.isFalse, - onWindowCloseButton: handleWindowCloseButton, - tail: const AddButton().paddingOnly(left: 10), - pageViewBuilder: (pageView) { - WindowController.fromWindowId(windowId()) - .setFullscreen(fullscreen.isTrue); - return pageView; - }, - tabBuilder: (key, icon, label, themeConf) => Obx(() { - final connectionType = ConnectionTypeState.find(key); - if (!connectionType.isValid()) { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - icon, - label, - ], - ); - } else { - final msgDirect = translate(connectionType.direct.value == - ConnectionType.strDirect - ? 'Direct Connection' - : 'Relay Connection'); - final msgSecure = translate(connectionType.secure.value == - ConnectionType.strSecure - ? 'Secure Connection' - : 'Insecure Connection'); - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - icon, - Tooltip( - message: '$msgDirect\n$msgSecure', - child: Image.asset( - 'assets/${connectionType.secure.value}${connectionType.direct.value}.png', - width: themeConf.iconSize, - height: themeConf.iconSize, - ).paddingOnly(right: 5), - ), - label, - ], - ); - } - }), - )), - ), - )); + final tabWidget = Container( + decoration: BoxDecoration( + border: Border.all(color: MyTheme.color(context).border!)), + child: Scaffold( + backgroundColor: MyTheme.color(context).bg, + body: DesktopTab( + controller: tabController, + showTabBar: fullscreen.isFalse, + onWindowCloseButton: handleWindowCloseButton, + tail: const AddButton().paddingOnly(left: 10), + pageViewBuilder: (pageView) { + WindowController.fromWindowId(windowId()) + .setFullscreen(fullscreen.isTrue); + return pageView; + }, + tabBuilder: (key, icon, label, themeConf) => Obx(() { + final connectionType = ConnectionTypeState.find(key); + if (!connectionType.isValid()) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + icon, + label, + ], + ); + } else { + final msgDirect = translate( + connectionType.direct.value == ConnectionType.strDirect + ? 'Direct Connection' + : 'Relay Connection'); + final msgSecure = translate( + connectionType.secure.value == ConnectionType.strSecure + ? 'Secure Connection' + : 'Insecure Connection'); + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + icon, + Tooltip( + message: '$msgDirect\n$msgSecure', + child: Image.asset( + 'assets/${connectionType.secure.value}${connectionType.direct.value}.png', + width: themeConf.iconSize, + height: themeConf.iconSize, + ).paddingOnly(right: 5), + ), + label, + ], + ); + } + }), + )), + ); + return Obx(() => Platform.isMacOS + ? tabWidget + : SubWindowDragToResizeArea( + resizeEdgeSize: fullscreen.value ? 1.0 : 8.0, + windowId: windowId(), + child: tabWidget)); } void onRemoveId(String id) { From 910fb84857f0bdeebe0a5b661fc3684e20e080cb Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 10:22:40 +0800 Subject: [PATCH 04/16] opt: more error catch on address book --- flutter/lib/models/ab_model.dart | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/flutter/lib/models/ab_model.dart b/flutter/lib/models/ab_model.dart index 2749e972f..161a4d8a5 100644 --- a/flutter/lib/models/ab_model.dart +++ b/flutter/lib/models/ab_model.dart @@ -45,8 +45,8 @@ class AbModel with ChangeNotifier { } catch (err) { abError = err.toString(); } finally { - notifyListeners(); abLoading = false; + notifyListeners(); } return null; } @@ -98,12 +98,18 @@ class AbModel with ChangeNotifier { final body = jsonEncode({ "data": jsonEncode({"tags": tags, "peers": peers}) }); - final resp = - await http.post(Uri.parse(api), headers: authHeaders, body: body); - abLoading = false; - await getAb(); + try { + final resp = + await http.post(Uri.parse(api), headers: authHeaders, body: body); + abError = ""; + await getAb(); + debugPrint("resp: ${resp.body}"); + } catch (e) { + abError = e.toString(); + } finally { + abLoading = false; + } notifyListeners(); - debugPrint("resp: ${resp.body}"); } bool idContainBy(String id) { From 225d5a098339e9e1fd6f24670698074382cf3370 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 11:09:29 +0800 Subject: [PATCH 05/16] fix: place obx down --- flutter/lib/desktop/pages/desktop_tab_page.dart | 4 ++-- flutter/lib/desktop/pages/remote_tab_page.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_tab_page.dart b/flutter/lib/desktop/pages/desktop_tab_page.dart index 725babdd8..a117bab12 100644 --- a/flutter/lib/desktop/pages/desktop_tab_page.dart +++ b/flutter/lib/desktop/pages/desktop_tab_page.dart @@ -57,9 +57,9 @@ class _DesktopTabPageState extends State { }) ]), ); - return Obx(() => Platform.isMacOS + return Platform.isMacOS ? tabWidget - : DragToResizeArea( + : Obx(() => DragToResizeArea( resizeEdgeSize: fullscreen.value ? 1.0 : 8.0, child: tabWidget)); } diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart index 2bef85b60..5ea94f4a9 100644 --- a/flutter/lib/desktop/pages/remote_tab_page.dart +++ b/flutter/lib/desktop/pages/remote_tab_page.dart @@ -140,9 +140,9 @@ class _ConnectionTabPageState extends State { }), )), ); - return Obx(() => Platform.isMacOS + return Platform.isMacOS ? tabWidget - : SubWindowDragToResizeArea( + : Obx(() => SubWindowDragToResizeArea( resizeEdgeSize: fullscreen.value ? 1.0 : 8.0, windowId: windowId(), child: tabWidget)); From f1a3a8ca0187d6b52f1ef6cf98d79d60b6254ca3 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 15:46:09 +0800 Subject: [PATCH 06/16] opt: add support locales --- flutter/lib/common.dart | 25 +++++++++++++++++++++++++ flutter/lib/main.dart | 41 ++++++++++++++++++++++++++++++++++++----- flutter/pubspec.yaml | 2 ++ 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index c07764e32..3e08d1e0c 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -244,6 +244,31 @@ final ButtonStyle flatButtonStyle = TextButton.styleFrom( ), ); +List supportedLocales = const [ + // specify CN/TW to fix CJK issue in flutter + Locale('zh', 'CN'), + Locale('zh', 'TW'), + Locale('fr'), + Locale('de'), + Locale('it'), + Locale('ja'), + Locale('cs'), + Locale('pl'), + Locale('ko'), + Locale('hu'), + Locale('pt'), + Locale('ru'), + Locale('sk'), + Locale('id'), + Locale('da'), + Locale('eo'), + Locale('tr'), + Locale('vi'), + Locale('pl'), + Locale('kz'), + Locale('en', 'US'), +]; + String formatDurationToTime(Duration duration) { var totalTime = duration.inSeconds; final secs = totalTime % 60; diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index 43069bf79..8f04846e9 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -8,6 +8,7 @@ import 'package:flutter_hbb/desktop/screen/desktop_file_transfer_screen.dart'; import 'package:flutter_hbb/desktop/screen/desktop_port_forward_screen.dart'; import 'package:flutter_hbb/desktop/screen/desktop_remote_screen.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:get/get.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -123,6 +124,12 @@ void runRemoteScreen(Map argument) async { home: DesktopRemoteScreen( params: argument, ), + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: supportedLocales, navigatorObservers: const [ // FirebaseAnalyticsObserver(analytics: analytics), ], @@ -141,6 +148,12 @@ void runFileTransferScreen(Map argument) async { darkTheme: MyTheme.darkTheme, themeMode: MyTheme.initialThemeMode(), home: DesktopFileTransferScreen(params: argument), + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: supportedLocales, navigatorObservers: const [ // FirebaseAnalyticsObserver(analytics: analytics), ], @@ -160,6 +173,12 @@ void runPortForwardScreen(Map argument) async { darkTheme: MyTheme.darkTheme, themeMode: MyTheme.initialThemeMode(), home: DesktopPortForwardScreen(params: argument), + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: supportedLocales, navigatorObservers: const [ // FirebaseAnalyticsObserver(analytics: analytics), ], @@ -178,14 +197,20 @@ void runConnectionManagerScreen() async { theme: MyTheme.lightTheme, darkTheme: MyTheme.darkTheme, themeMode: MyTheme.initialThemeMode(), + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: supportedLocales, home: const DesktopServerPage(), builder: _keepScaleBuilder())); windowManager.waitUntilReadyToShow(windowOptions, () async { - await windowManager.setAlignment(Alignment.topRight); - await windowManager.show(); - await windowManager.focus(); - await windowManager.setAlignment(Alignment.topRight); // ensure - }); + await windowManager.setAlignment(Alignment.topRight); + await windowManager.show(); + await windowManager.focus(); + await windowManager.setAlignment(Alignment.topRight); // ensure + }); } WindowOptions getHiddenTitleBarWindowOptions({Size? size}) { @@ -247,6 +272,12 @@ class _AppState extends State { navigatorObservers: const [ // FirebaseAnalyticsObserver(analytics: analytics), ], + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: supportedLocales, builder: isAndroid ? (context, child) => AccessibilityListener( child: MediaQuery( diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 09025ad0e..9248fe80e 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -24,6 +24,8 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. From 21eb7bd1651e586d2573b667d3fe7ba3f54091cf Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 16:06:03 +0800 Subject: [PATCH 07/16] opt: more configurable scroll logic & edge size --- flutter/lib/common.dart | 1 + .../lib/desktop/pages/desktop_tab_page.dart | 2 +- .../desktop/pages/file_manager_tab_page.dart | 1 + .../desktop/pages/port_forward_tab_page.dart | 1 + .../lib/desktop/pages/remote_tab_page.dart | 2 +- flutter/lib/desktop/widgets/peer_widget.dart | 97 ++++++++++--------- .../lib/desktop/widgets/scroll_wrapper.dart | 21 ++++ flutter/pubspec.yaml | 1 + 8 files changed, 79 insertions(+), 47 deletions(-) create mode 100644 flutter/lib/desktop/widgets/scroll_wrapper.dart diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 3e08d1e0c..dfe96c903 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -248,6 +248,7 @@ List supportedLocales = const [ // specify CN/TW to fix CJK issue in flutter Locale('zh', 'CN'), Locale('zh', 'TW'), + Locale('zh', 'SG'), Locale('fr'), Locale('de'), Locale('it'), diff --git a/flutter/lib/desktop/pages/desktop_tab_page.dart b/flutter/lib/desktop/pages/desktop_tab_page.dart index a117bab12..8a49f4cde 100644 --- a/flutter/lib/desktop/pages/desktop_tab_page.dart +++ b/flutter/lib/desktop/pages/desktop_tab_page.dart @@ -60,7 +60,7 @@ class _DesktopTabPageState extends State { return Platform.isMacOS ? tabWidget : Obx(() => DragToResizeArea( - resizeEdgeSize: fullscreen.value ? 1.0 : 8.0, child: tabWidget)); + resizeEdgeSize: fullscreen.value ? 1.0 : 4.0, child: tabWidget)); } void onAddSetting() { diff --git a/flutter/lib/desktop/pages/file_manager_tab_page.dart b/flutter/lib/desktop/pages/file_manager_tab_page.dart index bfaf33327..086f3b184 100644 --- a/flutter/lib/desktop/pages/file_manager_tab_page.dart +++ b/flutter/lib/desktop/pages/file_manager_tab_page.dart @@ -81,6 +81,7 @@ class _FileManagerTabPageState extends State { return Platform.isMacOS ? tabWidget : SubWindowDragToResizeArea( + resizeEdgeSize: 4.0, windowId: windowId(), child: tabWidget, ); diff --git a/flutter/lib/desktop/pages/port_forward_tab_page.dart b/flutter/lib/desktop/pages/port_forward_tab_page.dart index f142508de..b92943f13 100644 --- a/flutter/lib/desktop/pages/port_forward_tab_page.dart +++ b/flutter/lib/desktop/pages/port_forward_tab_page.dart @@ -92,6 +92,7 @@ class _PortForwardTabPageState extends State { return Platform.isMacOS ? tabWidget : SubWindowDragToResizeArea( + resizeEdgeSize: 4.0, windowId: windowId(), child: tabWidget, ); diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart index 5ea94f4a9..70003483a 100644 --- a/flutter/lib/desktop/pages/remote_tab_page.dart +++ b/flutter/lib/desktop/pages/remote_tab_page.dart @@ -143,7 +143,7 @@ class _ConnectionTabPageState extends State { return Platform.isMacOS ? tabWidget : Obx(() => SubWindowDragToResizeArea( - resizeEdgeSize: fullscreen.value ? 1.0 : 8.0, + resizeEdgeSize: fullscreen.value ? 1.0 : 4.0, windowId: windowId(), child: tabWidget)); } diff --git a/flutter/lib/desktop/widgets/peer_widget.dart b/flutter/lib/desktop/widgets/peer_widget.dart index f137241a9..07a621add 100644 --- a/flutter/lib/desktop/widgets/peer_widget.dart +++ b/flutter/lib/desktop/widgets/peer_widget.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart'; import 'package:get/get.dart'; import 'package:provider/provider.dart'; import 'package:visibility_detector/visibility_detector.dart'; @@ -41,6 +42,7 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener { static const int _maxQueryCount = 3; final _curPeers = {}; + final _scrollController = ScrollController(); var _lastChangeTime = DateTime.now(); var _lastQueryPeers = {}; var _lastQueryTime = DateTime.now().subtract(const Duration(hours: 1)); @@ -84,53 +86,58 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener { ? Center( child: Text(translate("Empty")), ) - : SingleChildScrollView( - controller: ScrollController(), - child: ObxValue((searchText) { - return FutureBuilder>( - builder: (context, snapshot) { - if (snapshot.hasData) { - final peers = snapshot.data!; - final cards = []; - for (final peer in peers) { - cards.add(Offstage( - key: ValueKey("off${peer.id}"), - offstage: widget.offstageFunc(peer), - child: Obx( - () => SizedBox( - width: 220, - height: - peerCardUiType.value == PeerUiType.grid - ? 140 - : 42, - child: VisibilityDetector( - key: ValueKey(peer.id), - onVisibilityChanged: (info) { - final peerId = - (info.key as ValueKey).value; - if (info.visibleFraction > 0.00001) { - _curPeers.add(peerId); - } else { - _curPeers.remove(peerId); - } - _lastChangeTime = DateTime.now(); - }, - child: widget.peerCardWidgetFunc(peer), + : DesktopScrollWrapper( + scrollController: _scrollController, + child: SingleChildScrollView( + controller: _scrollController, + child: ObxValue((searchText) { + return FutureBuilder>( + builder: (context, snapshot) { + if (snapshot.hasData) { + final peers = snapshot.data!; + final cards = []; + for (final peer in peers) { + cards.add(Offstage( + key: ValueKey("off${peer.id}"), + offstage: widget.offstageFunc(peer), + child: Obx( + () => SizedBox( + width: 220, + height: + peerCardUiType.value == PeerUiType.grid + ? 140 + : 42, + child: VisibilityDetector( + key: ValueKey(peer.id), + onVisibilityChanged: (info) { + final peerId = + (info.key as ValueKey).value; + if (info.visibleFraction > 0.00001) { + _curPeers.add(peerId); + } else { + _curPeers.remove(peerId); + } + _lastChangeTime = DateTime.now(); + }, + child: widget.peerCardWidgetFunc(peer), + ), ), - ), - ))); + ))); + } + return Wrap( + spacing: space, + runSpacing: space, + children: cards); + } else { + return const Center( + child: CircularProgressIndicator(), + ); } - return Wrap( - spacing: space, runSpacing: space, children: cards); - } else { - return const Center( - child: CircularProgressIndicator(), - ); - } - }, - future: matchPeers(searchText.value, peers.peers), - ); - }, peerSearchText), + }, + future: matchPeers(searchText.value, peers.peers), + ); + }, peerSearchText), + ), ), ), ); diff --git a/flutter/lib/desktop/widgets/scroll_wrapper.dart b/flutter/lib/desktop/widgets/scroll_wrapper.dart new file mode 100644 index 000000000..dc333205f --- /dev/null +++ b/flutter/lib/desktop/widgets/scroll_wrapper.dart @@ -0,0 +1,21 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_improved_scrolling/flutter_improved_scrolling.dart'; + +class DesktopScrollWrapper extends StatelessWidget { + final ScrollController scrollController; + final Widget child; + const DesktopScrollWrapper( + {Key? key, required this.scrollController, required this.child}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return ImprovedScrolling( + scrollController: scrollController, + enableCustomMouseWheelScrolling: false, + customMouseWheelScrollConfig: + const CustomMouseWheelScrollConfig(scrollAmountMultiplier: 3.0), + child: child, + ); + } +} diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 9248fe80e..9bc8816ef 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -80,6 +80,7 @@ dependencies: desktop_drop: ^0.3.3 scroll_pos: ^0.3.0 rxdart: ^0.27.5 + flutter_improved_scrolling: ^0.0.3 dev_dependencies: icons_launcher: ^2.0.4 From c2f516f57fc8f49330bea14542ee4382e27282c6 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 17:10:12 +0800 Subject: [PATCH 08/16] opt: use const variable --- flutter/lib/consts.dart | 5 +++++ flutter/lib/desktop/pages/desktop_tab_page.dart | 4 +++- flutter/lib/desktop/pages/file_manager_tab_page.dart | 3 ++- flutter/lib/desktop/pages/port_forward_tab_page.dart | 3 ++- flutter/lib/desktop/pages/remote_tab_page.dart | 3 ++- flutter/lib/desktop/widgets/scroll_wrapper.dart | 5 +++-- 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 8986f05ec..0d93df778 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -15,6 +15,11 @@ const int kMobileDefaultDisplayHeight = 1280; const int kDesktopDefaultDisplayWidth = 1080; const int kDesktopDefaultDisplayHeight = 720; +/// [kDefaultScrollAmountMultiplier] indicates how many rows can be scrolled after a minimum scroll action of mouse +const kDefaultScrollAmountMultiplier = 3.0; +const kFullScreenEdgeSize = 1.0; +const kWindowEdgeSize = 4.0; + const kInvalidValueStr = "InvalidValueStr"; /// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels diff --git a/flutter/lib/desktop/pages/desktop_tab_page.dart b/flutter/lib/desktop/pages/desktop_tab_page.dart index 8a49f4cde..58ed34947 100644 --- a/flutter/lib/desktop/pages/desktop_tab_page.dart +++ b/flutter/lib/desktop/pages/desktop_tab_page.dart @@ -60,7 +60,9 @@ class _DesktopTabPageState extends State { return Platform.isMacOS ? tabWidget : Obx(() => DragToResizeArea( - resizeEdgeSize: fullscreen.value ? 1.0 : 4.0, child: tabWidget)); + resizeEdgeSize: + fullscreen.value ? kFullScreenEdgeSize : kWindowEdgeSize, + child: tabWidget)); } void onAddSetting() { diff --git a/flutter/lib/desktop/pages/file_manager_tab_page.dart b/flutter/lib/desktop/pages/file_manager_tab_page.dart index 086f3b184..9b8060bb7 100644 --- a/flutter/lib/desktop/pages/file_manager_tab_page.dart +++ b/flutter/lib/desktop/pages/file_manager_tab_page.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/common.dart'; +import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/desktop/pages/file_manager_page.dart'; import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart'; @@ -81,7 +82,7 @@ class _FileManagerTabPageState extends State { return Platform.isMacOS ? tabWidget : SubWindowDragToResizeArea( - resizeEdgeSize: 4.0, + resizeEdgeSize: kWindowEdgeSize, windowId: windowId(), child: tabWidget, ); diff --git a/flutter/lib/desktop/pages/port_forward_tab_page.dart b/flutter/lib/desktop/pages/port_forward_tab_page.dart index b92943f13..d4f17aaef 100644 --- a/flutter/lib/desktop/pages/port_forward_tab_page.dart +++ b/flutter/lib/desktop/pages/port_forward_tab_page.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/common.dart'; +import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/desktop/pages/port_forward_page.dart'; import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart'; @@ -92,7 +93,7 @@ class _PortForwardTabPageState extends State { return Platform.isMacOS ? tabWidget : SubWindowDragToResizeArea( - resizeEdgeSize: 4.0, + resizeEdgeSize: kWindowEdgeSize, windowId: windowId(), child: tabWidget, ); diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart index 70003483a..b086a2e35 100644 --- a/flutter/lib/desktop/pages/remote_tab_page.dart +++ b/flutter/lib/desktop/pages/remote_tab_page.dart @@ -143,7 +143,8 @@ class _ConnectionTabPageState extends State { return Platform.isMacOS ? tabWidget : Obx(() => SubWindowDragToResizeArea( - resizeEdgeSize: fullscreen.value ? 1.0 : 4.0, + resizeEdgeSize: + fullscreen.value ? kFullScreenEdgeSize : kWindowEdgeSize, windowId: windowId(), child: tabWidget)); } diff --git a/flutter/lib/desktop/widgets/scroll_wrapper.dart b/flutter/lib/desktop/widgets/scroll_wrapper.dart index dc333205f..96eb9f735 100644 --- a/flutter/lib/desktop/widgets/scroll_wrapper.dart +++ b/flutter/lib/desktop/widgets/scroll_wrapper.dart @@ -1,4 +1,5 @@ import 'package:flutter/widgets.dart'; +import 'package:flutter_hbb/consts.dart'; import 'package:flutter_improved_scrolling/flutter_improved_scrolling.dart'; class DesktopScrollWrapper extends StatelessWidget { @@ -13,8 +14,8 @@ class DesktopScrollWrapper extends StatelessWidget { return ImprovedScrolling( scrollController: scrollController, enableCustomMouseWheelScrolling: false, - customMouseWheelScrollConfig: - const CustomMouseWheelScrollConfig(scrollAmountMultiplier: 3.0), + customMouseWheelScrollConfig: const CustomMouseWheelScrollConfig( + scrollAmountMultiplier: kDefaultScrollAmountMultiplier), child: child, ); } From e0d759c3bb47af8eae2641ac74a3319688538892 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 19 Sep 2022 18:38:19 +0800 Subject: [PATCH 09/16] remove menu from desktop home page --- flutter/analysis_options.yaml | 29 +- .../lib/desktop/pages/connection_page.dart | 2 + .../lib/desktop/pages/desktop_home_page.dart | 471 +----------------- flutter/pubspec.lock | 24 +- flutter/test/widget_test.dart | 30 -- 5 files changed, 42 insertions(+), 514 deletions(-) delete mode 100644 flutter/test/widget_test.dart diff --git a/flutter/analysis_options.yaml b/flutter/analysis_options.yaml index 61b6c4de1..a679f5774 100644 --- a/flutter/analysis_options.yaml +++ b/flutter/analysis_options.yaml @@ -1,29 +1,6 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. -include: package:flutter_lints/flutter.yaml +include: package:lints/recommended.yaml linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at - # https://dart-lang.github.io/linter/lints/index.html. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options + non_constant_identifier_names: false + sort_child_properties_last: false diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 9024c996f..e857df271 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -1,3 +1,5 @@ +// main window right pane + import 'dart:async'; import 'dart:convert'; diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index c8706d5a0..b574900fe 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -5,29 +5,14 @@ import 'package:flutter/material.dart' hide MenuItem; import 'package:flutter/services.dart'; import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/desktop/pages/connection_page.dart'; -import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart'; -import 'package:flutter_hbb/desktop/widgets/popup_menu.dart'; -import 'package:flutter_hbb/desktop/widgets/material_mod_popup_menu.dart' - as mod_menu; import 'package:flutter_hbb/models/platform_model.dart'; import 'package:flutter_hbb/models/server_model.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart'; import 'package:get/get.dart'; import 'package:provider/provider.dart'; -import 'package:shared_preferences/shared_preferences.dart'; import 'package:tray_manager/tray_manager.dart'; -import 'package:url_launcher/url_launcher_string.dart'; import 'package:window_manager/window_manager.dart'; -import '../../common/widgets/dialog.dart'; - -class _MenubarTheme { - static const Color commonColor = MyTheme.accent; - // kMinInteractiveDimension - static const double height = 25.0; - static const double dividerHeight = 12.0; -} - class DesktopHomePage extends StatefulWidget { const DesktopHomePage({Key? key}) : super(key: key); @@ -66,19 +51,19 @@ class _DesktopHomePageState extends State super.build(context); return Row( children: [ - buildServerInfo(context), + buildLeftPane(context), const VerticalDivider( width: 1, thickness: 1, ), Expanded( - child: buildServerBoard(context), + child: buildRightPane(context), ), ], ); } - buildServerInfo(BuildContext context) { + buildLeftPane(BuildContext context) { return ChangeNotifierProvider.value( value: gFFI.serverModel, child: Container( @@ -95,7 +80,7 @@ class _DesktopHomePageState extends State ); } - buildServerBoard(BuildContext context) { + buildRightPane(BuildContext context) { return Container( color: MyTheme.color(context).grayBg, child: ConnectionPage(), @@ -167,93 +152,9 @@ class _DesktopHomePageState extends State } Widget buildPopupMenu(BuildContext context) { - var position; RxBool hover = false.obs; return InkWell( - onTapDown: (detail) { - final x = detail.globalPosition.dx; - final y = detail.globalPosition.dy; - position = RelativeRect.fromLTRB(x, y, x, y); - }, - onTap: () async { - final userName = await gFFI.userModel.getUserName(); - final enabledInput = await bind.mainGetOption(key: 'enable-audio'); - final defaultInput = await gFFI.getDefaultAudioInput(); - var menu = [ - await genEnablePopupMenuItem( - translate("Enable Keyboard/Mouse"), - 'enable-keyboard', - ), - await genEnablePopupMenuItem( - translate("Enable Clipboard"), - 'enable-clipboard', - ), - await genEnablePopupMenuItem( - translate("Enable File Transfer"), - 'enable-file-transfer', - ), - await genEnablePopupMenuItem( - translate("Enable TCP Tunneling"), - 'enable-tunnel', - ), - genAudioInputPopupMenuItem(enabledInput != "N", defaultInput), - PopupMenuDivider(), - PopupMenuItem( - child: Text(translate("ID/Relay Server")), - value: 'custom-server', - ), - PopupMenuItem( - child: Text(translate("IP Whitelisting")), - value: 'whitelist', - ), - PopupMenuItem( - child: Text(translate("Socks5 Proxy")), - value: 'socks5-proxy', - ), - PopupMenuDivider(), - await genEnablePopupMenuItem( - translate("Enable Service"), - 'stop-service', - ), - // TODO: direct server - await genEnablePopupMenuItem( - translate("Always connected via relay"), - 'allow-always-relay', - ), - await genEnablePopupMenuItem( - translate("Start ID/relay service"), - 'stop-rendezvous-service', - ), - PopupMenuDivider(), - userName.isEmpty - ? PopupMenuItem( - child: Text(translate("Login")), - value: 'login', - ) - : PopupMenuItem( - child: Text("${translate("Logout")} $userName"), - value: 'logout', - ), - PopupMenuItem( - child: Text(translate("Change ID")), - value: 'change-id', - ), - PopupMenuDivider(), - await genEnablePopupMenuItem( - translate("Dark Theme"), - 'allow-darktheme', - ), - PopupMenuItem( - child: Text(translate("About")), - value: 'about', - ), - ]; - final v = - await showMenu(context: context, position: position, items: menu); - if (v != null) { - onSelectMenu(v); - } - }, + onTap: () async {}, child: Obx( () => CircleAvatar( radius: 15, @@ -276,6 +177,7 @@ class _DesktopHomePageState extends State buildPasswordBoard(BuildContext context) { final model = gFFI.serverModel; RxBool refreshHover = false.obs; + RxBool editHover = false.obs; return Container( margin: EdgeInsets.only(left: 20.0, right: 16, top: 13, bottom: 13), child: Row( @@ -334,7 +236,19 @@ class _DesktopHomePageState extends State onTap: () => bind.mainUpdateTemporaryPassword(), onHover: (value) => refreshHover.value = value, ), - const _PasswordPopupMenu(), + InkWell( + child: Obx( + () => Icon( + Icons.edit, + color: editHover.value + ? MyTheme.color(context).text + : Color(0xFFDDDDDD), + size: 22, + ).marginOnly(right: 8, bottom: 2), + ), + onTap: () => {}, + onHover: (value) => editHover.value = value, + ), ], ), ], @@ -408,236 +322,6 @@ class _DesktopHomePageState extends State windowManager.removeListener(this); super.dispose(); } - - void changeTheme(String choice) async { - if (choice == "Y") { - Get.changeTheme(MyTheme.darkTheme); - } else { - Get.changeTheme(MyTheme.lightTheme); - } - Get.find().setString("darkTheme", choice); - Get.forceAppUpdate(); - } - - void onSelectMenu(String key) async { - if (key.startsWith('enable-')) { - final option = await bind.mainGetOption(key: key); - bind.mainSetOption(key: key, value: option == "N" ? "" : "N"); - } else if (key.startsWith('allow-')) { - final option = await bind.mainGetOption(key: key); - final choice = option == "Y" ? "" : "Y"; - bind.mainSetOption(key: key, value: choice); - if (key == "allow-darktheme") changeTheme(choice); - } else if (key == "stop-service") { - final option = await bind.mainGetOption(key: key); - bind.mainSetOption(key: key, value: option == "Y" ? "" : "Y"); - } else if (key == "change-id") { - changeIdDialog(); - } else if (key == "custom-server") { - changeServer(); - } else if (key == "whitelist") { - changeWhiteList(); - } else if (key == "socks5-proxy") { - changeSocks5Proxy(); - } else if (key == "about") { - about(); - } else if (key == "logout") { - logOut(); - } else if (key == "login") { - login(); - } - } - - Future> genEnablePopupMenuItem( - String label, String key) async { - final v = await bind.mainGetOption(key: key); - bool enable; - if (key == "stop-service") { - enable = v != "Y"; - } else if (key.startsWith("allow-")) { - enable = v == "Y"; - } else { - enable = v != "N"; - } - - return PopupMenuItem( - child: Row( - children: [ - Icon(Icons.check, - color: enable ? null : MyTheme.accent.withAlpha(00)), - Text( - label, - style: genTextStyle(enable), - ), - ], - ), - value: key, - ); - } - - TextStyle genTextStyle(bool isPositive) { - return isPositive - ? TextStyle() - : TextStyle( - color: Colors.redAccent, decoration: TextDecoration.lineThrough); - } - - PopupMenuItem genAudioInputPopupMenuItem( - bool enableInput, String defaultAudioInput) { - final defaultInput = defaultAudioInput.obs; - final enabled = enableInput.obs; - - return PopupMenuItem( - child: FutureBuilder>( - future: gFFI.getAudioInputs(), - builder: (context, snapshot) { - if (snapshot.hasData) { - final inputs = snapshot.data!.toList(); - if (Platform.isWindows) { - inputs.insert(0, translate("System Sound")); - } - var inputList = inputs - .map((e) => PopupMenuItem( - child: Row( - children: [ - Obx(() => Offstage( - offstage: defaultInput.value != e, - child: Icon(Icons.check))), - Expanded( - child: Tooltip( - message: e, - child: Text( - "$e", - maxLines: 1, - overflow: TextOverflow.ellipsis, - ))), - ], - ), - value: e, - )) - .toList(); - inputList.insert( - 0, - PopupMenuItem( - child: Row( - children: [ - Obx(() => Offstage( - offstage: enabled.value, child: Icon(Icons.check))), - Expanded(child: Text(translate("Mute"))), - ], - ), - value: "Mute", - )); - return PopupMenuButton( - padding: EdgeInsets.zero, - child: Container( - alignment: Alignment.centerLeft, - child: Text(translate("Audio Input"))), - itemBuilder: (context) => inputList, - onSelected: (dev) async { - if (dev == "Mute") { - await bind.mainSetOption( - key: 'enable-audio', value: enabled.value ? '' : 'N'); - enabled.value = - await bind.mainGetOption(key: 'enable-audio') != 'N'; - } else if (dev != await gFFI.getDefaultAudioInput()) { - gFFI.setDefaultAudioInput(dev); - defaultInput.value = dev; - } - }, - ); - } else { - return Text("..."); - } - }, - ), - value: 'audio-input', - ); - } - - void about() async { - final appName = await bind.mainGetAppName(); - final license = await bind.mainGetLicense(); - final version = await bind.mainGetVersion(); - const linkStyle = TextStyle(decoration: TextDecoration.underline); - gFFI.dialogManager.show((setState, close) { - return CustomAlertDialog( - title: Text("About $appName"), - content: ConstrainedBox( - constraints: const BoxConstraints(minWidth: 500), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 8.0, - ), - Text("Version: $version").marginSymmetric(vertical: 4.0), - InkWell( - onTap: () { - launchUrlString("https://rustdesk.com/privacy"); - }, - child: const Text( - "Privacy Statement", - style: linkStyle, - ).marginSymmetric(vertical: 4.0)), - InkWell( - onTap: () { - launchUrlString("https://rustdesk.com"); - }, - child: const Text( - "Website", - style: linkStyle, - ).marginSymmetric(vertical: 4.0)), - Container( - decoration: const BoxDecoration(color: Color(0xFF2c8cff)), - padding: - const EdgeInsets.symmetric(vertical: 24, horizontal: 8), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Copyright © 2022 Purslane Ltd.\n$license", - style: const TextStyle(color: Colors.white), - ), - const Text( - "Made with heart in this chaotic world!", - style: TextStyle( - fontWeight: FontWeight.w800, - color: Colors.white), - ) - ], - ), - ), - ], - ), - ).marginSymmetric(vertical: 4.0) - ], - ), - ), - actions: [ - TextButton(onPressed: close, child: Text(translate("OK"))), - ], - onSubmit: close, - onCancel: close, - ); - }); - } - - void login() { - loginDialog().then((success) { - if (success) { - // refresh frame - setState(() {}); - } - }); - } - - void logOut() { - gFFI.userModel.logOut().then((_) => {setState(() {})}); - } } /// common login dialog for desktop @@ -874,120 +558,3 @@ void setPasswordDialog() async { ); }); } - -class _PasswordPopupMenu extends StatefulWidget { - const _PasswordPopupMenu({Key? key}) : super(key: key); - - @override - State<_PasswordPopupMenu> createState() => _PasswordPopupMenuState(); -} - -class _PasswordPopupMenuState extends State<_PasswordPopupMenu> { - final RxBool _tempEnabled = true.obs; - final RxBool _permEnabled = true.obs; - - List> _buildMenus() { - return >[ - MenuEntryRadios( - text: translate('Password type'), - optionsGetter: () => [ - MenuEntryRadioOption( - text: translate('Use temporary password'), - value: kUseTemporaryPassword), - MenuEntryRadioOption( - text: translate('Use permanent password'), - value: kUsePermanentPassword), - MenuEntryRadioOption( - text: translate('Use both passwords'), - value: kUseBothPasswords), - ], - curOptionGetter: () async { - return gFFI.serverModel.verificationMethod; - }, - optionSetter: (String oldValue, String newValue) async { - await bind.mainSetOption( - key: "verification-method", value: newValue); - await gFFI.serverModel.updatePasswordModel(); - setState(() { - _tempEnabled.value = - gFFI.serverModel.verificationMethod != kUsePermanentPassword; - _permEnabled.value = - gFFI.serverModel.verificationMethod != kUseTemporaryPassword; - }); - }), - MenuEntryDivider(), - MenuEntryButton( - enabled: _permEnabled, - childBuilder: (TextStyle? style) => Text( - translate('Set permanent password'), - style: style, - ), - proc: () { - setPasswordDialog(); - }, - dismissOnClicked: true, - ), - MenuEntrySubMenu( - enabled: _tempEnabled, - text: translate('Set temporary password length'), - entries: [ - MenuEntryRadios( - enabled: _tempEnabled, - text: translate(''), - optionsGetter: () => [ - MenuEntryRadioOption( - text: translate('6'), - value: '6', - enabled: _tempEnabled, - ), - MenuEntryRadioOption( - text: translate('8'), - value: '8', - enabled: _tempEnabled, - ), - MenuEntryRadioOption( - text: translate('10'), - value: '10', - enabled: _tempEnabled, - ), - ], - curOptionGetter: () async { - return gFFI.serverModel.temporaryPasswordLength; - }, - optionSetter: (String oldValue, String newValue) async { - if (oldValue != newValue) { - await gFFI.serverModel.setTemporaryPasswordLength(newValue); - await gFFI.serverModel.updatePasswordModel(); - } - }), - ]) - ]; - } - - @override - Widget build(BuildContext context) { - final editHover = false.obs; - return mod_menu.PopupMenuButton( - padding: EdgeInsets.zero, - onHover: (v) => editHover.value = v, - tooltip: translate(''), - position: mod_menu.PopupMenuPosition.overSide, - itemBuilder: (BuildContext context) => _buildMenus() - .map((entry) => entry.build( - context, - const MenuConfig( - commonColor: _MenubarTheme.commonColor, - height: _MenubarTheme.height, - dividerHeight: _MenubarTheme.dividerHeight, - ))) - .expand((i) => i) - .toList(), - child: Obx(() => Icon(Icons.edit, - size: 22, - color: editHover.value - ? MyTheme.color(context).text - : const Color(0xFFDDDDDD)) - .marginOnly(bottom: 2)), - ); - } -} diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 7c0b90e54..c6caebc77 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -140,7 +140,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "1.2.0" charcode: dependency: transitive description: @@ -161,7 +161,7 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.1.0" code_builder: dependency: transitive description: @@ -367,6 +367,13 @@ packages: url: "https://github.com/Kingtous/rustdesk_flutter_custom_cursor" source: git version: "0.0.1" + flutter_improved_scrolling: + dependency: "direct main" + description: + name: flutter_improved_scrolling + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.3" flutter_lints: dependency: "direct dev" description: @@ -374,6 +381,11 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_parsed_text: dependency: transitive description: @@ -478,7 +490,7 @@ packages: name: icons_launcher url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.4" image: dependency: "direct main" description: @@ -576,7 +588,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.5" + version: "0.1.4" menu_base: dependency: transitive description: @@ -590,7 +602,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.7.0" mime: dependency: transitive description: @@ -667,7 +679,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.8.1" path_provider: dependency: "direct main" description: diff --git a/flutter/test/widget_test.dart b/flutter/test/widget_test.dart deleted file mode 100644 index 3e7534740..000000000 --- a/flutter/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_hbb/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(App()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} From e1ab01a97f6d769c96c41a16ec43665b990edfd5 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 19:18:05 +0800 Subject: [PATCH 10/16] opt: use custom scroll feature --- flutter/lib/consts.dart | 2 +- flutter/lib/desktop/widgets/peer_widget.dart | 1 + flutter/lib/desktop/widgets/scroll_wrapper.dart | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 0d93df778..3ed080206 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -16,7 +16,7 @@ const int kDesktopDefaultDisplayWidth = 1080; const int kDesktopDefaultDisplayHeight = 720; /// [kDefaultScrollAmountMultiplier] indicates how many rows can be scrolled after a minimum scroll action of mouse -const kDefaultScrollAmountMultiplier = 3.0; +const kDefaultScrollAmountMultiplier = 10.0; const kFullScreenEdgeSize = 1.0; const kWindowEdgeSize = 4.0; diff --git a/flutter/lib/desktop/widgets/peer_widget.dart b/flutter/lib/desktop/widgets/peer_widget.dart index 07a621add..1b0626198 100644 --- a/flutter/lib/desktop/widgets/peer_widget.dart +++ b/flutter/lib/desktop/widgets/peer_widget.dart @@ -89,6 +89,7 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener { : DesktopScrollWrapper( scrollController: _scrollController, child: SingleChildScrollView( + physics: const NeverScrollableScrollPhysics(), controller: _scrollController, child: ObxValue((searchText) { return FutureBuilder>( diff --git a/flutter/lib/desktop/widgets/scroll_wrapper.dart b/flutter/lib/desktop/widgets/scroll_wrapper.dart index 96eb9f735..6ad63b99c 100644 --- a/flutter/lib/desktop/widgets/scroll_wrapper.dart +++ b/flutter/lib/desktop/widgets/scroll_wrapper.dart @@ -13,7 +13,7 @@ class DesktopScrollWrapper extends StatelessWidget { Widget build(BuildContext context) { return ImprovedScrolling( scrollController: scrollController, - enableCustomMouseWheelScrolling: false, + enableCustomMouseWheelScrolling: true, customMouseWheelScrollConfig: const CustomMouseWheelScrollConfig( scrollAmountMultiplier: kDefaultScrollAmountMultiplier), child: child, From 0679d01a63cd9a4680534be65c8f4806a8a5a79f Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 19 Sep 2022 19:24:51 +0800 Subject: [PATCH 11/16] fix connection status style --- .../lib/desktop/pages/connection_page.dart | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index e857df271..c989badb8 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -94,8 +94,8 @@ class _ConnectionPageState extends State { ).marginSymmetric(horizontal: 22), ), const Divider(), - SizedBox(height: 50, child: Obx(() => buildStatus())) - .paddingSymmetric(horizontal: 12.0) + SizedBox(child: Obx(() => buildStatus())) + .paddingOnly(bottom: 12, top: 6), ]), ); } @@ -303,6 +303,8 @@ class _ConnectionPageState extends State { var svcIsUsingPublicServer = true.obs; Widget buildStatus() { + final fontSize = 14.0; + final textStyle = TextStyle(fontSize: fontSize); final light = Container( height: 8, width: 8, @@ -310,13 +312,13 @@ class _ConnectionPageState extends State { borderRadius: BorderRadius.circular(20), color: svcStopped.value ? Colors.redAccent : Colors.green, ), - ).paddingSymmetric(horizontal: 10.0); + ).paddingSymmetric(horizontal: 12.0); if (svcStopped.value) { return Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ light, - Text(translate("Service is not running")), + Text(translate("Service is not running"), style: textStyle), TextButton( onPressed: () async { bool checked = await bind.mainCheckSuperUserPermission(); @@ -324,19 +326,25 @@ class _ConnectionPageState extends State { bind.mainSetOption(key: "stop-service", value: ""); } }, - child: Text(translate("Start Service"))) + child: Text(translate("Start Service"), style: textStyle)) ], ); } else { if (svcStatusCode.value == 0) { return Row( crossAxisAlignment: CrossAxisAlignment.center, - children: [light, Text(translate("connecting_status"))], + children: [ + light, + Text(translate("connecting_status"), style: textStyle) + ], ); } else if (svcStatusCode.value == -1) { return Row( crossAxisAlignment: CrossAxisAlignment.center, - children: [light, Text(translate("not_ready_status"))], + children: [ + light, + Text(translate("not_ready_status"), style: textStyle) + ], ); } } @@ -344,13 +352,15 @@ class _ConnectionPageState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ light, - Text(translate('Ready')), + Text(translate('Ready'), style: textStyle), + Text(', ', style: textStyle), svcIsUsingPublicServer.value ? InkWell( onTap: onUsePublicServerGuide, child: Text( - ', ${translate('setup_server_tip')}', - style: TextStyle(decoration: TextDecoration.underline), + translate('setup_server_tip'), + style: TextStyle( + decoration: TextDecoration.underline, fontSize: fontSize), ), ) : Offstage() @@ -424,7 +434,7 @@ class _ConnectionPageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(translate("${model.abError}")), + Text(translate(model.abError)), TextButton( onPressed: () { setState(() {}); From 19586f28bd4cba89de12b053cada52e70ea9627b Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 19 Sep 2022 19:42:13 +0800 Subject: [PATCH 12/16] save peer_tab_index --- flutter/lib/desktop/pages/connection_page.dart | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index c989badb8..198f64bcc 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -768,20 +768,33 @@ class _PeerTabbedPage extends StatefulWidget { class _PeerTabbedPageState extends State<_PeerTabbedPage> with SingleTickerProviderStateMixin { - late PageController _pageController = PageController(); - RxInt _tabIndex = 0.obs; + late final PageController _pageController = PageController(); + final RxInt _tabIndex = 0.obs; @override void initState() { + () async { + await bind.mainGetLocalOption(key: 'peer_tab_index').then((value) { + if (value == '') return; + final tab = int.parse(value); + _tabIndex.value = tab; + _pageController.jumpToPage(tab); + }); + }(); super.initState(); } // hard code for now void _handleTabSelection(int index) { + if (index == _tabIndex.value) return; // reset search text peerSearchText.value = ""; peerSearchTextController.clear(); _tabIndex.value = index; + () async { + await bind.mainSetLocalOption( + key: 'peer_tab_index', value: index.toString()); + }(); _pageController.jumpToPage(index); switch (index) { case 0: From df5a2ab5569cae8ad9c8a29c49631f5dc96b5a5e Mon Sep 17 00:00:00 2001 From: Kingtous Date: Mon, 19 Sep 2022 21:09:54 +0800 Subject: [PATCH 13/16] opt: custom scroll for better scroll and add trackpad support --- flutter/lib/consts.dart | 4 +++- flutter/lib/desktop/pages/connection_page.dart | 4 +++- flutter/lib/desktop/widgets/peer_widget.dart | 2 +- flutter/lib/desktop/widgets/scroll_wrapper.dart | 6 +++++- flutter/pubspec.yaml | 5 ++++- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 3ed080206..e7c506ecc 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -16,7 +16,9 @@ const int kDesktopDefaultDisplayWidth = 1080; const int kDesktopDefaultDisplayHeight = 720; /// [kDefaultScrollAmountMultiplier] indicates how many rows can be scrolled after a minimum scroll action of mouse -const kDefaultScrollAmountMultiplier = 10.0; +const kDefaultScrollAmountMultiplier = 5.0; +const kDefaultScrollDuration = Duration(milliseconds: 50); +const kDefaultMouseWhellThrottleDuration = Duration(milliseconds: 50); const kFullScreenEdgeSize = 1.0; const kWindowEdgeSize = 4.0; diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index e857df271..3c7994861 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -852,7 +852,9 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage> Widget _createTabBarView() { return Expanded( child: PageView( - controller: _pageController, children: super.widget.children) + physics: NeverScrollableScrollPhysics(), + controller: _pageController, + children: super.widget.children) .marginSymmetric(vertical: 12)); } diff --git a/flutter/lib/desktop/widgets/peer_widget.dart b/flutter/lib/desktop/widgets/peer_widget.dart index 1b0626198..a7edc0b93 100644 --- a/flutter/lib/desktop/widgets/peer_widget.dart +++ b/flutter/lib/desktop/widgets/peer_widget.dart @@ -89,7 +89,7 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener { : DesktopScrollWrapper( scrollController: _scrollController, child: SingleChildScrollView( - physics: const NeverScrollableScrollPhysics(), + physics: NeverScrollableScrollPhysics(), controller: _scrollController, child: ObxValue((searchText) { return FutureBuilder>( diff --git a/flutter/lib/desktop/widgets/scroll_wrapper.dart b/flutter/lib/desktop/widgets/scroll_wrapper.dart index 6ad63b99c..aaa3aa403 100644 --- a/flutter/lib/desktop/widgets/scroll_wrapper.dart +++ b/flutter/lib/desktop/widgets/scroll_wrapper.dart @@ -14,7 +14,11 @@ class DesktopScrollWrapper extends StatelessWidget { return ImprovedScrolling( scrollController: scrollController, enableCustomMouseWheelScrolling: true, - customMouseWheelScrollConfig: const CustomMouseWheelScrollConfig( + customMouseWheelScrollConfig: CustomMouseWheelScrollConfig( + scrollDuration: kDefaultScrollDuration, + scrollCurve: Curves.linearToEaseOut, + mouseWheelTurnsThrottleTimeMs: + kDefaultMouseWhellThrottleDuration.inMilliseconds, scrollAmountMultiplier: kDefaultScrollAmountMultiplier), child: child, ); diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 9bc8816ef..696f2a5d2 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -80,7 +80,10 @@ dependencies: desktop_drop: ^0.3.3 scroll_pos: ^0.3.0 rxdart: ^0.27.5 - flutter_improved_scrolling: ^0.0.3 + flutter_improved_scrolling: + git: + url: https://github.com/Kingtous/flutter_improved_scrolling + ref: 62f09545149f320616467c306c8c5f71714a18e6 dev_dependencies: icons_launcher: ^2.0.4 From e5a292ef26af89ece90aa56a336f9610ed9e41f7 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Tue, 20 Sep 2022 10:25:18 +0800 Subject: [PATCH 14/16] opt: flutter_improved_scrolling doc & remove border --- flutter/lib/desktop/pages/desktop_tab_page.dart | 2 -- flutter/pubspec.yaml | 12 ++++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_tab_page.dart b/flutter/lib/desktop/pages/desktop_tab_page.dart index 58ed34947..2f24ddbde 100644 --- a/flutter/lib/desktop/pages/desktop_tab_page.dart +++ b/flutter/lib/desktop/pages/desktop_tab_page.dart @@ -38,8 +38,6 @@ class _DesktopTabPageState extends State { RxBool fullscreen = false.obs; Get.put(fullscreen, tag: 'fullscreen'); final tabWidget = Container( - decoration: BoxDecoration( - border: Border.all(color: MyTheme.color(context).border!)), child: Overlay(initialEntries: [ OverlayEntry(builder: (context) { gFFI.dialogManager.setOverlayState(Overlay.of(context)); diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 696f2a5d2..7eb074e4d 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -80,10 +80,14 @@ dependencies: desktop_drop: ^0.3.3 scroll_pos: ^0.3.0 rxdart: ^0.27.5 - flutter_improved_scrolling: - git: - url: https://github.com/Kingtous/flutter_improved_scrolling - ref: 62f09545149f320616467c306c8c5f71714a18e6 + flutter_improved_scrolling: ^0.0.3 + # currently, we use flutter 3.0.5 for windows build, latest for other builds. + # + # for flutter 3.0.5, please use official version(just comment code below). + # if build rustdesk by flutter >=3.3, please use our custom pub below (uncomment code below). + # git: + # url: https://github.com/Kingtous/flutter_improved_scrolling + # ref: 62f09545149f320616467c306c8c5f71714a18e6 dev_dependencies: icons_launcher: ^2.0.4 From 13fe2164d47cef8637524b168c2ebe270567cd60 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Tue, 20 Sep 2022 18:09:02 +0800 Subject: [PATCH 15/16] more style bug fix --- flutter/lib/consts.dart | 4 +- .../lib/desktop/pages/connection_page.dart | 82 ++++++++----------- src/lang/cn.rs | 2 +- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index e7c506ecc..55d13f10e 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -19,8 +19,8 @@ const int kDesktopDefaultDisplayHeight = 720; const kDefaultScrollAmountMultiplier = 5.0; const kDefaultScrollDuration = Duration(milliseconds: 50); const kDefaultMouseWhellThrottleDuration = Duration(milliseconds: 50); -const kFullScreenEdgeSize = 1.0; -const kWindowEdgeSize = 4.0; +const kFullScreenEdgeSize = 0.0; +const kWindowEdgeSize = 1.0; const kInvalidValueStr = "InvalidValueStr"; diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 05cb3858a..5c127354e 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -774,27 +774,31 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage> @override void initState() { () async { - await bind.mainGetLocalOption(key: 'peer_tab_index').then((value) { + await bind.mainGetLocalOption(key: 'peer-tab-index').then((value) { if (value == '') return; final tab = int.parse(value); _tabIndex.value = tab; _pageController.jumpToPage(tab); }); + await bind.mainGetLocalOption(key: 'peer-card-ui-type').then((value) { + if (value == '') return; + final tab = int.parse(value); + peerCardUiType.value = + tab == PeerUiType.list.index ? PeerUiType.list : PeerUiType.grid; + }); }(); super.initState(); } // hard code for now - void _handleTabSelection(int index) { + Future _handleTabSelection(int index) async { if (index == _tabIndex.value) return; // reset search text peerSearchText.value = ""; peerSearchTextController.clear(); _tabIndex.value = index; - () async { - await bind.mainSetLocalOption( - key: 'peer_tab_index', value: index.toString()); - }(); + await bind.mainSetLocalOption( + key: 'peer-tab-index', value: index.toString()); _pageController.jumpToPage(index); switch (index) { case 0: @@ -845,7 +849,7 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage> shrinkWrap: true, controller: ScrollController(), children: super.widget.tabs.asMap().entries.map((t) { - return Obx(() => GestureDetector( + return Obx(() => InkWell( child: Container( padding: EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( @@ -867,7 +871,7 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage> : MyTheme.color(context).lightText), ), )), - onTap: () => _handleTabSelection(t.key), + onTap: () async => await _handleTabSelection(t.key), )); }).toList()); } @@ -959,44 +963,30 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage> _createPeerViewTypeSwitch(BuildContext context) { final activeDeco = BoxDecoration(color: MyTheme.color(context).bg); return Row( - children: [ - Obx( - () => Container( - padding: EdgeInsets.all(4.0), - decoration: - peerCardUiType.value == PeerUiType.grid ? activeDeco : null, - child: InkWell( - onTap: () { - peerCardUiType.value = PeerUiType.grid; - }, - child: Icon( - Icons.grid_view_rounded, - size: 18, - color: peerCardUiType.value == PeerUiType.grid - ? MyTheme.color(context).text - : MyTheme.color(context).lightText, - )), - ), - ), - Obx( - () => Container( - padding: EdgeInsets.all(4.0), - decoration: - peerCardUiType.value == PeerUiType.list ? activeDeco : null, - child: InkWell( - onTap: () { - peerCardUiType.value = PeerUiType.list; - }, - child: Icon( - Icons.list, - size: 18, - color: peerCardUiType.value == PeerUiType.list - ? MyTheme.color(context).text - : MyTheme.color(context).lightText, - )), - ), - ), - ], + children: [PeerUiType.grid, PeerUiType.list] + .map((type) => Obx( + () => Container( + padding: EdgeInsets.all(4.0), + decoration: peerCardUiType.value == type ? activeDeco : null, + child: InkWell( + onTap: () async { + await bind.mainSetLocalOption( + key: 'peer-card-ui-type', + value: type.index.toString()); + peerCardUiType.value = type; + }, + child: Icon( + type == PeerUiType.grid + ? Icons.grid_view_rounded + : Icons.list, + size: 18, + color: peerCardUiType.value == type + ? MyTheme.color(context).text + : MyTheme.color(context).lightText, + )), + ), + )) + .toList(), ); } } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 920013be3..664d6f05b 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -189,7 +189,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("x11 expected", "请切换到 x11"), ("Port", "端口"), ("Settings", "设置"), - ("Username", " 用户名"), + ("Username", "用户名"), ("Invalid port", "无效端口"), ("Closed manually by the peer", "被对方手动关闭"), ("Enable remote configuration modification", "允许远程修改配置"), From 3101c4e11982bb3abd254403562d62f0d9b2d4fb Mon Sep 17 00:00:00 2001 From: rustdesk Date: Tue, 20 Sep 2022 19:31:32 +0800 Subject: [PATCH 16/16] fix formatId, right panel button style, default windows size (windows, Linux, no idea about Mac, need to check with xcode) --- flutter/lib/common.dart | 6 ++- .../lib/common/formatter/id_formatter.dart | 1 + .../lib/desktop/pages/connection_page.dart | 53 ++++++++++--------- .../lib/desktop/pages/desktop_home_page.dart | 9 ++-- flutter/linux/my_application.cc | 2 +- flutter/windows/runner/main.cpp | 2 +- 6 files changed, 40 insertions(+), 33 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index dfe96c903..f268286a9 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -760,8 +760,9 @@ class PermissionManager { if (isDesktop) { return Future.value(true); } - if (!permissions.contains(type)) + if (!permissions.contains(type)) { return Future.error("Wrong permission!$type"); + } return gFFI.invokeMethod("check_permission", type); } @@ -769,8 +770,9 @@ class PermissionManager { if (isDesktop) { return Future.value(true); } - if (!permissions.contains(type)) + if (!permissions.contains(type)) { return Future.error("Wrong permission!$type"); + } gFFI.invokeMethod("request_permission", type); if (type == "ignore_battery_optimizations") { diff --git a/flutter/lib/common/formatter/id_formatter.dart b/flutter/lib/common/formatter/id_formatter.dart index c7ce14da4..a9e4893a6 100644 --- a/flutter/lib/common/formatter/id_formatter.dart +++ b/flutter/lib/common/formatter/id_formatter.dart @@ -33,6 +33,7 @@ class IDTextInputFormatter extends TextInputFormatter { String formatID(String id) { String id2 = id.replaceAll(' ', ''); + if (int.tryParse(id2) == null) return id; String newID = ''; if (id2.length <= 3) { newID = id2; diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 5c127354e..f7fdd3e5f 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -215,7 +215,7 @@ class _ConnectionPageState extends State { onConnect(isFileTransfer: true); }, child: Container( - height: 24, + height: 27, alignment: Alignment.center, decoration: BoxDecoration( color: ftPressed.value @@ -252,31 +252,36 @@ class _ConnectionPageState extends State { onTapCancel: () => connPressed.value = false, onHover: (value) => connHover.value = value, onTap: onConnect, - child: Container( - height: 24, - decoration: BoxDecoration( - color: connPressed.value - ? MyTheme.accent - : MyTheme.button, - border: Border.all( - color: connPressed.value - ? MyTheme.accent - : connHover.value - ? MyTheme.hoverBorder - : MyTheme.button, + child: ConstrainedBox( + constraints: BoxConstraints( + minWidth: 80.0, ), - borderRadius: BorderRadius.circular(5), - ), - child: Center( - child: Text( - translate( - "Connect", + child: Container( + height: 27, + decoration: BoxDecoration( + color: connPressed.value + ? MyTheme.accent + : MyTheme.button, + border: Border.all( + color: connPressed.value + ? MyTheme.accent + : connHover.value + ? MyTheme.hoverBorder + : MyTheme.button, + ), + borderRadius: BorderRadius.circular(5), ), - style: TextStyle( - fontSize: 12, color: MyTheme.color(context).bg), - ), - ).marginSymmetric(horizontal: 12), - ), + child: Center( + child: Text( + translate( + "Connect", + ), + style: TextStyle( + fontSize: 12, + color: MyTheme.color(context).bg), + ), + ).marginSymmetric(horizontal: 12), + )), ), ), ], diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index b574900fe..edae7deeb 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -290,7 +290,7 @@ class _DesktopHomePageState extends State @override void onTrayMenuItemClick(MenuItem menuItem) { - print('click ${menuItem.key}'); + debugPrint('click ${menuItem.key}'); switch (menuItem.key) { case "quit": exit(0); @@ -308,8 +308,8 @@ class _DesktopHomePageState extends State trayManager.addListener(this); windowManager.addListener(this); rustDeskWinManager.setMethodHandler((call, fromWindowId) async { - print( - "call ${call.method} with args ${call.arguments} from window ${fromWindowId}"); + debugPrint( + "call ${call.method} with args ${call.arguments} from window $fromWindowId"); if (call.method == "main_window_on_top") { window_on_top(null); } @@ -373,8 +373,7 @@ Future loginDialog() async { debugPrint("$resp"); completer.complete(true); } catch (err) { - // ignore: avoid_print - print(err.toString()); + debugPrint(err.toString()); cancel(); return; } diff --git a/flutter/linux/my_application.cc b/flutter/linux/my_application.cc index deea3f549..6d101687b 100644 --- a/flutter/linux/my_application.cc +++ b/flutter/linux/my_application.cc @@ -51,7 +51,7 @@ static void my_application_activate(GApplication* application) { // auto bdw = bitsdojo_window_from(window); // <--- add this line // bdw->setCustomFrame(true); // <-- add this line - gtk_window_set_default_size(window, 1280, 720); // <-- comment this line + gtk_window_set_default_size(window, 800, 600); // <-- comment this line gtk_widget_show(GTK_WIDGET(window)); g_autoptr(FlDartProject) project = fl_dart_project_new(); diff --git a/flutter/windows/runner/main.cpp b/flutter/windows/runner/main.cpp index f84fc1861..0724ace8a 100644 --- a/flutter/windows/runner/main.cpp +++ b/flutter/windows/runner/main.cpp @@ -52,7 +52,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(project); Win32Window::Point origin(10, 10); - Win32Window::Size size(1280, 720); + Win32Window::Size size(800, 600); if (!window.CreateAndShow(L"flutter_hbb", origin, size)) { return EXIT_FAILURE;