From 0ef1659b8784608e4a56552514d5ca158015cbf1 Mon Sep 17 00:00:00 2001 From: csf Date: Fri, 5 Aug 2022 20:29:43 +0800 Subject: [PATCH] fix mobile features --- flutter/lib/common.dart | 17 +++ flutter/lib/desktop/pages/remote_page.dart | 26 ----- flutter/lib/mobile/pages/home_page.dart | 6 +- flutter/lib/mobile/pages/remote_page.dart | 119 +++++++++----------- flutter/lib/mobile/pages/settings_page.dart | 26 ++--- flutter/lib/models/model.dart | 9 +- 6 files changed, 89 insertions(+), 114 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index f49440655..16e8a172e 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -352,6 +352,23 @@ RadioListTile getRadio( ); } +CheckboxListTile getToggle( + String id, void Function(void Function()) setState, option, name) { + final opt = bind.getSessionToggleOptionSync(id: id, arg: option); + return CheckboxListTile( + value: opt, + onChanged: (v) { + setState(() { + bind.sessionToggleOption(id: id, value: option); + }); + if (option == "show-quality-monitor") { + gFFI.qualityMonitorModel.checkShowQualityMonitor(id); + } + }, + dense: true, + title: Text(translate(name))); +} + /// find ffi, tag is Remote ID /// for session specific usage FFI ffi(String? tag) { diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index ed62e5067..bfc193a89 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -887,32 +887,6 @@ class ImagePainter extends CustomPainter { } } -CheckboxListTile getToggle( - String id, void Function(void Function()) setState, option, name) { - final opt = bind.getSessionToggleOptionSync(id: id, arg: option); - return CheckboxListTile( - value: opt, - onChanged: (v) { - setState(() { - bind.sessionToggleOption(id: id, value: option); - }); - }, - dense: true, - title: Text(translate(name))); -} - -RadioListTile getRadio(String name, String toValue, String curValue, - void Function(String?) onChange) { - return RadioListTile( - controlAffinity: ListTileControlAffinity.trailing, - title: Text(translate(name)), - value: toValue, - groupValue: curValue, - onChanged: onChange, - dense: true, - ); -} - void showOptions(String id) async { String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced'; if (quality == '') quality = 'balanced'; diff --git a/flutter/lib/mobile/pages/home_page.dart b/flutter/lib/mobile/pages/home_page.dart index e56434487..6bf0be2c7 100644 --- a/flutter/lib/mobile/pages/home_page.dart +++ b/flutter/lib/mobile/pages/home_page.dart @@ -12,10 +12,10 @@ abstract class PageShape extends Widget { final List appBarActions = []; } -final homeKey = GlobalKey<_HomePageState>(); - class HomePage extends StatefulWidget { - HomePage({Key? key}) : super(key: key); + static final homeKey = GlobalKey<_HomePageState>(); + + HomePage() : super(key: homeKey); @override _HomePageState createState() => _HomePageState(); diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index 980f665e7..6ea4ca2e6 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -12,6 +12,7 @@ import 'package:wakelock/wakelock.dart'; import '../../common.dart'; import '../../models/model.dart'; +import '../../models/platform_model.dart'; import '../widgets/dialog.dart'; import '../widgets/gestures.dart'; import '../widgets/overlay.dart'; @@ -135,7 +136,7 @@ class _RemotePageState extends State { if (newValue.length > common) { var s = newValue.substring(common); if (s.length > 1) { - gFFI.setByName('input_string', s); + bind.sessionInputString(id: widget.id, value: s); } else { inputChar(s); } @@ -169,11 +170,11 @@ class _RemotePageState extends State { content == '()' || content == '【】')) { // can not only input content[0], because when input ], [ are also auo insert, which cause ] never be input - gFFI.setByName('input_string', content); + bind.sessionInputString(id: widget.id, value: content); openKeyboard(); return; } - gFFI.setByName('input_string', content); + bind.sessionInputString(id: widget.id, value: content); } else { inputChar(content); } @@ -409,7 +410,7 @@ class _RemotePageState extends State { icon: Icon(Icons.tv), onPressed: () { setState(() => _showEdit = false); - showOptions(); + showOptions(widget.id); }, ) ] + @@ -461,7 +462,7 @@ class _RemotePageState extends State { icon: Icon(Icons.more_vert), onPressed: () { setState(() => _showEdit = false); - showActions(); + showActions(widget.id); }, ), ]), @@ -573,7 +574,7 @@ class _RemotePageState extends State { }, onTwoFingerScaleEnd: (d) { _scale = 1; - gFFI.setByName('peer_option', '{"name": "view-style", "value": ""}'); + bind.sessionPeerOption(id: widget.id, name: "view-style", value: ""); }, onThreeFingerVerticalDragUpdate: gFFI.ffiModel.isPeerAndroid ? null @@ -620,8 +621,9 @@ class _RemotePageState extends State { Widget getBodyForDesktopWithListener(bool keyboard) { var paints = [ImagePaint()]; - if (keyboard || - gFFI.getByName('toggle_option', 'show-remote-cursor') == 'true') { + final cursor = bind.getSessionToggleOptionSync( + id: widget.id, arg: 'show-remote-cursor'); + if (keyboard || cursor) { paints.add(CursorPaint()); } return Container( @@ -649,7 +651,7 @@ class _RemotePageState extends State { return out; } - void showActions() { + void showActions(String id) async { final size = MediaQuery.of(context).size; final x = 120.0; final y = size.height; @@ -668,7 +670,7 @@ class _RemotePageState extends State { style: flatButtonStyle, onPressed: () { Navigator.pop(context); - showSetOSPassword(false); + showSetOSPassword(id, false); }, child: Icon(Icons.edit, color: MyTheme.accent), ) @@ -691,7 +693,8 @@ class _RemotePageState extends State { more.add(PopupMenuItem( child: Text(translate('Insert Lock')), value: 'lock')); if (pi.platform == 'Windows' && - gFFI.getByName('toggle_option', 'privacy-mode') != 'true') { + await bind.getSessionToggleOption(id: id, arg: 'privacy-mode') != + true) { more.add(PopupMenuItem( child: Text(translate((gFFI.ffiModel.inputBlocked ? 'Unb' : 'B') + 'lock user input')), @@ -713,28 +716,29 @@ class _RemotePageState extends State { elevation: 8, ); if (value == 'cad') { - gFFI.setByName('ctrl_alt_del'); + bind.sessionCtrlAltDel(id: widget.id); } else if (value == 'lock') { - gFFI.setByName('lock_screen'); + bind.sessionLockScreen(id: widget.id); } else if (value == 'block-input') { - gFFI.setByName('toggle_option', - (gFFI.ffiModel.inputBlocked ? 'un' : '') + 'block-input'); + bind.sessionToggleOption( + id: widget.id, + value: (gFFI.ffiModel.inputBlocked ? 'un' : '') + 'block-input'); gFFI.ffiModel.inputBlocked = !gFFI.ffiModel.inputBlocked; } else if (value == 'refresh') { - gFFI.setByName('refresh'); + bind.sessionRefresh(id: widget.id); } else if (value == 'paste') { () async { ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain); if (data != null && data.text != null) { - gFFI.setByName('input_string', '${data.text}'); + bind.sessionInputString(id: widget.id, value: data.text ?? ""); } }(); } else if (value == 'enter_os_password') { - var password = gFFI.getByName('peer_option', "os-password"); - if (password != "") { - gFFI.setByName('input_os_password', password); + var password = await bind.getSessionOption(id: id, arg: "os-password"); + if (password != null) { + bind.sessionInputOsPassword(id: widget.id, value: password); } else { - showSetOSPassword(true); + showSetOSPassword(id, true); } } else if (value == 'reset_canvas') { gFFI.cursorModel.reset(); @@ -762,8 +766,8 @@ class _RemotePageState extends State { onTouchModeChange: (t) { gFFI.ffiModel.toggleTouchMode(); final v = gFFI.ffiModel.touchMode ? 'Y' : ''; - gFFI.setByName('peer_option', - '{"name": "touch-mode", "value": "$v"}'); + bind.sessionPeerOption( + id: widget.id, name: "touch", value: v); })); })); } @@ -978,23 +982,23 @@ class QualityMonitor extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Speed: ${qualityMonitorModel.data.speed}", + "Speed: ${qualityMonitorModel.data.speed ?? ''}", style: TextStyle(color: MyTheme.grayBg), ), Text( - "FPS: ${qualityMonitorModel.data.fps}", + "FPS: ${qualityMonitorModel.data.fps ?? ''}", style: TextStyle(color: MyTheme.grayBg), ), Text( - "Delay: ${qualityMonitorModel.data.delay} ms", + "Delay: ${qualityMonitorModel.data.delay ?? ''} ms", style: TextStyle(color: MyTheme.grayBg), ), Text( - "Target Bitrate: ${qualityMonitorModel.data.targetBitrate}kb", + "Target Bitrate: ${qualityMonitorModel.data.targetBitrate ?? ''}kb", style: TextStyle(color: MyTheme.grayBg), ), Text( - "Codec: ${qualityMonitorModel.data.codecFormat}", + "Codec: ${qualityMonitorModel.data.codecFormat ?? ''}", style: TextStyle(color: MyTheme.grayBg), ), ], @@ -1003,26 +1007,11 @@ class QualityMonitor extends StatelessWidget { : SizedBox.shrink()))); } -CheckboxListTile getToggle( - void Function(void Function()) setState, option, name) { - return CheckboxListTile( - value: gFFI.getByName('toggle_option', option) == 'true', - onChanged: (v) { - setState(() { - gFFI.setByName('toggle_option', option); - }); - if (option == "show-quality-monitor") { - gFFI.qualityMonitorModel.checkShowQualityMonitor(); - } - }, - dense: true, - title: Text(translate(name))); -} - -void showOptions() { - String quality = gFFI.getByName('image_quality'); +void showOptions(String id) async { + String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced'; if (quality == '') quality = 'balanced'; - String viewStyle = gFFI.getByName('peer_option', 'view-style'); + String viewStyle = + await bind.getSessionOption(id: id, arg: 'view-style') ?? ''; var displays = []; final pi = gFFI.ffiModel.pi; final image = gFFI.ffiModel.getConnectionImage(); @@ -1035,7 +1024,7 @@ void showOptions() { children.add(InkWell( onTap: () { if (i == cur) return; - gFFI.setByName('switch_display', i.toString()); + bind.sessionSwitchDisplay(id: id, value: i); SmartDialog.dismiss(); }, child: Ink( @@ -1064,30 +1053,30 @@ void showOptions() { DialogManager.show((setState, close) { final more = []; if (perms['audio'] != false) { - more.add(getToggle(setState, 'disable-audio', 'Mute')); + more.add(getToggle(id, setState, 'disable-audio', 'Mute')); } if (perms['keyboard'] != false) { if (perms['clipboard'] != false) - more.add(getToggle(setState, 'disable-clipboard', 'Disable clipboard')); + more.add( + getToggle(id, setState, 'disable-clipboard', 'Disable clipboard')); more.add(getToggle( - setState, 'lock-after-session-end', 'Lock after session end')); + id, setState, 'lock-after-session-end', 'Lock after session end')); if (pi.platform == 'Windows') { - more.add(getToggle(setState, 'privacy-mode', 'Privacy mode')); + more.add(getToggle(id, setState, 'privacy-mode', 'Privacy mode')); } } var setQuality = (String? value) { if (value == null) return; setState(() { quality = value; - gFFI.setByName('image_quality', value); + bind.sessionSetImageQuality(id: id, value: value); }); }; var setViewStyle = (String? value) { if (value == null) return; setState(() { viewStyle = value; - gFFI.setByName( - 'peer_option', '{"name": "view-style", "value": "$value"}'); + bind.sessionPeerOption(id: id, name: "view-style", value: value); gFFI.canvasModel.updateViewStyle(); }); }; @@ -1105,9 +1094,10 @@ void showOptions() { getRadio('Balanced', 'balanced', quality, setQuality), getRadio('Optimize reaction time', 'low', quality, setQuality), Divider(color: MyTheme.border), - getToggle(setState, 'show-remote-cursor', 'Show remote cursor'), getToggle( - setState, 'show-quality-monitor', 'Show quality monitor'), + id, setState, 'show-remote-cursor', 'Show remote cursor'), + getToggle(id, setState, 'show-quality-monitor', + 'Show quality monitor'), ] + more), actions: [], @@ -1137,10 +1127,10 @@ void showRestartRemoteDevice(PeerInfo pi, String id) async { if (res == true) gFFI.setByName('restart_remote_device'); } -void showSetOSPassword(bool login) { +void showSetOSPassword(String id, bool login) async { final controller = TextEditingController(); - var password = gFFI.getByName('peer_option', "os-password"); - var autoLogin = gFFI.getByName('peer_option', "auto-login") != ""; + var password = await bind.getSessionOption(id: id, arg: "os-password") ?? ""; + var autoLogin = await bind.getSessionOption(id: id, arg: "auto-login") != ""; controller.text = password; DialogManager.show((setState, close) { return CustomAlertDialog( @@ -1173,12 +1163,11 @@ void showSetOSPassword(bool login) { style: flatButtonStyle, onPressed: () { var text = controller.text.trim(); - gFFI.setByName( - 'peer_option', '{"name": "os-password", "value": "$text"}'); - gFFI.setByName('peer_option', - '{"name": "auto-login", "value": "${autoLogin ? 'Y' : ''}"}'); + bind.sessionPeerOption(id: id, name: "os-password", value: text); + bind.sessionPeerOption( + id: id, name: "auto-login", value: autoLogin ? 'Y' : ''); if (text != "" && login) { - gFFI.setByName('input_os_password', text); + bind.sessionInputOsPassword(id: id, value: text); } close(); }, diff --git a/flutter/lib/mobile/pages/settings_page.dart b/flutter/lib/mobile/pages/settings_page.dart index ab7b2584d..01cf4ae5d 100644 --- a/flutter/lib/mobile/pages/settings_page.dart +++ b/flutter/lib/mobile/pages/settings_page.dart @@ -9,6 +9,7 @@ import 'package:url_launcher/url_launcher.dart'; import '../../common.dart'; import '../../models/model.dart'; +import '../../models/platform_model.dart'; import '../widgets/dialog.dart'; import 'home_page.dart'; import 'scan_page.dart'; @@ -192,21 +193,18 @@ void showServerSettings() { showServerSettingsWithValue(id, relay, key, api); } -void showLanguageSettings() { +void showLanguageSettings() async { try { final langs = json.decode(gFFI.getByName('langs')) as List; - var lang = gFFI.getByName('local_option', 'lang'); + var lang = await bind.mainGetLocalOption(key: "lang"); DialogManager.show((setState, close) { final setLang = (v) { if (lang != v) { setState(() { lang = v; }); - final msg = Map() - ..['name'] = 'lang' - ..['value'] = v; - gFFI.setByName('local_option', json.encode(msg)); - homeKey.currentState?.refreshPages(); + bind.mainSetLocalOption(key: "lang", value: v); + HomePage.homeKey.currentState?.refreshPages(); Future.delayed(Duration(milliseconds: 200), close); } }; @@ -277,8 +275,8 @@ fetch('http://localhost:21114/api/login', { final body = { 'username': name, 'password': pass, - 'id': gFFI.getByName('server_id'), - 'uuid': gFFI.getByName('uuid') + 'id': bind.mainGetMyId(), + 'uuid': bind.mainGetUuid() }; try { final response = await http.post(Uri.parse('$url/api/login'), @@ -314,10 +312,7 @@ void refreshCurrentUser() async { final token = gFFI.getByName("option", "access_token"); if (token == '') return; final url = getUrl(); - final body = { - 'id': gFFI.getByName('server_id'), - 'uuid': gFFI.getByName('uuid') - }; + final body = {'id': bind.mainGetMyId(), 'uuid': bind.mainGetUuid()}; try { final response = await http.post(Uri.parse('$url/api/currentUser'), headers: { @@ -340,10 +335,7 @@ void logout() async { final token = gFFI.getByName("option", "access_token"); if (token == '') return; final url = getUrl(); - final body = { - 'id': gFFI.getByName('server_id'), - 'uuid': gFFI.getByName('uuid') - }; + final body = {'id': bind.mainGetMyId(), 'uuid': bind.mainGetUuid()}; try { await http.post(Uri.parse('$url/api/logout'), headers: { diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 612dd04ac..f67d0d5fa 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -171,6 +171,8 @@ class FfiModel with ChangeNotifier { parent.target?.serverModel.onClientAuthorized(evt); } else if (name == 'on_client_remove') { parent.target?.serverModel.onClientRemove(evt); + } else if (name == 'update_quality_status') { + parent.target?.qualityMonitorModel.updateQualityStatus(evt); } }; } @@ -807,9 +809,10 @@ class QualityMonitorModel with ChangeNotifier { bool get show => _show; QualityMonitorData get data => _data; - checkShowQualityMonitor() { - final show = - gFFI.getByName('toggle_option', 'show-quality-monitor') == 'true'; + checkShowQualityMonitor(String id) async { + final show = await bind.getSessionToggleOption( + id: id, arg: 'show-quality-monitor') == + true; if (_show != show) { _show = show; notifyListeners();