From 2c7f0d7588d403fc7c7e1a26850a6b69cd4fee05 Mon Sep 17 00:00:00 2001 From: csf Date: Thu, 18 Aug 2022 19:49:41 +0800 Subject: [PATCH] fix cm event listener & switch permission --- flutter/lib/common.dart | 10 +- flutter/lib/desktop/pages/server_page.dart | 193 ++++++++------------- flutter/lib/models/server_model.dart | 6 +- src/flutter.rs | 11 +- 4 files changed, 87 insertions(+), 133 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 8570e5b7e..e963993f7 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -29,14 +29,16 @@ int androidVersion = 0; typedef F = String Function(String); typedef FMethod = String Function(String, dynamic); -final iconKeyboard = MemoryImage(Uint8List.fromList(base64Decode( +late 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( +late 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( +late 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( +late 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=='))); +late 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'))); class IconFont { static const _family = 'iconfont'; diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index 32130ad2e..beaf9c1eb 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -2,109 +2,14 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -// import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:provider/provider.dart'; import 'package:window_manager/window_manager.dart'; import '../../common.dart'; -import '../../mobile/pages/home_page.dart'; import '../../models/platform_model.dart'; import '../../models/server_model.dart'; -class DesktopServerPage extends StatefulWidget implements PageShape { - @override - final title = translate("Share Screen"); - - @override - final icon = Icon(Icons.mobile_screen_share); - - @override - final appBarActions = [ - PopupMenuButton( - icon: Icon(Icons.more_vert), - itemBuilder: (context) { - return [ - PopupMenuItem( - child: Text(translate("Change ID")), - padding: EdgeInsets.symmetric(horizontal: 16.0), - value: "changeID", - enabled: false, - ), - PopupMenuItem( - child: Text(translate("Set permanent password")), - padding: EdgeInsets.symmetric(horizontal: 16.0), - value: "setPermanentPassword", - enabled: - gFFI.serverModel.verificationMethod != kUseTemporaryPassword, - ), - PopupMenuItem( - child: Text(translate("Set temporary password length")), - padding: EdgeInsets.symmetric(horizontal: 16.0), - value: "setTemporaryPasswordLength", - enabled: - gFFI.serverModel.verificationMethod != kUsePermanentPassword, - ), - const PopupMenuDivider(), - PopupMenuItem( - padding: EdgeInsets.symmetric(horizontal: 0.0), - value: kUseTemporaryPassword, - child: Container( - child: ListTile( - title: Text(translate("Use temporary password")), - trailing: Icon( - Icons.check, - color: gFFI.serverModel.verificationMethod == - kUseTemporaryPassword - ? null - : Color(0xFFFFFFFF), - ))), - ), - PopupMenuItem( - padding: EdgeInsets.symmetric(horizontal: 0.0), - value: kUsePermanentPassword, - child: ListTile( - title: Text(translate("Use permanent password")), - trailing: Icon( - Icons.check, - color: gFFI.serverModel.verificationMethod == - kUsePermanentPassword - ? null - : Color(0xFFFFFFFF), - )), - ), - PopupMenuItem( - padding: EdgeInsets.symmetric(horizontal: 0.0), - value: kUseBothPasswords, - child: ListTile( - title: Text(translate("Use both passwords")), - trailing: Icon( - Icons.check, - color: gFFI.serverModel.verificationMethod != - kUseTemporaryPassword && - gFFI.serverModel.verificationMethod != - kUsePermanentPassword - ? null - : Color(0xFFFFFFFF), - )), - ), - ]; - }, - onSelected: (value) { - if (value == "changeID") { - // TODO - } else if (value == "setPermanentPassword") { - // setPermanentPasswordDialog(); - } else if (value == "setTemporaryPasswordLength") { - // setTemporaryPasswordLengthDialog(); - } else if (value == kUsePermanentPassword || - value == kUseTemporaryPassword || - value == kUseBothPasswords) { - bind.mainSetOption(key: "verification-method", value: value); - gFFI.serverModel.updatePasswordModel(); - } - }) - ]; - +class DesktopServerPage extends StatefulWidget { @override State createState() => _DesktopServerPageState(); } @@ -112,22 +17,27 @@ class DesktopServerPage extends StatefulWidget implements PageShape { class _DesktopServerPageState extends State with AutomaticKeepAliveClientMixin { @override + void initState() { + gFFI.ffiModel.updateEventListener(""); + super.initState(); + } + Widget build(BuildContext context) { super.build(context); return ChangeNotifierProvider.value( value: gFFI.serverModel, child: Consumer( builder: (context, serverModel, child) => Material( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded(child: ConnectionManager()), - SizedBox.fromSize(size: Size(0, 15.0)), - ], - ), - ), - ))); + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded(child: ConnectionManager()), + SizedBox.fromSize(size: Size(0, 15.0)), + ], + ), + ), + ))); } @override @@ -359,18 +269,24 @@ class _CmHeaderState extends State<_CmHeader> bool get wantKeepAlive => true; } -class _PrivilegeBoard extends StatelessWidget { +class _PrivilegeBoard extends StatefulWidget { final Client client; const _PrivilegeBoard({Key? key, required this.client}) : super(key: key); + @override + State createState() => _PrivilegeBoardState(); +} + +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), + BoxDecoration(color: enabled ? MyTheme.accent80 : Colors.grey), padding: EdgeInsets.all(4.0), child: InkWell( onTap: () => onTap?.call(!enabled), @@ -401,14 +317,41 @@ class _PrivilegeBoard extends StatelessWidget { ), Row( children: [ - buildPermissionIcon( - client.keyboard, iconKeyboard, (enable) => null, null), - buildPermissionIcon( - client.clipboard, iconClipboard, (enable) => null, null), - buildPermissionIcon( - client.audio, iconAudio, (enable) => null, null), - // TODO: file transfer - buildPermissionIcon(false, iconFile, (enable) => null, null), + buildPermissionIcon(client.keyboard, iconKeyboard, (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "keyboard", enabled: enabled); + setState(() { + client.keyboard = enabled; + }); + }, null), + buildPermissionIcon(client.clipboard, iconClipboard, (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "clipboard", enabled: enabled); + setState(() { + client.clipboard = enabled; + }); + }, null), + buildPermissionIcon(client.audio, iconAudio, (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "audio", enabled: enabled); + setState(() { + client.audio = enabled; + }); + }, null), + buildPermissionIcon(client.file, iconFile, (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "file", enabled: enabled); + setState(() { + client.file = enabled; + }); + }, null), + buildPermissionIcon(client.restart, iconRestart, (enabled) { + bind.cmSwitchPermission( + connId: client.id, name: "restart", enabled: enabled); + setState(() { + client.restart = enabled; + }); + }, null), ], ), ], @@ -530,9 +473,9 @@ class PaddingCard extends StatelessWidget { children: [ titleIcon != null ? Padding( - padding: EdgeInsets.only(right: 10), - child: Icon(titleIcon, - color: MyTheme.accent80, size: 30)) + padding: EdgeInsets.only(right: 10), + child: Icon(titleIcon, + color: MyTheme.accent80, size: 30)) : SizedBox.shrink(), Text( title!, @@ -579,12 +522,12 @@ Widget clientInfo(Client client) { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(client.name, - style: TextStyle(color: MyTheme.idColor, fontSize: 18)), - SizedBox(width: 8), - Text(client.peerId, - style: TextStyle(color: MyTheme.idColor, fontSize: 10)) - ])) + Text(client.name, + style: TextStyle(color: MyTheme.idColor, fontSize: 18)), + SizedBox(width: 8), + Text(client.peerId, + style: TextStyle(color: MyTheme.idColor, fontSize: 10)) + ])) ], ), ])); diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 0bbb0c13e..9f69dd04a 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -366,7 +366,7 @@ class ServerModel with ChangeNotifier { _clients[client.id] = client; scrollToBottom(); notifyListeners(); - showLoginDialog(client); + if (isAndroid) showLoginDialog(client); } catch (e) { debugPrint("Failed to call loginRequest,error:$e"); } @@ -483,6 +483,8 @@ class Client { bool keyboard = false; bool clipboard = false; bool audio = false; + bool file = false; + bool restart = false; Client(this.authorized, this.isFileTransfer, this.name, this.peerId, this.keyboard, this.clipboard, this.audio); @@ -496,6 +498,8 @@ class Client { keyboard = json['keyboard']; clipboard = json['clipboard']; audio = json['audio']; + file = json['file']; + restart = json['restart']; } Map toJson() { diff --git a/src/flutter.rs b/src/flutter.rs index 928be607d..dfdef8c5a 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -41,6 +41,7 @@ use crate::{client::*, flutter_ffi::EventToUI, make_fd_flutter}; pub(super) const APP_TYPE_MAIN: &str = "main"; pub(super) const APP_TYPE_DESKTOP_REMOTE: &str = "remote"; pub(super) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer"; +pub(super) const APP_TYPE_DESKTOP_CONNECTION_MANAGER: &str = "connection manager"; lazy_static::lazy_static! { // static ref SESSION: Arc>> = Default::default(); @@ -1678,6 +1679,8 @@ pub mod connection_manager { keyboard: bool, clipboard: bool, audio: bool, + file: bool, + restart: bool, #[serde(skip)] tx: UnboundedSender, } @@ -1885,8 +1888,8 @@ pub mod connection_manager { keyboard: bool, clipboard: bool, audio: bool, - _file: bool, - _restart: bool, + file: bool, + restart: bool, tx: mpsc::UnboundedSender, ) { let mut client = Client { @@ -1898,6 +1901,8 @@ pub mod connection_manager { keyboard, clipboard, audio, + file, + restart, tx, }; if authorized { @@ -1935,7 +1940,7 @@ pub mod connection_manager { if let Some(s) = GLOBAL_EVENT_STREAM .read() .unwrap() - .get(super::APP_TYPE_MAIN) + .get(super::APP_TYPE_DESKTOP_CONNECTION_MANAGER) { s.add(serde_json::ser::to_string(&h).unwrap_or("".to_owned())); };