From ec4a95f906bbb8ece21e429fc66893ed01092893 Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Thu, 18 May 2023 11:41:16 +0200 Subject: [PATCH 01/11] replaced buttons with switches --- flutter/lib/consts.dart | 3 +- flutter/lib/desktop/pages/server_page.dart | 38 +++++++++++----------- flutter/lib/main.dart | 10 +++--- flutter/lib/models/chat_model.dart | 5 +-- flutter/test/cm_test.dart | 6 ++-- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 827fd3b3f..1facf4e4b 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -76,7 +76,8 @@ extension StringExtension on String { String get nonBreaking => replaceAll(' ', String.fromCharCode($nbsp)); } -const Size kConnectionManagerWindowSize = Size(300, 400); +const Size kConnectionManagerWindowSizeClosedChat = Size(300, 500); +const Size kConnectionManagerWindowSizeOpenChat = Size(600, 500); // Tabbar transition duration, now we remove the duration const Duration kTabTransitionDuration = Duration.zero; const double kEmptyMarginTop = 50; diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index 45591b79b..ff35fa69f 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -408,17 +408,12 @@ class _PrivilegeBoard extends StatefulWidget { class _PrivilegeBoardState extends State<_PrivilegeBoard> { late final client = widget.client; - Widget buildPermissionIcon( - bool enabled, ImageProvider icon, Function(bool)? onTap, String tooltip) { - return Tooltip( - message: tooltip, - child: Ink( - decoration: - BoxDecoration(color: enabled ? MyTheme.accent80 : Colors.grey), - padding: EdgeInsets.all(4.0), - child: InkWell( - onTap: () => - checkClickTime(widget.client.id, () => onTap?.call(!enabled)), + Widget buildPermissionTile(bool enabled, ImageProvider icon, + Function(bool)? onTap, String tooltipText) { + return Row( + children: [ + Tooltip( + message: tooltipText, child: Image( image: icon, width: 50, @@ -426,7 +421,12 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { fit: BoxFit.scaleDown, ), ), - ).marginSymmetric(horizontal: 4.0), + Switch( + value: enabled, + onChanged: (v) => + checkClickTime(widget.client.id, () => onTap?.call(v)), + ), + ], ); } @@ -445,44 +445,44 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { height: 8.0, ), FittedBox( - child: Row( + child: Column( children: [ - buildPermissionIcon(client.keyboard, iconKeyboard, (enabled) { + buildPermissionTile(client.keyboard, iconKeyboard, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "keyboard", enabled: enabled); setState(() { client.keyboard = enabled; }); }, translate('Allow using keyboard and mouse')), - buildPermissionIcon(client.clipboard, iconClipboard, (enabled) { + buildPermissionTile(client.clipboard, iconClipboard, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "clipboard", enabled: enabled); setState(() { client.clipboard = enabled; }); }, translate('Allow using clipboard')), - buildPermissionIcon(client.audio, iconAudio, (enabled) { + buildPermissionTile(client.audio, iconAudio, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "audio", enabled: enabled); setState(() { client.audio = enabled; }); }, translate('Allow hearing sound')), - buildPermissionIcon(client.file, iconFile, (enabled) { + buildPermissionTile(client.file, iconFile, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "file", enabled: enabled); setState(() { client.file = enabled; }); }, translate('Allow file copy and paste')), - buildPermissionIcon(client.restart, iconRestart, (enabled) { + buildPermissionTile(client.restart, iconRestart, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "restart", enabled: enabled); setState(() { client.restart = enabled; }); }, translate('Allow remote restart')), - buildPermissionIcon(client.recording, iconRecording, (enabled) { + buildPermissionTile(client.recording, iconRecording, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "recording", enabled: enabled); setState(() { diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index 318f9c2cc..3dca92a2e 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -233,21 +233,21 @@ void runConnectionManagerScreen(bool hide) async { } void showCmWindow() { - WindowOptions windowOptions = - getHiddenTitleBarWindowOptions(size: kConnectionManagerWindowSize); + WindowOptions windowOptions = getHiddenTitleBarWindowOptions( + size: kConnectionManagerWindowSizeClosedChat); windowManager.waitUntilReadyToShow(windowOptions, () async { bind.mainHideDocker(); await windowManager.show(); await Future.wait([windowManager.focus(), windowManager.setOpacity(1)]); // ensure initial window size to be changed await windowManager.setSizeAlignment( - kConnectionManagerWindowSize, Alignment.topRight); + kConnectionManagerWindowSizeClosedChat, Alignment.topRight); }); } void hideCmWindow() { - WindowOptions windowOptions = - getHiddenTitleBarWindowOptions(size: kConnectionManagerWindowSize); + WindowOptions windowOptions = getHiddenTitleBarWindowOptions( + size: kConnectionManagerWindowSizeClosedChat); windowManager.setOpacity(0); windowManager.waitUntilReadyToShow(windowOptions, () async { bind.mainHideDocker(); diff --git a/flutter/lib/models/chat_model.dart b/flutter/lib/models/chat_model.dart index 9db5a1571..99ffcd220 100644 --- a/flutter/lib/models/chat_model.dart +++ b/flutter/lib/models/chat_model.dart @@ -203,11 +203,12 @@ class ChatModel with ChangeNotifier { notifyListeners(); await windowManager.show(); await windowManager.setSizeAlignment( - kConnectionManagerWindowSize, Alignment.topRight); + kConnectionManagerWindowSizeClosedChat, Alignment.topRight); } else { requestChatInputFocus(); await windowManager.show(); - await windowManager.setSizeAlignment(Size(600, 400), Alignment.topRight); + await windowManager.setSizeAlignment( + kConnectionManagerWindowSizeOpenChat, Alignment.topRight); _isShowCMChatPage = !_isShowCMChatPage; notifyListeners(); } diff --git a/flutter/test/cm_test.dart b/flutter/test/cm_test.dart index 2c037c7b0..fca9d8cee 100644 --- a/flutter/test/cm_test.dart +++ b/flutter/test/cm_test.dart @@ -45,12 +45,12 @@ void main(List args) async { ], supportedLocales: supportedLocales, home: const DesktopServerPage())); - WindowOptions windowOptions = - getHiddenTitleBarWindowOptions(size: kConnectionManagerWindowSize); + WindowOptions windowOptions = getHiddenTitleBarWindowOptions( + size: kConnectionManagerWindowSizeClosedChat); windowManager.waitUntilReadyToShow(windowOptions, () async { await windowManager.show(); // ensure initial window size to be changed - await windowManager.setSize(kConnectionManagerWindowSize); + await windowManager.setSize(kConnectionManagerWindowSizeClosedChat); await Future.wait([ windowManager.setAlignment(Alignment.topRight), windowManager.focus(), From 301faf43870399d2df15627444949a3ba03a5266 Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Thu, 18 May 2023 22:10:49 +0200 Subject: [PATCH 02/11] added new icons --- flutter/assets/audio.svg | 3 + flutter/assets/clipboard.svg | 3 + flutter/assets/restart.svg | 3 + flutter/lib/common.dart | 13 -- flutter/lib/desktop/pages/server_page.dart | 220 ++++++++++++++------- 5 files changed, 154 insertions(+), 88 deletions(-) create mode 100644 flutter/assets/audio.svg create mode 100644 flutter/assets/clipboard.svg create mode 100644 flutter/assets/restart.svg diff --git a/flutter/assets/audio.svg b/flutter/assets/audio.svg new file mode 100644 index 000000000..baf0972db --- /dev/null +++ b/flutter/assets/audio.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/flutter/assets/clipboard.svg b/flutter/assets/clipboard.svg new file mode 100644 index 000000000..ff3158752 --- /dev/null +++ b/flutter/assets/clipboard.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/flutter/assets/restart.svg b/flutter/assets/restart.svg new file mode 100644 index 000000000..bf74398a8 --- /dev/null +++ b/flutter/assets/restart.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 01610527b..107221d32 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -68,19 +68,6 @@ typedef F = String Function(String); typedef FMethod = String Function(String, dynamic); typedef StreamEventHandler = Future Function(Map); - -final iconKeyboard = MemoryImage(Uint8List.fromList(base64Decode( - "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAgVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9d3yJTAAAAKnRSTlMA0Gd/0y8ILZgbJffDPUwV2nvzt+TMqZxyU7CMb1pYQyzsvKunkXE4AwJnNC24AAAA+0lEQVQ4y83O2U7DMBCF4ZMxk9rZk26kpQs7nPd/QJy4EiLbLf01N5Y/2YP/qxDFQvGB5NPC/ZpVnfJx4b5xyGfF95rkHvNCWH1u+N6J6T0sC7gqRy8uGPfBLEbozPXUjlkQKwGaFPNizwQbwkx0TDvhCii34ExZCSQVBdzIOEOyeclSHgBGXkpeygXSQgStACtWx4Z8rr8COHOvfEP/IbbsQAToFUAAV1M408IIjIGYAPoCSNRP7DQutfQTqxuAiH7UUg1FaJR2AGrrx52sK2ye28LZ0wBAEyR6y8X+NADhm1B4fgiiHXbRrTrxpwEY9RdM9wsepnvFHfUDwYEeiwAJr/gAAAAASUVORK5CYII="))); -final iconClipboard = MemoryImage(Uint8List.fromList(base64Decode( - 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAjVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8DizOFAAAALnRSTlMAnIsyZy8YZF3NSAuabRL34cq6trCScyZ4qI9CQDwV+fPl2tnTwzkeB+m/pIFK/Xx0ewAAAQlJREFUOMudktduhDAQRWep69iY3tle0+7/f16Qg7MsJUQ5Dwh8jzRzhemJPIaf3GiW7eFQfOwDPp1ek/iMnKgBi5PrhJAhZAa1lCxE9pw5KWMswOMAQXuQOvqTB7tLFJ36wimKLrufZTzUaoRtdthqRA2vEwS+tR4qguiElRKk1YMrYfUQRkwLmwVBYDMvJKF8R0o3V2MOhNrfo+hXSYYjPn1L/S+n438t8gWh+q1F+cYFBMm1Jh8Ia7y2OWXQxMMRLqr2eTc1crSD84cWfEGwYM4LlaACEee2ZjsQXJxR3qmYb+GpC8ZfNM5oh3yxxbxgQE7lEkb3ZvvH1BiRHn1bu02ICcKGWr4AudUkyYxmvywAAAAASUVORK5CYII='))); -final iconAudio = MemoryImage(Uint8List.fromList(base64Decode( - 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAk1BMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ROyVeAAAAMHRSTlMAgfz08DDqCAThvraZjEcoGA751JxzbGdfTRP25NrIpaGTcEM+HAvMuKinhXhWNx9Yzm/gAAABFUlEQVQ4y82S2XLCMAxFheMsQNghCQFalkL39vz/11V4GpNk0r629+Va1pmxPFfyh1ravOP2Y1ydJmBO0lYP3r+PyQ62s2Y7fgF6VRXOYdToT++ogIuoVhCUtX7YpwJG3F8f6V8rr3WABwwUahlEvr8y3IBniGKdKYBQ5OGQpukQakBpIVcfwptIhJcf8hWGakdndAAhBInIGHbdQGJg6jjbDUgEE5EpmB+AAM4uj6gb+AQT6wdhITLvAHJ4VCtgoAlG1tpNA0gWON/f4ioHdSADc1bfgt+PZFkDlD6ojWF+kVoaHlhvFjPHuVRrefohY1GdcFm1N8JvwEyrJ/X2Th2rIoVgIi3Fo6Xf0z5k8psKu5f/oi+nHjjI92o36AAAAABJRU5ErkJggg=='))); -final iconFile = MemoryImage(Uint8List.fromList(base64Decode( - 'iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAMAAADVRocKAAAAUVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////8IN+deAAAAGnRSTlMAH+CAESEN8jyZkcIb5N/ONy3vmHhmiGjUm7UwS+YAAAHZSURBVGje7dnbboMwDIBhBwgQoFAO7Ta//4NOqCAXYZQstatq4r+r5ubrgQSpg8iyC4ZURa+PlIpQYGiwrzyeHtYZjAL8T05O4H8BbbKvFgRa4NoBU8pXeYEkDDgaaLQBcwJrmeErJQB/7wes3QBWGnCIX0+AQycL1PO6BMwPa0nA4ZxbgTvOjUYMGPHRnZkQAY4mxPZBjmy53E7ukSkFKYB/D4XsWZQx64sCeYebOogGsoOBYvv6/UCb8F0IOBZ0TlP6lEYdANY350AJqB9/qPVuOI5evw4A1hgLigAlepnyxW80bcCcwN++A2s82Vcu02ta+ceq9BoL5KGTTRwQPlpqA3gCnwWU2kCDgeWRQPj2jAPCDxgCMjhI6uZnToDpvd/BJeFrJQB/fsAa02gCt3mi1wNuy8GgBNDZlysBNNSrADVSjcJl6vCpUn6jOdx0kz0q6PMhQRa4465SFKhx35cgUCBTwj2/NHwZAb71qR8GEP2H1XcmAtBPTEO67GP6FUUAIKGABbDLQ0EArhN2sAIGesRO+iyy+RMAjckVTlMCKFVAbh/4Af9OPgG61SkDVco3BQGT3GXaDAnTIAcYZDuBTwGsAGDxuBFeAQqIqwoFMlAVLrHr/wId5MPt0nilGgAAAABJRU5ErkJggg=='))); -final iconRestart = MemoryImage(Uint8List.fromList(base64Decode( - 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAB7BAAAewQHDaVRTAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAbhJREFUWIXVlrFqFGEUhb+7UYxaWCQKlrKKxaZSQVGDJih2tj6MD2DnMwiWvoAIRnENIpZiYxEro6IooiS7SPwsMgNLkk3mjmYmnmb45/73nMNwz/x/qH3gMu2gH6rAU+Blw+Lngau4jpmGxVF7qp1iPWjaQKnZ2WnXbuP/NqAeUPc3ZkA9XDwvqc+BVWCgPlJ7tRwUKThZce819b46VH+pfXVRXVO/q2cSul3VOgZUl0ejq86r39TXI8mqZKDuDEwCw3IREQvAbWAGmMsQZQ0sAl3gHPB1Q+0e8BuYzRDuy2yOiFVgaUxtRf0ETGc4syk4rc6PqU0Cx9j8Zf6dAeAK8Fi9sUXtFjABvEgxJlNwRP2svlNPjbw/q35U36oTFbnyMSwabxb/gB/qA3VBHagrauV7RW0DRfP1IvMlXqkXkhz1DYyQTKtHa/Z2VVMx3IiI+PI3/bCHjuOpFrSnAMpL6QfgTcMGesDx0kBr2BMzsNyi/vtQu8CJlgwsRbZDnWP90NkKaxHxJMOXMqAeAn5u0ydwMCKGY+qbkB3C2W3EKWoXk5zVoHbUZ+6Mh7tl4G4F8RJ3qvL+AfV3r5Vdpj70AAAAAElFTkSuQmCC'))); -final iconRecording = MemoryImage(Uint8List.fromList(base64Decode( - 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAANpJREFUWEftltENAiEMhtsJ1NcynG6gI+gGugEOR591gppeQoIYSDBILxEeydH/57u2FMF4obE+TAOTwLoIhBDOAHBExG2n6rgR0akW640AM0sn4SWMiDycc7s8JjN7Ijro/k8NqAAR5RoeAPZxv2ggP9hCJiWZxtGbq3hqbJiBVHy4gVx8qAER8Yi4JFy6huVAKXemgb8icI+1b5KEitq0DOO/Nm1EEX1TK27p/bVvv36MOhl4EtHHbFF7jq8AoG1z08OAiFycczrkFNe6RrIet26NMQlMAuYEXiayryF/QQktAAAAAElFTkSuQmCC'))); final iconHardDrive = MemoryImage(Uint8List.fromList(base64Decode( 'iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAmVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjHWqVAAAAMnRSTlMAv0BmzLJNXlhiUu2fxXDgu7WuSUUe29LJvpqUjX53VTstD7ilNujCqTEk5IYH+vEoFjKvAagAAAPpSURBVHja7d0JbhpBEIXhB3jYzb5vBgzYgO04df/DJXGUKMwU9ECmZ6pQfSfw028LCXW3YYwxxhhjjDHGGGOM0eZ9VV1MckdKWLM1bRQ/35GW/WxHHu1me6ShuyHvNl34VhlTKsYVeDWj1EzgUZ1S1DrAk/UDparZgxd9Sl0BHnxSBhpI3jfKQG2FpLUpE69I2ILikv1nsvygjBwPSNKYMlNHggqUoSKS80AZCnwHqQ1zCRvW+CRegwRFeFAMKKrtM8gTPJlzSfwFgT9dJom3IDN4VGaSeAryAK8m0SSeghTg1ZYiql6CjBDhO8mzlyAVhKhIwgXxrh5NojGIhyRckEdwpCdhgpSQgiWTRGMQNonGIGySp0SDvMDBX5KWxiB8Eo1BgE00SYJBykhNnkmSWJAcLpGaJNMgfJKyxiDAK4WNEwryhMtkJsk8CJtEYxA+icYgQIfCcgkEqcJNXhIRQdgkGoPwSTQG+e8khdu/7JOVREwQIKCwF41B2CQljUH4JLcH6SI+OUlEBQHa0SQag/BJNAbhkjxqDMIn0RgEeI4muSlID9eSkERgEKAVTaIxCJ9EYxA2ydVB8hCASVLRGAQYR5NoDMIn0RgEyFHYSGMQPonGII4kziCNvBgNJonEk4u3GAk8Sprk6eYaqbMDY0oKvUm5jfC/viGiSypV7+M3i2iDsAGpNEDYjlTa3W8RdR/r544g50ilnA0RxoZIE2NIXqQbhkAkGyKNDZHGhkhjQ6SxIdLYEGlsiDQ2JGTVeD0264U9zipPh7XOooffpA6pfNCXjxl4/c3pUzlChwzor53zwYYVfpI5pOV6LWFF/2jiJ5FDSs5jdY/0rwUAkUMeXWdBqnSqD0DikBqdqCHsjTvELm9In0IOri/0pwAEDtlSyNaRjAIAAoesKWTtuusxByBwCJp0oomwBXcYUuCQgE50ENajE4OvZAKHLB1/68Br5NqiyCGYOY8YRd77kTkEb64n7lZN+mOIX4QOwb5FX0ZVx3uOxwW+SB0CbBubemWP8/rlaaeRX+M3uUOuZENsiA25zIbYkPsZElBIHwL13U/PTjJ/cyOOEoVM3I+hziDQlELm7pPxw3eI8/7gPh1fpLA6xGnEeDDgO0UcIAzzM35HxLPIq5SXe9BLzOsj9eUaQqyXzxS1QFSfWM2cCANiHcAISJ0AnCKpUwTuIkkA3EeSInAXSQKcs1V18e24wlllUmQp9v9zXKeHi+akRAMOPVKhAqdPBZeUmnnEsO6QcJ0+4qmOSbBxFfGVRiTUqITrdKcCbyYO3/K4wX4+aQ+FfNjXhu3JfAVjjDHGGGOMMcYYY4xIPwCgfqT6TbhCLAAAAABJRU5ErkJggg=='))); diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index ff35fa69f..ed00d2421 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -70,25 +70,28 @@ class _DesktopServerPageState extends State Widget build(BuildContext context) { super.build(context); return MultiProvider( - providers: [ - ChangeNotifierProvider.value(value: gFFI.serverModel), - ChangeNotifierProvider.value(value: gFFI.chatModel), - ], - child: Consumer( - builder: (context, serverModel, child) => Container( - decoration: BoxDecoration( - border: Border.all(color: MyTheme.color(context).border!)), - child: Scaffold( - backgroundColor: Theme.of(context).colorScheme.background, - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded(child: ConnectionManager()), - ], - ), - ), - )))); + providers: [ + ChangeNotifierProvider.value(value: gFFI.serverModel), + ChangeNotifierProvider.value(value: gFFI.chatModel), + ], + child: Consumer( + builder: (context, serverModel, child) => Container( + decoration: BoxDecoration( + border: Border.all(color: MyTheme.color(context).border!)), + child: Scaffold( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded(child: ConnectionManager()), + ], + ), + ), + ), + ), + ), + ); } @override @@ -408,23 +411,39 @@ class _PrivilegeBoard extends StatefulWidget { class _PrivilegeBoardState extends State<_PrivilegeBoard> { late final client = widget.client; - Widget buildPermissionTile(bool enabled, ImageProvider icon, - Function(bool)? onTap, String tooltipText) { + Widget buildPermissionTile(bool enabled, String assetPath, + Function(bool)? onTap, String permissionText, String tooltipText) { return Row( children: [ Tooltip( message: tooltipText, - child: Image( - image: icon, - width: 50, - height: 50, - fit: BoxFit.scaleDown, - ), - ), + child: Container( + decoration: BoxDecoration( + color: MyTheme.accent, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + ), + child: SvgPicture.asset( + assetPath, + color: Colors.white, + width: 40.0, + height: 40.0, + ), + ).paddingOnly(left: 5.0, bottom: 5.0), + ).paddingOnly(right: 8.0), + SizedBox( + child: Text( + permissionText, + style: TextStyle(fontSize: 18), + ), + width: 250), Switch( value: enabled, - onChanged: (v) => - checkClickTime(widget.client.id, () => onTap?.call(v)), + onChanged: (v) => checkClickTime( + widget.client.id, + () => onTap?.call(v), + ), ), ], ); @@ -433,62 +452,113 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { @override Widget build(BuildContext context) { return Container( - margin: EdgeInsets.only(top: 16.0, bottom: 8.0), + margin: EdgeInsets.only(top: 16.0, bottom: 8.0, left: 5.0, right: 5.0), + padding: EdgeInsets.all(5.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Theme.of(context).colorScheme.background, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + spreadRadius: 1, + blurRadius: 1, + offset: Offset(0, 1.5), // changes position of shadow + ), + ], + ), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( translate("Permissions"), - style: TextStyle(fontSize: 16), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + textAlign: TextAlign.center, ).marginOnly(left: 4.0), SizedBox( height: 8.0, ), FittedBox( child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - buildPermissionTile(client.keyboard, iconKeyboard, (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "keyboard", enabled: enabled); - setState(() { - client.keyboard = enabled; - }); - }, translate('Allow using keyboard and mouse')), - buildPermissionTile(client.clipboard, iconClipboard, (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "clipboard", enabled: enabled); - setState(() { - client.clipboard = enabled; - }); - }, translate('Allow using clipboard')), - buildPermissionTile(client.audio, iconAudio, (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "audio", enabled: enabled); - setState(() { - client.audio = enabled; - }); - }, translate('Allow hearing sound')), - buildPermissionTile(client.file, iconFile, (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "file", enabled: enabled); - setState(() { - client.file = enabled; - }); - }, translate('Allow file copy and paste')), - buildPermissionTile(client.restart, iconRestart, (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "restart", enabled: enabled); - setState(() { - client.restart = enabled; - }); - }, translate('Allow remote restart')), - buildPermissionTile(client.recording, iconRecording, (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "recording", enabled: enabled); - setState(() { - client.recording = enabled; - }); - }, translate('Allow recording session')) + buildPermissionTile( + client.keyboard, + "assets/keyboard.svg", + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "keyboard", enabled: enabled); + setState(() { + client.keyboard = enabled; + }); + }, + translate("Input Control"), + translate('Allow using keyboard and mouse'), + ), + buildPermissionTile( + client.clipboard, + "assets/clipboard.svg", + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "clipboard", enabled: enabled); + setState(() { + client.clipboard = enabled; + }); + }, + translate("Clipboard"), + translate('Allow using clipboard'), + ), + buildPermissionTile( + client.audio, + "assets/audio.svg", + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "audio", enabled: enabled); + setState(() { + client.audio = enabled; + }); + }, + translate("Audio"), + translate('Allow hearing sound'), + ), + buildPermissionTile( + client.file, + "assets/file.svg", + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "file", enabled: enabled); + setState(() { + client.file = enabled; + }); + }, + translate("File"), + translate('Allow file copy and paste'), + ), + buildPermissionTile( + client.restart, + "assets/restart.svg", + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "restart", enabled: enabled); + setState(() { + client.restart = enabled; + }); + }, + translate("Restart"), + translate('Allow remote restart'), + ), + buildPermissionTile( + client.recording, + "assets/rec.svg", + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "recording", enabled: enabled); + setState(() { + client.recording = enabled; + }); + }, + translate("Recording"), + translate('Allow recording session'), + ) ], )), ], From 87c3a2850d5d6bc1a89c9ff541362e7e98edd0d4 Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Thu, 18 May 2023 22:59:07 +0200 Subject: [PATCH 03/11] modernized header --- flutter/assets/audio.svg | 2 - flutter/assets/clipboard.svg | 2 - flutter/assets/restart.svg | 2 - flutter/lib/desktop/pages/server_page.dart | 147 +++++++++++++-------- 4 files changed, 89 insertions(+), 64 deletions(-) diff --git a/flutter/assets/audio.svg b/flutter/assets/audio.svg index baf0972db..ba12b34e6 100644 --- a/flutter/assets/audio.svg +++ b/flutter/assets/audio.svg @@ -1,3 +1 @@ - - \ No newline at end of file diff --git a/flutter/assets/clipboard.svg b/flutter/assets/clipboard.svg index ff3158752..d2230845d 100644 --- a/flutter/assets/clipboard.svg +++ b/flutter/assets/clipboard.svg @@ -1,3 +1 @@ - - \ No newline at end of file diff --git a/flutter/assets/restart.svg b/flutter/assets/restart.svg index bf74398a8..21a085569 100644 --- a/flutter/assets/restart.svg +++ b/flutter/assets/restart.svg @@ -1,3 +1 @@ - - \ No newline at end of file diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index ed00d2421..79aeaf896 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -329,70 +329,101 @@ class _CmHeaderState extends State<_CmHeader> @override Widget build(BuildContext context) { super.build(context); - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // icon - Container( - width: 90, - height: 90, - alignment: Alignment.center, - decoration: BoxDecoration(color: str2color(client.name)), - child: Text( - client.name[0], - style: TextStyle( - fontWeight: FontWeight.bold, color: Colors.white, fontSize: 65), - ), - ).marginOnly(left: 4.0, right: 8.0), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - FittedBox( - child: Text( - client.name, - style: TextStyle( - color: MyTheme.cmIdColor, - fontWeight: FontWeight.bold, - fontSize: 20, - overflow: TextOverflow.ellipsis, - ), - maxLines: 1, - )), - FittedBox( - child: Text("(${client.peerId})", - style: - TextStyle(color: MyTheme.cmIdColor, fontSize: 14))), - SizedBox( - height: 16.0, + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + gradient: LinearGradient( + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + Color(0xff00bfe1), + Color(0xff0071ff), + ], + ), + ), + margin: EdgeInsets.all(5.0), + padding: EdgeInsets.all(10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 70, + height: 70, + alignment: Alignment.center, + decoration: BoxDecoration( + color: str2color(client.name), + borderRadius: BorderRadius.circular(15.0), + ), + child: Text( + client.name[0], + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + fontSize: 55, ), - FittedBox( - child: Row( - children: [ - Text(client.authorized + ), + ).marginOnly(right: 10.0), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + FittedBox( + child: Text( + client.name, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 20, + overflow: TextOverflow.ellipsis, + ), + maxLines: 1, + )), + FittedBox( + child: Text( + "(${client.peerId})", + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ).marginOnly(bottom: 10.0), + FittedBox( + child: Row( + children: [ + Text( + client.authorized ? client.disconnected ? translate("Disconnected") : translate("Connected") - : "${translate("Request access to your device")}...") - .marginOnly(right: 8.0), - if (client.authorized) - Obx(() => Text( - formatDurationToTime(Duration(seconds: _time.value)))) - ], - )) - ], + : "${translate("Request access to your device")}...", + style: TextStyle(color: Colors.white), + ).marginOnly(right: 8.0), + if (client.authorized) + Obx( + () => Text( + formatDurationToTime( + Duration(seconds: _time.value), + ), + style: TextStyle(color: Colors.white), + ), + ) + ], + )) + ], + ), ), - ), - Offstage( - offstage: !client.authorized || client.type_() != ClientType.remote, - child: IconButton( + Offstage( + offstage: !client.authorized || client.type_() != ClientType.remote, + child: IconButton( onPressed: () => checkClickTime( client.id, () => gFFI.chatModel.toggleCMChatPage(client.id)), - icon: Icon(Icons.message_outlined), - splashRadius: kDesktopIconButtonSplashRadius), - ) - ], + icon: Icon( + Icons.message_rounded, + color: Colors.white, + ), + splashRadius: kDesktopIconButtonSplashRadius, + ), + ) + ], + ), ); } @@ -452,7 +483,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { @override Widget build(BuildContext context) { return Container( - margin: EdgeInsets.only(top: 16.0, bottom: 8.0, left: 5.0, right: 5.0), + margin: EdgeInsets.all(5.0), padding: EdgeInsets.all(5.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), From 3dbc3b9d6ce92967d0ecf44275cc8a987fcb8149 Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Fri, 19 May 2023 23:20:09 +0200 Subject: [PATCH 04/11] added fluent icons --- flutter/pubspec.lock | 8 ++++++++ flutter/pubspec.yaml | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 30cfcd377..06920dc5c 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -450,6 +450,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + fluentui_system_icons: + dependency: "direct main" + description: + name: fluentui_system_icons + sha256: "745d58831bba404532bebce20286fb1920c650a4cc74678990251a16fb4d2600" + url: "https://pub.dev" + source: hosted + version: "1.1.201" flutter: dependency: "direct main" description: flutter diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index c3781a817..296aa0a89 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -41,7 +41,7 @@ dependencies: package_info_plus: ^1.4.2 url_launcher: ^6.0.9 toggle_switch: ^1.4.0 - dash_chat_2: ^0.0.14 + dash_chat_2: ^0.0.15 draggable_float_widget: ^0.0.2 settings_ui: ^2.0.2 flutter_breadcrumb: ^1.0.1 @@ -99,6 +99,7 @@ dependencies: texture_rgba_renderer: ^0.0.16 percent_indicator: ^4.2.2 dropdown_button2: ^2.0.0 + fluentui_system_icons: ^1.1.201 dev_dependencies: icons_launcher: ^2.0.4 From f106a116ab342ce4398a475681fad5f8557a406e Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Fri, 19 May 2023 23:21:13 +0200 Subject: [PATCH 05/11] larger chat and moved to left --- flutter/lib/common/widgets/chat_page.dart | 147 ++++++++++++-------- flutter/lib/consts.dart | 4 +- flutter/lib/desktop/pages/server_page.dart | 154 +++++++++++---------- 3 files changed, 167 insertions(+), 138 deletions(-) diff --git a/flutter/lib/common/widgets/chat_page.dart b/flutter/lib/common/widgets/chat_page.dart index 9460f4f41..54805c94a 100644 --- a/flutter/lib/common/widgets/chat_page.dart +++ b/flutter/lib/common/widgets/chat_page.dart @@ -1,7 +1,9 @@ import 'package:dash_chat_2/dash_chat_2.dart'; +import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/models/chat_model.dart'; +import 'package:get/get.dart'; import 'package:provider/provider.dart'; import '../../mobile/pages/home_page.dart'; @@ -43,12 +45,28 @@ class ChatPage extends StatelessWidget implements PageShape { @override Widget build(BuildContext context) { return ChangeNotifierProvider.value( - value: chatModel, - child: Container( - color: Theme.of(context).scaffoldBackgroundColor, - child: Consumer(builder: (context, chatModel, child) { - final currentUser = chatModel.currentUser; - return Stack( + value: chatModel, + child: Container( + color: Theme.of(context).scaffoldBackgroundColor, + padding: EdgeInsets.all(20.0), + child: Consumer( + builder: (context, chatModel, child) { + final currentUser = chatModel.currentUser; + return Container( + padding: EdgeInsets.symmetric(vertical: 5.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Theme.of(context).colorScheme.background, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + spreadRadius: 1, + blurRadius: 1, + offset: Offset(0, 1.5), // changes position of shadow + ), + ], + ), + child: Stack( children: [ LayoutBuilder(builder: (context, constraints) { final chat = DashChat( @@ -61,40 +79,40 @@ class ChatPage extends StatelessWidget implements PageShape { .messages[chatModel.currentID]?.chatMessages ?? [], inputOptions: InputOptions( - sendOnEnter: true, - focusNode: chatModel.inputNode, - inputTextStyle: TextStyle( - fontSize: 14, - color: Theme.of(context) - .textTheme - .titleLarge - ?.color), - inputDecoration: isDesktop - ? InputDecoration( - isDense: true, - hintText: - "${translate('Write a message')}", - filled: true, - fillColor: - Theme.of(context).colorScheme.background, - contentPadding: EdgeInsets.all(10), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(6), - borderSide: const BorderSide( - width: 0, - style: BorderStyle.none, - ), + sendOnEnter: true, + focusNode: chatModel.inputNode, + inputTextStyle: TextStyle( + fontSize: 14, + color: + Theme.of(context).textTheme.titleLarge?.color), + inputDecoration: isDesktop + ? InputDecoration( + isDense: true, + hintText: translate('Write a message'), + filled: true, + fillColor: + Theme.of(context).colorScheme.background, + contentPadding: EdgeInsets.all(10), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + borderSide: const BorderSide( + width: 1, + style: BorderStyle.solid, ), - ) - : defaultInputDecoration( - hintText: - "${translate('Write a message')}", - fillColor: - Theme.of(context).colorScheme.background), - sendButtonBuilder: defaultSendButton( - padding: EdgeInsets.symmetric( - horizontal: 6, vertical: 0), - color: Theme.of(context).colorScheme.primary)), + ), + ) + : defaultInputDecoration( + hintText: translate('Write a message'), + fillColor: + Theme.of(context).colorScheme.background, + ), + sendButtonBuilder: defaultSendButton( + padding: + EdgeInsets.symmetric(horizontal: 6, vertical: 0), + color: Theme.of(context).colorScheme.primary, + icon: FluentIcons.send_24_filled, + ), + ), messageOptions: MessageOptions( showOtherUsersAvatar: false, textColor: Colors.white, @@ -104,32 +122,34 @@ class ChatPage extends StatelessWidget implements PageShape { message.user.id == currentUser.id; return Column( crossAxisAlignment: isOwnMessage - ? CrossAxisAlignment.end - : CrossAxisAlignment.start, + ? CrossAxisAlignment.start + : CrossAxisAlignment.end, children: [ Text(message.text, style: TextStyle(color: Colors.white)), - Padding( - padding: const EdgeInsets.only(top: 5), - child: Text( - "${message.createdAt.hour}:${message.createdAt.minute}", - style: TextStyle( - color: Colors.white, - fontSize: 10, - ), + Text( + "${message.createdAt.hour}:${message.createdAt.minute}", + style: TextStyle( + color: Colors.white, + fontSize: 8, ), - ), + ).marginOnly(top: 3), ], ); }, - messageDecorationBuilder: (_, __, ___) => - defaultMessageDecoration( - color: MyTheme.accent80, - borderTopLeft: 8, - borderTopRight: 8, - borderBottomRight: 8, - borderBottomLeft: 8, - )), + messageDecorationBuilder: (message, __, ___) { + final isOwnMessage = + message.user.id == currentUser.id; + return defaultMessageDecoration( + color: isOwnMessage + ? Color.fromARGB(170, 71, 97, 129) + : MyTheme.accent80, + borderTopLeft: 8, + borderTopRight: 8, + borderBottomRight: isOwnMessage ? 8 : 2, + borderBottomLeft: isOwnMessage ? 2 : 8, + ); + }), ); return SelectionArea(child: chat); }), @@ -148,9 +168,14 @@ class ChatPage extends StatelessWidget implements PageShape { style: TextStyle(color: MyTheme.accent50), ), ], - )), + ), + ), ], - ); - }))); + ), + ); + }, + ), + ), + ); } } diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 1facf4e4b..d69b6cb3b 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -76,8 +76,8 @@ extension StringExtension on String { String get nonBreaking => replaceAll(' ', String.fromCharCode($nbsp)); } -const Size kConnectionManagerWindowSizeClosedChat = Size(300, 500); -const Size kConnectionManagerWindowSizeOpenChat = Size(600, 500); +const Size kConnectionManagerWindowSizeClosedChat = Size(300, 450); +const Size kConnectionManagerWindowSizeOpenChat = Size(700, 450); // Tabbar transition duration, now we remove the duration const Duration kTabTransitionDuration = Duration.zero; const double kEmptyMarginTop = 50; diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index 79aeaf896..01d26ff9c 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -12,6 +12,7 @@ import 'package:get/get.dart'; import 'package:provider/provider.dart'; import 'package:window_manager/window_manager.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import '../../common.dart'; import '../../common/widgets/chat_page.dart'; @@ -139,41 +140,45 @@ class ConnectionManagerState extends State { onPointerDown: pointerHandler, onPointerMove: pointerHandler, child: DesktopTab( - showTitle: false, - showMaximize: false, - showMinimize: true, - showClose: true, - onWindowCloseButton: handleWindowCloseButton, - controller: serverModel.tabController, - maxLabelWidth: 100, - tail: buildScrollJumper(), - selectedTabBackgroundColor: - Theme.of(context).hintColor.withOpacity(0.2), - tabBuilder: (key, icon, label, themeConf) { - final client = serverModel.clients.firstWhereOrNull( - (client) => client.id.toString() == key); - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Tooltip( - message: key, - waitDuration: Duration(seconds: 1), - child: label), - Obx(() => Offstage( - offstage: - !(client?.hasUnreadChatMessage.value ?? false), - child: - Icon(Icons.circle, color: Colors.red, size: 10))) - ], - ); - }, - pageViewBuilder: (pageView) => Row(children: [ - Expanded(child: pageView), - Consumer( - builder: (_, model, child) => model.isShowCMChatPage - ? Expanded(child: Scaffold(body: ChatPage())) - : Offstage()) - ]))); + showTitle: false, + showMaximize: false, + showMinimize: true, + showClose: true, + onWindowCloseButton: handleWindowCloseButton, + controller: serverModel.tabController, + maxLabelWidth: 100, + tail: buildScrollJumper(), + selectedTabBackgroundColor: + Theme.of(context).hintColor.withOpacity(0.2), + tabBuilder: (key, icon, label, themeConf) { + final client = serverModel.clients + .firstWhereOrNull((client) => client.id.toString() == key); + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Tooltip( + message: key, + waitDuration: Duration(seconds: 1), + child: label), + Obx(() => Offstage( + offstage: + !(client?.hasUnreadChatMessage.value ?? false), + child: Icon(Icons.circle, color: Colors.red, size: 10))) + ], + ); + }, + pageViewBuilder: (pageView) => Row( + children: [ + Consumer( + builder: (_, model, child) => model.isShowCMChatPage + ? Container( + width: 400, child: Scaffold(body: ChatPage())) + : Offstage()), + Expanded(child: pageView), + ], + ), + ), + ); } Widget buildTitleBar() { @@ -251,10 +256,11 @@ Widget buildConnectionCard(Client client) { ? Offstage() : _PrivilegeBoard(client: client), Expanded( - child: Align( - alignment: Alignment.bottomCenter, - child: _CmControlPanel(client: client), - )) + child: Align( + alignment: Alignment.bottomCenter, + child: _CmControlPanel(client: client), + ), + ) ], ).paddingSymmetric(vertical: 8.0, horizontal: 8.0)); } @@ -341,7 +347,7 @@ class _CmHeaderState extends State<_CmHeader> ], ), ), - margin: EdgeInsets.all(5.0), + margin: EdgeInsets.symmetric(horizontal: 5.0, vertical: 10.0), padding: EdgeInsets.all(10), child: Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -416,7 +422,7 @@ class _CmHeaderState extends State<_CmHeader> onPressed: () => checkClickTime( client.id, () => gFFI.chatModel.toggleCMChatPage(client.id)), icon: Icon( - Icons.message_rounded, + FluentIcons.chat_32_filled, color: Colors.white, ), splashRadius: kDesktopIconButtonSplashRadius, @@ -442,25 +448,14 @@ class _PrivilegeBoard extends StatefulWidget { class _PrivilegeBoardState extends State<_PrivilegeBoard> { late final client = widget.client; - Widget buildPermissionTile(bool enabled, String assetPath, + Widget buildPermissionTile(bool enabled, IconData iconData, Function(bool)? onTap, String permissionText, String tooltipText) { return Row( children: [ Tooltip( message: tooltipText, - child: Container( - decoration: BoxDecoration( - color: MyTheme.accent, - borderRadius: BorderRadius.all( - Radius.circular(10.0), - ), - ), - child: SvgPicture.asset( - assetPath, - color: Colors.white, - width: 40.0, - height: 40.0, - ), + child: Icon( + iconData, ).paddingOnly(left: 5.0, bottom: 5.0), ).paddingOnly(right: 8.0), SizedBox( @@ -514,7 +509,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { children: [ buildPermissionTile( client.keyboard, - "assets/keyboard.svg", + FluentIcons.keyboard_24_filled, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "keyboard", enabled: enabled); @@ -527,7 +522,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { ), buildPermissionTile( client.clipboard, - "assets/clipboard.svg", + FluentIcons.clipboard_24_filled, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "clipboard", enabled: enabled); @@ -540,7 +535,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { ), buildPermissionTile( client.audio, - "assets/audio.svg", + FluentIcons.speaker_1_24_filled, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "audio", enabled: enabled); @@ -553,7 +548,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { ), buildPermissionTile( client.file, - "assets/file.svg", + FluentIcons.arrow_sort_24_filled, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "file", enabled: enabled); @@ -566,7 +561,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { ), buildPermissionTile( client.restart, - "assets/restart.svg", + FluentIcons.arrow_clockwise_24_filled, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "restart", enabled: enabled); @@ -579,7 +574,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { ), buildPermissionTile( client.recording, - "assets/rec.svg", + FluentIcons.record_24_filled, (enabled) { bind.cmSwitchPermission( connId: client.id, name: "recording", enabled: enabled); @@ -681,11 +676,17 @@ class _CmControlPanel extends StatelessWidget { Row( children: [ Expanded( - child: buildButton(context, - color: Colors.redAccent, - onClick: handleDisconnect, - text: 'Disconnect', - textColor: Colors.white)), + child: buildButton(context, + color: Colors.redAccent, + onClick: handleDisconnect, + text: 'Disconnect', + icon: Icon( + FluentIcons.plug_disconnected_20_filled, + color: Colors.white, + size: 14, + ), + textColor: Colors.white), + ), ], ) ], @@ -789,16 +790,19 @@ class _CmControlPanel extends StatelessWidget { return Container( height: 30, decoration: BoxDecoration( - color: color, borderRadius: BorderRadius.circular(4), border: border), + color: color, + borderRadius: BorderRadius.circular(10.0), + border: border), child: InkWell( - onTap: () => checkClickTime(client.id, onClick), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Offstage(offstage: icon == null, child: icon), - textWidget, - ], - )), + onTap: () => checkClickTime(client.id, onClick), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Offstage(offstage: icon == null, child: icon).marginOnly(right: 5), + textWidget, + ], + ), + ), ).marginAll(4); } From 11fc56ab2c3c1a1a260429d7937e13454548bfdd Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Sat, 20 May 2023 15:12:52 +0200 Subject: [PATCH 06/11] switched to grid layout --- flutter/lib/common.dart | 20 +- flutter/lib/common/widgets/chat_page.dart | 19 +- flutter/lib/consts.dart | 4 +- flutter/lib/desktop/pages/server_page.dart | 338 +++++++++++---------- flutter/lib/models/chat_model.dart | 33 +- flutter/lib/models/server_model.dart | 8 +- 6 files changed, 229 insertions(+), 193 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 107221d32..544dabaf7 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -183,6 +183,8 @@ class MyTheme { ), ); + static const SwitchThemeData switchTheme = SwitchThemeData(splashRadius: 0); + // Checkbox static const CheckboxThemeData checkboxTheme = CheckboxThemeData( splashRadius: 0, @@ -307,6 +309,7 @@ class MyTheme { ), ), ), + switchTheme: switchTheme, checkboxTheme: checkboxTheme, listTileTheme: listTileTheme, menuBarTheme: MenuBarThemeData( @@ -346,12 +349,16 @@ class MyTheme { ) : null, textTheme: const TextTheme( - titleLarge: TextStyle(fontSize: 19), - titleSmall: TextStyle(fontSize: 14), - bodySmall: TextStyle(fontSize: 12, height: 1.25), - bodyMedium: TextStyle(fontSize: 14, height: 1.25), - labelLarge: TextStyle( - fontSize: 16.0, fontWeight: FontWeight.bold, color: accent80)), + titleLarge: TextStyle(fontSize: 19), + titleSmall: TextStyle(fontSize: 14), + bodySmall: TextStyle(fontSize: 12, height: 1.25), + bodyMedium: TextStyle(fontSize: 14, height: 1.25), + labelLarge: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: accent80, + ), + ), cardColor: Color(0xFF24252B), visualDensity: VisualDensity.adaptivePlatformDensity, tabBarTheme: const TabBarTheme( @@ -397,6 +404,7 @@ class MyTheme { ), ), ), + switchTheme: switchTheme, checkboxTheme: checkboxTheme, listTileTheme: listTileTheme, menuBarTheme: MenuBarThemeData( diff --git a/flutter/lib/common/widgets/chat_page.dart b/flutter/lib/common/widgets/chat_page.dart index 54805c94a..a88e120f1 100644 --- a/flutter/lib/common/widgets/chat_page.dart +++ b/flutter/lib/common/widgets/chat_page.dart @@ -57,14 +57,6 @@ class ChatPage extends StatelessWidget implements PageShape { decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), color: Theme.of(context).colorScheme.background, - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.2), - spreadRadius: 1, - blurRadius: 1, - offset: Offset(0, 1.5), // changes position of shadow - ), - ], ), child: Stack( children: [ @@ -109,12 +101,13 @@ class ChatPage extends StatelessWidget implements PageShape { sendButtonBuilder: defaultSendButton( padding: EdgeInsets.symmetric(horizontal: 6, vertical: 0), - color: Theme.of(context).colorScheme.primary, + color: MyTheme.accent, icon: FluentIcons.send_24_filled, ), ), messageOptions: MessageOptions( showOtherUsersAvatar: false, + showOtherUsersName: false, textColor: Colors.white, maxWidth: constraints.maxWidth * 0.7, messageTextBuilder: (message, _, __) { @@ -128,7 +121,7 @@ class ChatPage extends StatelessWidget implements PageShape { Text(message.text, style: TextStyle(color: Colors.white)), Text( - "${message.createdAt.hour}:${message.createdAt.minute}", + "${message.createdAt.hour}:${message.createdAt.minute.toString().padLeft(2, '0')}", style: TextStyle( color: Colors.white, fontSize: 8, @@ -142,8 +135,8 @@ class ChatPage extends StatelessWidget implements PageShape { message.user.id == currentUser.id; return defaultMessageDecoration( color: isOwnMessage - ? Color.fromARGB(170, 71, 97, 129) - : MyTheme.accent80, + ? Colors.blueGrey + : MyTheme.accent, borderTopLeft: 8, borderTopRight: 8, borderBottomRight: isOwnMessage ? 8 : 2, @@ -165,7 +158,7 @@ class ChatPage extends StatelessWidget implements PageShape { SizedBox(width: 5), Text( "${currentUser.firstName} ${currentUser.id}", - style: TextStyle(color: MyTheme.accent50), + style: TextStyle(color: MyTheme.accent), ), ], ), diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index d69b6cb3b..3e664c484 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -76,8 +76,8 @@ extension StringExtension on String { String get nonBreaking => replaceAll(' ', String.fromCharCode($nbsp)); } -const Size kConnectionManagerWindowSizeClosedChat = Size(300, 450); -const Size kConnectionManagerWindowSizeOpenChat = Size(700, 450); +const Size kConnectionManagerWindowSizeClosedChat = Size(300, 490); +const Size kConnectionManagerWindowSizeOpenChat = Size(700, 490); // Tabbar transition duration, now we remove the duration const Duration kTabTransitionDuration = Duration.zero; const double kEmptyMarginTop = 50; diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index 01d26ff9c..184fd5a2a 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -348,7 +348,12 @@ class _CmHeaderState extends State<_CmHeader> ), ), margin: EdgeInsets.symmetric(horizontal: 5.0, vertical: 10.0), - padding: EdgeInsets.all(10), + padding: EdgeInsets.only( + top: 10.0, + bottom: 10.0, + left: 10.0, + right: 5.0, + ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -420,7 +425,9 @@ class _CmHeaderState extends State<_CmHeader> offstage: !client.authorized || client.type_() != ClientType.remote, child: IconButton( onPressed: () => checkClickTime( - client.id, () => gFFI.chatModel.toggleCMChatPage(client.id)), + client.id, + () => gFFI.chatModel.toggleCMChatPage(client.id), + ), icon: Icon( FluentIcons.chat_32_filled, color: Colors.white, @@ -448,36 +455,34 @@ class _PrivilegeBoard extends StatefulWidget { class _PrivilegeBoardState extends State<_PrivilegeBoard> { late final client = widget.client; - Widget buildPermissionTile(bool enabled, IconData iconData, + Widget buildPermissionIcon(bool enabled, IconData iconData, Function(bool)? onTap, String permissionText, String tooltipText) { - return Row( - children: [ - Tooltip( - message: tooltipText, + return Tooltip( + message: tooltipText, + child: Container( + decoration: BoxDecoration( + color: enabled ? MyTheme.accent : Colors.blueGrey, + borderRadius: BorderRadius.circular(10.0), + ), + padding: EdgeInsets.all(4.0), + child: InkWell( + onTap: () => + checkClickTime(widget.client.id, () => onTap?.call(!enabled)), child: Icon( iconData, - ).paddingOnly(left: 5.0, bottom: 5.0), - ).paddingOnly(right: 8.0), - SizedBox( - child: Text( - permissionText, - style: TextStyle(fontSize: 18), - ), - width: 250), - Switch( - value: enabled, - onChanged: (v) => checkClickTime( - widget.client.id, - () => onTap?.call(v), + size: 30.0, + color: Colors.white, ), ), - ], + ), ); } @override Widget build(BuildContext context) { return Container( + width: double.infinity, + height: 200.0, margin: EdgeInsets.all(5.0), padding: EdgeInsets.all(5.0), decoration: BoxDecoration( @@ -488,7 +493,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { color: Colors.black.withOpacity(0.2), spreadRadius: 1, blurRadius: 1, - offset: Offset(0, 1.5), // changes position of shadow + offset: Offset(0, 1.5), ), ], ), @@ -499,101 +504,102 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { translate("Permissions"), style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), textAlign: TextAlign.center, - ).marginOnly(left: 4.0), - SizedBox( - height: 8.0, + ).marginOnly(left: 4.0, bottom: 8.0), + Expanded( + child: GridView.count( + crossAxisCount: 3, + padding: EdgeInsets.symmetric(horizontal: 20.0), + mainAxisSpacing: 20.0, + crossAxisSpacing: 20.0, + children: [ + buildPermissionIcon( + client.keyboard, + FluentIcons.keyboard_24_filled, + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "keyboard", enabled: enabled); + setState(() { + client.keyboard = enabled; + }); + }, + translate("Input Control"), + translate('Allow using keyboard and mouse'), + ), + buildPermissionIcon( + client.clipboard, + FluentIcons.clipboard_24_filled, + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "clipboard", enabled: enabled); + setState(() { + client.clipboard = enabled; + }); + }, + translate("Clipboard"), + translate('Allow using clipboard'), + ), + buildPermissionIcon( + client.audio, + FluentIcons.speaker_1_24_filled, + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "audio", enabled: enabled); + setState(() { + client.audio = enabled; + }); + }, + translate("Audio"), + translate('Allow hearing sound'), + ), + buildPermissionIcon( + client.file, + FluentIcons.arrow_sort_24_filled, + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "file", enabled: enabled); + setState(() { + client.file = enabled; + }); + }, + translate("File"), + translate('Allow file copy and paste'), + ), + buildPermissionIcon( + client.restart, + FluentIcons.arrow_sync_circle_20_filled, + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "restart", enabled: enabled); + setState(() { + client.restart = enabled; + }); + }, + translate("Restart"), + translate('Allow remote restart'), + ), + buildPermissionIcon( + client.recording, + FluentIcons.record_stop_24_filled, + (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "recording", enabled: enabled); + setState(() { + client.recording = enabled; + }); + }, + translate("Recording"), + translate('Allow recording session'), + ) + ], + ), ), - FittedBox( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - buildPermissionTile( - client.keyboard, - FluentIcons.keyboard_24_filled, - (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "keyboard", enabled: enabled); - setState(() { - client.keyboard = enabled; - }); - }, - translate("Input Control"), - translate('Allow using keyboard and mouse'), - ), - buildPermissionTile( - client.clipboard, - FluentIcons.clipboard_24_filled, - (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "clipboard", enabled: enabled); - setState(() { - client.clipboard = enabled; - }); - }, - translate("Clipboard"), - translate('Allow using clipboard'), - ), - buildPermissionTile( - client.audio, - FluentIcons.speaker_1_24_filled, - (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "audio", enabled: enabled); - setState(() { - client.audio = enabled; - }); - }, - translate("Audio"), - translate('Allow hearing sound'), - ), - buildPermissionTile( - client.file, - FluentIcons.arrow_sort_24_filled, - (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "file", enabled: enabled); - setState(() { - client.file = enabled; - }); - }, - translate("File"), - translate('Allow file copy and paste'), - ), - buildPermissionTile( - client.restart, - FluentIcons.arrow_clockwise_24_filled, - (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "restart", enabled: enabled); - setState(() { - client.restart = enabled; - }); - }, - translate("Restart"), - translate('Allow remote restart'), - ), - buildPermissionTile( - client.recording, - FluentIcons.record_24_filled, - (enabled) { - bind.cmSwitchPermission( - connId: client.id, name: "recording", enabled: enabled); - setState(() { - client.recording = enabled; - }); - }, - translate("Recording"), - translate('Allow recording session'), - ) - ], - )), ], ), ); } } -const double bigMargin = 15; +const double buttonBottomMargin = 8; class _CmControlPanel extends StatelessWidget { final Client client; @@ -620,12 +626,18 @@ class _CmControlPanel extends StatelessWidget { children: [ Offstage( offstage: !client.inVoiceCall, - child: buildButton(context, - color: Colors.red, - onClick: () => closeVoiceCall(), - icon: Icon(Icons.phone_disabled_rounded, color: Colors.white), - text: "Stop voice call", - textColor: Colors.white), + child: buildButton( + context, + color: Colors.red, + onClick: () => closeVoiceCall(), + icon: Icon( + FluentIcons.call_end_20_filled, + color: Colors.white, + size: 14, + ), + text: "Stop voice call", + textColor: Colors.white, + ), ), Offstage( offstage: !client.incomingVoiceCall, @@ -635,18 +647,27 @@ class _CmControlPanel extends StatelessWidget { child: buildButton(context, color: MyTheme.accent, onClick: () => handleVoiceCall(true), - icon: Icon(Icons.phone_enabled, color: Colors.white), + icon: Icon( + FluentIcons.call_20_filled, + color: Colors.white, + size: 14, + ), text: "Accept", textColor: Colors.white), ), Expanded( - child: buildButton(context, - color: Colors.red, - onClick: () => handleVoiceCall(false), - icon: - Icon(Icons.phone_disabled_rounded, color: Colors.white), - text: "Dismiss", - textColor: Colors.white), + child: buildButton( + context, + color: Colors.red, + onClick: () => handleVoiceCall(false), + icon: Icon( + FluentIcons.call_dismiss_20_filled, + color: Colors.white, + size: 14, + ), + text: "Dismiss", + textColor: Colors.white, + ), ) ], ), @@ -662,16 +683,21 @@ class _CmControlPanel extends StatelessWidget { ), Offstage( offstage: !showElevation, - child: buildButton(context, color: Colors.green[700], onClick: () { - handleElevate(context); - windowManager.minimize(); - }, - icon: Icon( - Icons.security_sharp, - color: Colors.white, - ), - text: 'Elevate', - textColor: Colors.white), + child: buildButton( + context, + color: MyTheme.accent, + onClick: () { + handleElevate(context); + windowManager.minimize(); + }, + icon: Icon( + FluentIcons.shield_checkmark_20_filled, + color: Colors.white, + size: 14, + ), + text: 'Elevate', + textColor: Colors.white, + ), ), Row( children: [ @@ -690,9 +716,7 @@ class _CmControlPanel extends StatelessWidget { ], ) ], - ) - .marginOnly(bottom: showElevation ? 0 : bigMargin) - .marginSymmetric(horizontal: showElevation ? 0 : bigMargin); + ).marginOnly(bottom: buttonBottomMargin); } buildDisconnected(BuildContext context) { @@ -706,7 +730,7 @@ class _CmControlPanel extends StatelessWidget { text: 'Close', textColor: Colors.white)), ], - ).marginOnly(bottom: 15).marginSymmetric(horizontal: bigMargin); + ).marginOnly(bottom: buttonBottomMargin); } buildUnAuthorized(BuildContext context) { @@ -728,8 +752,9 @@ class _CmControlPanel extends StatelessWidget { }, text: 'Accept', icon: Icon( - Icons.security_sharp, + FluentIcons.shield_checkmark_20_filled, color: Colors.white, + size: 14, ), textColor: Colors.white), ), @@ -740,26 +765,33 @@ class _CmControlPanel extends StatelessWidget { Expanded( child: Column( children: [ - buildButton(context, color: MyTheme.accent, onClick: () { - handleAccept(context); - windowManager.minimize(); - }, text: 'Accept', textColor: Colors.white), + buildButton( + context, + color: MyTheme.accent, + onClick: () { + handleAccept(context); + windowManager.minimize(); + }, + text: 'Accept', + textColor: Colors.white, + ), ], ), ), Expanded( - child: buildButton(context, - color: Colors.transparent, - border: Border.all(color: Colors.grey), - onClick: handleDisconnect, - text: 'Cancel', - textColor: null)), + child: buildButton( + context, + color: Colors.transparent, + border: Border.all(color: Colors.grey), + onClick: handleDisconnect, + text: 'Cancel', + textColor: null, + ), + ), ], ), ], - ) - .marginOnly(bottom: showElevation ? 0 : bigMargin) - .marginSymmetric(horizontal: showElevation ? 0 : bigMargin); + ).marginOnly(bottom: buttonBottomMargin); } Widget buildButton( @@ -788,7 +820,7 @@ class _CmControlPanel extends StatelessWidget { ); } return Container( - height: 30, + height: 28, decoration: BoxDecoration( color: color, borderRadius: BorderRadius.circular(10.0), diff --git a/flutter/lib/models/chat_model.dart b/flutter/lib/models/chat_model.dart index 99ffcd220..6b3379310 100644 --- a/flutter/lib/models/chat_model.dart +++ b/flutter/lib/models/chat_model.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:dash_chat_2/dash_chat_2.dart'; import 'package:draggable_float_widget/draggable_float_widget.dart'; +import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/models/platform_model.dart'; import 'package:get/get_rx/src/rx_types/rx_types.dart'; @@ -104,21 +105,23 @@ class ChatModel with ChangeNotifier { final overlay = OverlayEntry(builder: (context) { return DraggableFloatWidget( - config: DraggableFloatWidgetBaseConfig( - initPositionYInTop: false, - initPositionYMarginBorder: 100, - borderTopContainTopBar: true, - ), - child: FloatingActionButton( - onPressed: () { - if (chatWindowOverlayEntry == null) { - showChatWindowOverlay(); - } else { - hideChatWindowOverlay(); - } - }, - backgroundColor: Theme.of(context).colorScheme.primary, - child: Icon(Icons.message))); + config: DraggableFloatWidgetBaseConfig( + initPositionYInTop: false, + initPositionYMarginBorder: 100, + borderTopContainTopBar: true, + ), + child: FloatingActionButton( + onPressed: () { + if (chatWindowOverlayEntry == null) { + showChatWindowOverlay(); + } else { + hideChatWindowOverlay(); + } + }, + backgroundColor: Theme.of(context).colorScheme.primary, + child: Icon(FluentIcons.chat_24_filled), + ), + ); }); overlayState.insert(overlay); chatIconOverlayEntry = overlay; diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 273c4fe58..e1db03f27 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -288,8 +288,8 @@ class ServerModel with ChangeNotifier { /// Toggle the screen sharing service. toggleService() async { if (_isStart) { - final res = - await parent.target?.dialogManager.show((setState, close, context) { + final res = await parent.target?.dialogManager + .show((setState, close, context) { submit() => close(true); return CustomAlertDialog( title: Row(children: [ @@ -311,8 +311,8 @@ class ServerModel with ChangeNotifier { stopService(); } } else { - final res = - await parent.target?.dialogManager.show((setState, close, context) { + final res = await parent.target?.dialogManager + .show((setState, close, context) { submit() => close(true); return CustomAlertDialog( title: Row(children: [ From 0b1fdffdcc155d7eb7401a39a0c294fcc72a6e3d Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Sat, 20 May 2023 18:30:13 +0200 Subject: [PATCH 07/11] grey disabled permissions --- flutter/lib/desktop/pages/server_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index 184fd5a2a..f0b797aff 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -461,7 +461,7 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { message: tooltipText, child: Container( decoration: BoxDecoration( - color: enabled ? MyTheme.accent : Colors.blueGrey, + color: enabled ? MyTheme.accent : Colors.grey[700], borderRadius: BorderRadius.circular(10.0), ), padding: EdgeInsets.all(4.0), From a84e774dc03578f5db6f03838911b4cb10949f5e Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Sat, 20 May 2023 18:32:01 +0200 Subject: [PATCH 08/11] removed unused icons --- flutter/assets/audio.svg | 1 - flutter/assets/clipboard.svg | 1 - flutter/assets/restart.svg | 1 - 3 files changed, 3 deletions(-) delete mode 100644 flutter/assets/audio.svg delete mode 100644 flutter/assets/clipboard.svg delete mode 100644 flutter/assets/restart.svg diff --git a/flutter/assets/audio.svg b/flutter/assets/audio.svg deleted file mode 100644 index ba12b34e6..000000000 --- a/flutter/assets/audio.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/flutter/assets/clipboard.svg b/flutter/assets/clipboard.svg deleted file mode 100644 index d2230845d..000000000 --- a/flutter/assets/clipboard.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/flutter/assets/restart.svg b/flutter/assets/restart.svg deleted file mode 100644 index 21a085569..000000000 --- a/flutter/assets/restart.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 52f1e062572ed4cf9db3c49c41666fecc5f7986c Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Sat, 20 May 2023 18:33:40 +0200 Subject: [PATCH 09/11] removed unused text --- flutter/lib/desktop/pages/server_page.dart | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index f0b797aff..0ae067d64 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -456,7 +456,7 @@ class _PrivilegeBoard extends StatefulWidget { class _PrivilegeBoardState extends State<_PrivilegeBoard> { late final client = widget.client; Widget buildPermissionIcon(bool enabled, IconData iconData, - Function(bool)? onTap, String permissionText, String tooltipText) { + Function(bool)? onTap, String tooltipText) { return Tooltip( message: tooltipText, child: Container( @@ -522,7 +522,6 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { client.keyboard = enabled; }); }, - translate("Input Control"), translate('Allow using keyboard and mouse'), ), buildPermissionIcon( @@ -535,7 +534,6 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { client.clipboard = enabled; }); }, - translate("Clipboard"), translate('Allow using clipboard'), ), buildPermissionIcon( @@ -548,7 +546,6 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { client.audio = enabled; }); }, - translate("Audio"), translate('Allow hearing sound'), ), buildPermissionIcon( @@ -561,7 +558,6 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { client.file = enabled; }); }, - translate("File"), translate('Allow file copy and paste'), ), buildPermissionIcon( @@ -574,7 +570,6 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { client.restart = enabled; }); }, - translate("Restart"), translate('Allow remote restart'), ), buildPermissionIcon( @@ -587,7 +582,6 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { client.recording = enabled; }); }, - translate("Recording"), translate('Allow recording session'), ) ], From 9374188ea98c8ed7b7a133fabb37462b7bb28bdf Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Sun, 21 May 2023 10:20:40 +0200 Subject: [PATCH 10/11] replaced hardcoded chatpage size with expanded, alignment adjustments --- flutter/lib/common/widgets/chat_page.dart | 2 +- flutter/lib/desktop/pages/server_page.dart | 65 ++++++++++++---------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/flutter/lib/common/widgets/chat_page.dart b/flutter/lib/common/widgets/chat_page.dart index a88e120f1..751178ea6 100644 --- a/flutter/lib/common/widgets/chat_page.dart +++ b/flutter/lib/common/widgets/chat_page.dart @@ -48,7 +48,7 @@ class ChatPage extends StatelessWidget implements PageShape { value: chatModel, child: Container( color: Theme.of(context).scaffoldBackgroundColor, - padding: EdgeInsets.all(20.0), + padding: EdgeInsets.only(top: 14.0, bottom: 14.0, left: 14.0), child: Consumer( builder: (context, chatModel, child) { final currentUser = chatModel.currentUser; diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index 0ae067d64..5c345d50d 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -81,14 +81,7 @@ class _DesktopServerPageState extends State border: Border.all(color: MyTheme.color(context).border!)), child: Scaffold( backgroundColor: Theme.of(context).scaffoldBackgroundColor, - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded(child: ConnectionManager()), - ], - ), - ), + body: ConnectionManager(), ), ), ), @@ -170,11 +163,22 @@ class ConnectionManagerState extends State { pageViewBuilder: (pageView) => Row( children: [ Consumer( - builder: (_, model, child) => model.isShowCMChatPage - ? Container( - width: 400, child: Scaffold(body: ChatPage())) - : Offstage()), - Expanded(child: pageView), + builder: (_, model, child) => model.isShowCMChatPage + ? Expanded( + child: ChatPage(), + flex: (kConnectionManagerWindowSizeOpenChat.width - + kConnectionManagerWindowSizeClosedChat + .width) + .toInt(), + ) + : Offstage(), + ), + Expanded( + child: pageView, + flex: kConnectionManagerWindowSizeClosedChat.width + .toInt() - + 4 // prevent stretch of the page view when chat is open, + ), ], ), ), @@ -246,23 +250,24 @@ class ConnectionManagerState extends State { Widget buildConnectionCard(Client client) { return Consumer( - builder: (context, value, child) => Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - key: ValueKey(client.id), - children: [ - _CmHeader(client: client), - client.type_() != ClientType.remote || client.disconnected - ? Offstage() - : _PrivilegeBoard(client: client), - Expanded( - child: Align( - alignment: Alignment.bottomCenter, - child: _CmControlPanel(client: client), - ), - ) - ], - ).paddingSymmetric(vertical: 8.0, horizontal: 8.0)); + builder: (context, value, child) => Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + key: ValueKey(client.id), + children: [ + _CmHeader(client: client), + client.type_() != ClientType.remote || client.disconnected + ? Offstage() + : _PrivilegeBoard(client: client), + Expanded( + child: Align( + alignment: Alignment.bottomCenter, + child: _CmControlPanel(client: client), + ), + ) + ], + ).paddingSymmetric(vertical: 4.0, horizontal: 8.0), + ); } class _AppIcon extends StatelessWidget { From 3da530191cc37efb02e269c3ace5bf5e579037a9 Mon Sep 17 00:00:00 2001 From: NicKoehler Date: Sun, 21 May 2023 14:24:51 +0200 Subject: [PATCH 11/11] added on/off text indicator --- flutter/lib/desktop/pages/server_page.dart | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index 5c345d50d..e5860a4f3 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -469,14 +469,28 @@ class _PrivilegeBoardState extends State<_PrivilegeBoard> { color: enabled ? MyTheme.accent : Colors.grey[700], borderRadius: BorderRadius.circular(10.0), ), - padding: EdgeInsets.all(4.0), + padding: EdgeInsets.all(8.0), child: InkWell( onTap: () => checkClickTime(widget.client.id, () => onTap?.call(!enabled)), - child: Icon( - iconData, - size: 30.0, - color: Colors.white, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Icon( + iconData, + size: 30.0, + color: Colors.white, + ), + Text( + enabled ? "ON" : "OFF", + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.w200, + color: Colors.white, + fontSize: 10.0, + ), + ) + ], ), ), ),