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'), + ) ], )), ],