From a04a36d9b007dd8aec47fdb0df165f141529bbcb Mon Sep 17 00:00:00 2001 From: grummbeer Date: Sun, 4 Jun 2023 19:59:09 +0200 Subject: [PATCH 01/11] Page Install. Use path.join for install_path instead of string concat --- flutter/lib/desktop/pages/install_page.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index 979364bbf..babf4401d 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -7,6 +7,7 @@ import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; import 'package:flutter_hbb/models/platform_model.dart'; import 'package:flutter_hbb/models/state_model.dart'; import 'package:get/get.dart'; +import 'package:path/path.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:window_manager/window_manager.dart'; @@ -312,8 +313,7 @@ class _InstallPageBodyState extends State<_InstallPageBody> String? install_path = await FilePicker.platform .getDirectoryPath(initialDirectory: controller.text); if (install_path != null) { - install_path = '$install_path\\${await bind.mainGetAppName()}'; - controller.text = install_path; + controller.text = join(install_path, await bind.mainGetAppName()); } } } From ed1535ac7b6a6ae73cc379b87f7c166ed9bac478 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Mon, 5 Jun 2023 08:55:00 +0200 Subject: [PATCH 02/11] Page Install. Tooltip, icon, https for outgoing url. --- flutter/lib/desktop/pages/install_page.dart | 22 +++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index babf4401d..1a9df8412 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -206,14 +206,20 @@ class _InstallPageBodyState extends State<_InstallPageBody> ), ), ), - GestureDetector( - onTap: () => launchUrlString('http://rustdesk.com/privacy'), - child: Row( - children: [ - Text(translate('End-user license agreement'), - style: const TextStyle( - decoration: TextDecoration.underline)) - ], + InkWell( + hoverColor: Colors.transparent, + onTap: () => launchUrlString('https://rustdesk.com/privacy'), + child: Tooltip( + message: 'https://rustdesk.com/privacy', + child: Row(children: [ + Icon(Icons.launch_outlined, size: 16) + .marginOnly(right: 5), + Text( + translate('End-user license agreement'), + style: const TextStyle( + decoration: TextDecoration.underline), + ) + ]), )).marginOnly(top: 2 * em), Row(children: [Text(translate('agreement_tip'))]) .marginOnly(top: em), From 88ce6e74a86c38ccd83d9c728eda484335392203 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Mon, 5 Jun 2023 10:23:57 +0200 Subject: [PATCH 03/11] Page Install. Add icons to buttons on confirmation dialog. --- flutter/lib/desktop/pages/install_page.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index 1a9df8412..74f0e44dc 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -287,11 +287,13 @@ class _InstallPageBodyState extends State<_InstallPageBody> final btns = [ dialogButton( 'Cancel', + icon: Icon(Icons.close_rounded), onPressed: () => gFFI.dialogManager.dismissByTag(tag), isOutline: true, ), dialogButton( 'OK', + icon: Icon(Icons.done_rounded), onPressed: () { gFFI.dialogManager.dismissByTag(tag); do_install(); From ba12c50dc124363c55238a73a643c584ecf0f7b0 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Mon, 5 Jun 2023 12:18:19 +0200 Subject: [PATCH 04/11] Page Install. Checkboxes. Fix overflow, alignment. --- flutter/lib/desktop/pages/install_page.dart | 53 ++++++++++----------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index 74f0e44dc..e17336fb8 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -149,62 +149,59 @@ class _InstallPageBodyState extends State<_InstallPageBody> .marginOnly(left: em)) ], ).marginSymmetric(vertical: 2 * em), - TextButton( - onPressed: () => startmenu.value = !startmenu.value, + InkWell( + borderRadius: BorderRadius.circular(6), + onTap: () => startmenu.value = !startmenu.value, child: Row( children: [ Obx(() => Checkbox( + visualDensity: + VisualDensity(horizontal: -4, vertical: -4), value: startmenu.value, onChanged: (b) { if (b != null) startmenu.value = b; - })), - RichText( - text: TextSpan( - text: translate('Create start menu shortcuts'), - style: DefaultTextStyle.of(context).style, - ), - ), + }).marginOnly(right: 8)), + Expanded( + child: Text(translate('Create start menu shortcuts'))), ], ), - ), - TextButton( - onPressed: () => desktopicon.value = !desktopicon.value, + ).marginOnly(bottom: 7), + InkWell( + borderRadius: BorderRadius.circular(6), + onTap: () => desktopicon.value = !desktopicon.value, child: Row( children: [ Obx(() => Checkbox( + visualDensity: + VisualDensity(horizontal: -4, vertical: -4), value: desktopicon.value, onChanged: (b) { if (b != null) desktopicon.value = b; - })), - RichText( - text: TextSpan( - text: translate('Create desktop icon'), - style: DefaultTextStyle.of(context).style, - ), - ), + }).marginOnly(right: 8)), + Expanded(child: Text(translate('Create desktop icon'))), ], ), ), Offstage( offstage: !Platform.isWindows, - child: TextButton( - onPressed: () => driverCert.value = !driverCert.value, + child: InkWell( + borderRadius: BorderRadius.circular(6), + onTap: () => driverCert.value = !driverCert.value, child: Row( children: [ Obx(() => Checkbox( + visualDensity: + VisualDensity(horizontal: -4, vertical: -4), value: driverCert.value, onChanged: (b) { if (b != null) driverCert.value = b; - })), - RichText( - text: TextSpan( - text: translate('idd_driver_tip'), - style: DefaultTextStyle.of(context).style, - ), + }).marginOnly(right: 8)), + Expanded( + child: Text(translate('idd_driver_tip')), ), ], ), - ), + ).marginOnly(top: 7), ), InkWell( hoverColor: Colors.transparent, From a029bd9a928345e27881d2d80bb60d7f9aeaf113 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Mon, 5 Jun 2023 13:03:58 +0200 Subject: [PATCH 05/11] Page Install. Reset styles for input field. --- flutter/lib/desktop/pages/install_page.dart | 41 ++++++++------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index e17336fb8..4e2da3f87 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -101,10 +101,6 @@ class _InstallPageBodyState extends State<_InstallPageBody> shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(button_radius)), )); - final inputBorder = OutlineInputBorder( - borderRadius: BorderRadius.zero, - borderSide: - BorderSide(color: isDarkTheme ? Colors.white70 : Colors.black12)); final textColor = isDarkTheme ? null : Colors.black87; final dividerColor = isDarkTheme ? Colors.white70 : Colors.black87; return Scaffold( @@ -123,30 +119,23 @@ class _InstallPageBodyState extends State<_InstallPageBody> ), Row( children: [ - Text('${translate('Installation Path')}: '), + Text('${translate('Installation Path')}:') + .marginOnly(right: 10), Expanded( - child: TextField( - controller: controller, - readOnly: true, - style: TextStyle( - fontSize: 1.5 * em, fontWeight: FontWeight.w400), - decoration: InputDecoration( - isDense: true, - contentPadding: EdgeInsets.all(0.75 * em), - enabledBorder: inputBorder, - border: inputBorder, - focusedBorder: inputBorder, - constraints: BoxConstraints(maxHeight: 3 * em), - ), - )), + child: TextField( + controller: controller, + readOnly: true, + decoration: InputDecoration( + contentPadding: EdgeInsets.all(0.75 * em), + ), + ).marginOnly(right: 10), + ), Obx(() => OutlinedButton( - onPressed: - btnEnabled.value ? selectInstallPath : null, - style: buttonStyle, - child: Text(translate('Change Path'), - style: TextStyle( - color: textColor, fontSize: btnFontSize))) - .marginOnly(left: em)) + onPressed: btnEnabled.value ? selectInstallPath : null, + style: buttonStyle, + child: Text(translate('Change Path'), + style: TextStyle( + color: textColor, fontSize: btnFontSize)))) ], ).marginSymmetric(vertical: 2 * em), InkWell( From d90201f874345f737bef08966d50fedf374f7be6 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Mon, 5 Jun 2023 16:56:30 +0200 Subject: [PATCH 06/11] Page Install. Reset styles for buttons. --- flutter/lib/desktop/pages/install_page.dart | 96 ++++++++++----------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index 4e2da3f87..bea759f6f 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -70,6 +70,12 @@ class _InstallPageBodyState extends State<_InstallPageBody> final RxBool showProgress = false.obs; final RxBool btnEnabled = true.obs; + // todo move to theme. + final buttonStyle = OutlinedButton.styleFrom( + textStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.normal), + padding: EdgeInsets.symmetric(vertical: 15, horizontal: 12), + ); + @override void initState() { windowManager.addListener(this); @@ -94,14 +100,7 @@ class _InstallPageBodyState extends State<_InstallPageBody> @override Widget build(BuildContext context) { final double em = 13; - final btnFontSize = 0.9 * em; - final double button_radius = 6; final isDarkTheme = MyTheme.currentThemeMode() == ThemeMode.dark; - final buttonStyle = OutlinedButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(button_radius)), - )); - final textColor = isDarkTheme ? null : Colors.black87; final dividerColor = isDarkTheme ? Colors.white70 : Colors.black87; return Scaffold( backgroundColor: null, @@ -130,12 +129,14 @@ class _InstallPageBodyState extends State<_InstallPageBody> ), ).marginOnly(right: 10), ), - Obx(() => OutlinedButton( + Obx( + () => OutlinedButton.icon( + icon: Icon(Icons.folder_outlined, size: 16), onPressed: btnEnabled.value ? selectInstallPath : null, style: buttonStyle, - child: Text(translate('Change Path'), - style: TextStyle( - color: textColor, fontSize: btnFontSize)))) + label: Text(translate('Change Path')), + ), + ) ], ).marginSymmetric(vertical: 2 * em), InkWell( @@ -217,38 +218,35 @@ class _InstallPageBodyState extends State<_InstallPageBody> offstage: !showProgress.value, child: LinearProgressIndicator(), ))), - Obx(() => OutlinedButton( - onPressed: btnEnabled.value - ? () => windowManager.close() - : null, - style: buttonStyle, - child: Text(translate('Cancel'), - style: TextStyle( - color: textColor, fontSize: btnFontSize))) - .marginSymmetric(horizontal: 2 * em)), - Obx(() => ElevatedButton( + Obx( + () => OutlinedButton.icon( + icon: Icon(Icons.close_rounded, size: 16), + label: Text(translate('Cancel')), + onPressed: + btnEnabled.value ? () => windowManager.close() : null, + style: buttonStyle, + ).marginOnly(right: 10), + ), + Obx( + () => ElevatedButton.icon( + icon: Icon(Icons.done_rounded, size: 16), + label: Text(translate('Accept and Install')), onPressed: btnEnabled.value ? install : null, - style: ElevatedButton.styleFrom( - primary: MyTheme.button, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(button_radius)), - )), - child: Text( - translate('Accept and Install'), - style: TextStyle(fontSize: btnFontSize), - ))), + style: buttonStyle, + ), + ), Offstage( offstage: bind.installShowRunWithoutInstall(), - child: Obx(() => OutlinedButton( - onPressed: btnEnabled.value - ? () => bind.installRunWithoutInstall() - : null, - style: buttonStyle, - child: Text(translate('Run without install'), - style: TextStyle( - color: textColor, fontSize: btnFontSize))) - .marginOnly(left: 2 * em)), + child: Obx( + () => OutlinedButton.icon( + icon: Icon(Icons.screen_share_outlined, size: 16), + label: Text(translate('Run without install')), + onPressed: btnEnabled.value + ? () => bind.installRunWithoutInstall() + : null, + style: buttonStyle, + ).marginOnly(left: 10), + ), ), ], ) @@ -271,21 +269,21 @@ class _InstallPageBodyState extends State<_InstallPageBody> if (driverCert.isTrue) { final tag = 'install-info-install-cert-confirm'; final btns = [ - dialogButton( - 'Cancel', - icon: Icon(Icons.close_rounded), + OutlinedButton.icon( + icon: Icon(Icons.close_rounded, size: 16), + label: Text(translate('Cancel')), onPressed: () => gFFI.dialogManager.dismissByTag(tag), - isOutline: true, + style: buttonStyle, ), - dialogButton( - 'OK', - icon: Icon(Icons.done_rounded), + ElevatedButton.icon( + icon: Icon(Icons.done_rounded, size: 16), + label: Text(translate('OK')), onPressed: () { gFFI.dialogManager.dismissByTag(tag); do_install(); }, - isOutline: false, - ), + style: buttonStyle, + ) ]; gFFI.dialogManager.show( (setState, close, context) => CustomAlertDialog( From a6f27e0c828e2fa126cfc979fcf86a6a0e3a18c5 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Mon, 5 Jun 2023 17:07:51 +0200 Subject: [PATCH 07/11] Page Install. Adjust window inner padding. --- flutter/lib/desktop/pages/install_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index bea759f6f..e6a158e0f 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -251,7 +251,7 @@ class _InstallPageBodyState extends State<_InstallPageBody> ], ) ], - ).paddingSymmetric(horizontal: 8 * em, vertical: 2 * em), + ).paddingSymmetric(horizontal: 4 * em, vertical: 3 * em), )); } From ae9c0df8184df36b8972d81699fa315875c3dd49 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Mon, 5 Jun 2023 17:29:45 +0200 Subject: [PATCH 08/11] Page Install. Reset styles for headline to theme defaults. --- flutter/lib/desktop/pages/install_page.dart | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index e6a158e0f..8f3c36dab 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -106,16 +106,10 @@ class _InstallPageBodyState extends State<_InstallPageBody> backgroundColor: null, body: SingleChildScrollView( child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Text( - translate('Installation'), - style: TextStyle( - fontSize: 2 * em, fontWeight: FontWeight.w500), - ), - ], - ), + Text(translate('Installation'), + style: Theme.of(context).textTheme.headlineMedium), Row( children: [ Text('${translate('Installation Path')}:') From 5b74e30b239a0885a91513fafe85281b5f59b167 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Tue, 6 Jun 2023 11:01:22 +0200 Subject: [PATCH 09/11] Page Install. ProgressIndiactor space to buttons. --- flutter/lib/desktop/pages/install_page.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index 8f3c36dab..4dda8cda8 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -208,10 +208,12 @@ class _InstallPageBodyState extends State<_InstallPageBody> Row( children: [ Expanded( - child: Obx(() => Offstage( - offstage: !showProgress.value, - child: LinearProgressIndicator(), - ))), + child: Obx(() => Offstage( + offstage: !showProgress.value, + child: + LinearProgressIndicator().marginOnly(right: 10), + )), + ), Obx( () => OutlinedButton.icon( icon: Icon(Icons.close_rounded, size: 16), From c78e7ec49f667560118a5c21f803349668c603e7 Mon Sep 17 00:00:00 2001 From: grummbeer Date: Tue, 6 Jun 2023 11:28:20 +0200 Subject: [PATCH 10/11] Page Install. Make agreement area more visible --- flutter/lib/desktop/pages/install_page.dart | 56 ++++++++++++++------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index 4dda8cda8..707f5a8fb 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -101,7 +101,6 @@ class _InstallPageBodyState extends State<_InstallPageBody> Widget build(BuildContext context) { final double em = 13; final isDarkTheme = MyTheme.currentThemeMode() == ThemeMode.dark; - final dividerColor = isDarkTheme ? Colors.white70 : Colors.black87; return Scaffold( backgroundColor: null, body: SingleChildScrollView( @@ -187,24 +186,45 @@ class _InstallPageBodyState extends State<_InstallPageBody> ), ).marginOnly(top: 7), ), - InkWell( - hoverColor: Colors.transparent, - onTap: () => launchUrlString('https://rustdesk.com/privacy'), - child: Tooltip( - message: 'https://rustdesk.com/privacy', - child: Row(children: [ - Icon(Icons.launch_outlined, size: 16) - .marginOnly(right: 5), - Text( - translate('End-user license agreement'), - style: const TextStyle( - decoration: TextDecoration.underline), + Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + color: isDarkTheme + ? Color.fromARGB(135, 87, 87, 90) + : Colors.grey[100], + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey), + ), + child: Row( + children: [ + Icon(Icons.info_outline_rounded, size: 32) + .marginOnly(right: 16), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(translate('agreement_tip')) + .marginOnly(bottom: em), + InkWell( + hoverColor: Colors.transparent, + onTap: () => + launchUrlString('https://rustdesk.com/privacy'), + child: Tooltip( + message: 'https://rustdesk.com/privacy', + child: Row(children: [ + Icon(Icons.launch_outlined, size: 16) + .marginOnly(right: 5), + Text( + translate('End-user license agreement'), + style: const TextStyle( + decoration: TextDecoration.underline), + ) + ]), + ), + ), + ], ) - ]), - )).marginOnly(top: 2 * em), - Row(children: [Text(translate('agreement_tip'))]) - .marginOnly(top: em), - Divider(color: dividerColor).marginSymmetric(vertical: 0.5 * em), + ], + )).marginSymmetric(vertical: 2 * em), Row( children: [ Expanded( From 67ad5e3e4016c9e2d79e2371c251901c4183103d Mon Sep 17 00:00:00 2001 From: grummbeer Date: Tue, 6 Jun 2023 13:38:29 +0200 Subject: [PATCH 11/11] Page Install. Disable checkboxes when installation has been started. --- flutter/lib/desktop/pages/install_page.dart | 80 ++++++++------------- 1 file changed, 28 insertions(+), 52 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index 707f5a8fb..74452c7ee 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -97,6 +97,29 @@ class _InstallPageBodyState extends State<_InstallPageBody> windowManager.close(); } + InkWell Option(RxBool option, {String label = ''}) { + return InkWell( + // todo mouseCursor: "SystemMouseCursors.forbidden" or no cursor on btnEnabled == false + borderRadius: BorderRadius.circular(6), + onTap: () => btnEnabled.value ? option.value = !option.value : null, + child: Row( + children: [ + Obx( + () => Checkbox( + visualDensity: VisualDensity(horizontal: -4, vertical: -4), + value: option.value, + onChanged: (v) => + btnEnabled.value ? option.value = !option.value : null, + ).marginOnly(right: 8), + ), + Expanded( + child: Text(translate(label)), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { final double em = 13; @@ -132,60 +155,13 @@ class _InstallPageBodyState extends State<_InstallPageBody> ) ], ).marginSymmetric(vertical: 2 * em), - InkWell( - borderRadius: BorderRadius.circular(6), - onTap: () => startmenu.value = !startmenu.value, - child: Row( - children: [ - Obx(() => Checkbox( - visualDensity: - VisualDensity(horizontal: -4, vertical: -4), - value: startmenu.value, - onChanged: (b) { - if (b != null) startmenu.value = b; - }).marginOnly(right: 8)), - Expanded( - child: Text(translate('Create start menu shortcuts'))), - ], - ), - ).marginOnly(bottom: 7), - InkWell( - borderRadius: BorderRadius.circular(6), - onTap: () => desktopicon.value = !desktopicon.value, - child: Row( - children: [ - Obx(() => Checkbox( - visualDensity: - VisualDensity(horizontal: -4, vertical: -4), - value: desktopicon.value, - onChanged: (b) { - if (b != null) desktopicon.value = b; - }).marginOnly(right: 8)), - Expanded(child: Text(translate('Create desktop icon'))), - ], - ), - ), + Option(startmenu, label: 'Create start menu shortcuts') + .marginOnly(bottom: 7), + Option(desktopicon, label: 'Create desktop icon'), Offstage( offstage: !Platform.isWindows, - child: InkWell( - borderRadius: BorderRadius.circular(6), - onTap: () => driverCert.value = !driverCert.value, - child: Row( - children: [ - Obx(() => Checkbox( - visualDensity: - VisualDensity(horizontal: -4, vertical: -4), - value: driverCert.value, - onChanged: (b) { - if (b != null) driverCert.value = b; - }).marginOnly(right: 8)), - Expanded( - child: Text(translate('idd_driver_tip')), - ), - ], - ), - ).marginOnly(top: 7), - ), + child: Option(driverCert, label: 'idd_driver_tip'), + ).marginOnly(top: 7), Container( padding: EdgeInsets.all(12), decoration: BoxDecoration(