commit
						522c865096
					
				| @ -118,7 +118,9 @@ void window_on_top(int? id) { | |||||||
|     windowManager.show(); |     windowManager.show(); | ||||||
|     windowManager.focus(); |     windowManager.focus(); | ||||||
|   } else { |   } else { | ||||||
|     WindowController.fromWindowId(id)..focus()..show(); |     WindowController.fromWindowId(id) | ||||||
|  |       ..focus() | ||||||
|  |       ..show(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,11 +8,9 @@ import 'package:flutter_hbb/desktop/widgets/peer_widget.dart'; | |||||||
| import 'package:flutter_hbb/utils/multi_window_manager.dart'; | import 'package:flutter_hbb/utils/multi_window_manager.dart'; | ||||||
| import 'package:get/get.dart'; | import 'package:get/get.dart'; | ||||||
| import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||||
| import 'package:url_launcher/url_launcher.dart'; |  | ||||||
| import 'package:url_launcher/url_launcher_string.dart'; | import 'package:url_launcher/url_launcher_string.dart'; | ||||||
| 
 | 
 | ||||||
| import '../../common.dart'; | import '../../common.dart'; | ||||||
| import '../../mobile/pages/home_page.dart'; |  | ||||||
| import '../../mobile/pages/scan_page.dart'; | import '../../mobile/pages/scan_page.dart'; | ||||||
| import '../../mobile/pages/settings_page.dart'; | import '../../mobile/pages/settings_page.dart'; | ||||||
| import '../../models/model.dart'; | import '../../models/model.dart'; | ||||||
| @ -21,18 +19,9 @@ import '../../models/platform_model.dart'; | |||||||
| // enum RemoteType { recently, favorite, discovered, addressBook } | // enum RemoteType { recently, favorite, discovered, addressBook } | ||||||
| 
 | 
 | ||||||
| /// Connection page for connecting to a remote peer. | /// Connection page for connecting to a remote peer. | ||||||
| class ConnectionPage extends StatefulWidget implements PageShape { | class ConnectionPage extends StatefulWidget { | ||||||
|   ConnectionPage({Key? key}) : super(key: key); |   ConnectionPage({Key? key}) : super(key: key); | ||||||
| 
 | 
 | ||||||
|   @override |  | ||||||
|   final icon = Icon(Icons.connected_tv); |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   final title = translate("Connection"); |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   final appBarActions = !isAndroid ? <Widget>[WebMenu()] : <Widget>[]; |  | ||||||
| 
 |  | ||||||
|   @override |   @override | ||||||
|   _ConnectionPageState createState() => _ConnectionPageState(); |   _ConnectionPageState createState() => _ConnectionPageState(); | ||||||
| } | } | ||||||
| @ -174,8 +163,8 @@ class _ConnectionPageState extends State<ConnectionPage> { | |||||||
|         : InkWell( |         : InkWell( | ||||||
|             onTap: () async { |             onTap: () async { | ||||||
|               final url = _updateUrl + '.apk'; |               final url = _updateUrl + '.apk'; | ||||||
|               if (await canLaunch(url)) { |               if (await canLaunchUrlString(url)) { | ||||||
|                 await launch(url); |                 await launchUrlString(url); | ||||||
|               } |               } | ||||||
|             }, |             }, | ||||||
|             child: Container( |             child: Container( | ||||||
| @ -387,13 +376,20 @@ class _ConnectionPageState extends State<ConnectionPage> { | |||||||
|       width: 8, |       width: 8, | ||||||
|       decoration: BoxDecoration( |       decoration: BoxDecoration( | ||||||
|         borderRadius: BorderRadius.circular(20), |         borderRadius: BorderRadius.circular(20), | ||||||
|         color: Colors.green, |         color: svcStopped.value ? Colors.redAccent : Colors.green, | ||||||
|       ), |       ), | ||||||
|     ).paddingSymmetric(horizontal: 8.0); |     ).paddingSymmetric(horizontal: 10.0); | ||||||
|     if (svcStopped.value) { |     if (svcStopped.value) { | ||||||
|       return Row( |       return Row( | ||||||
|         crossAxisAlignment: CrossAxisAlignment.center, |         crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|         children: [light, Text(translate("Service is not running"))], |         children: [ | ||||||
|  |           light, | ||||||
|  |           Text(translate("Service is not running")), | ||||||
|  |           TextButton( | ||||||
|  |               onPressed: () => | ||||||
|  |                   bind.mainSetOption(key: "stop-service", value: ""), | ||||||
|  |               child: Text(translate("Start Service"))) | ||||||
|  |         ], | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
|       if (svcStatusCode.value == 0) { |       if (svcStatusCode.value == 0) { | ||||||
| @ -436,7 +432,7 @@ class _ConnectionPageState extends State<ConnectionPage> { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   updateStatus() async { |   updateStatus() async { | ||||||
|     svcStopped.value = bind.mainGetOption(key: "stop-service") == "Y"; |     svcStopped.value = await bind.mainGetOption(key: "stop-service") == "Y"; | ||||||
|     final status = |     final status = | ||||||
|         jsonDecode(await bind.mainGetConnectStatus()) as Map<String, dynamic>; |         jsonDecode(await bind.mainGetConnectStatus()) as Map<String, dynamic>; | ||||||
|     svcStatusCode.value = status["status_num"]; |     svcStatusCode.value = status["status_num"]; | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ import 'dart:async'; | |||||||
| import 'dart:convert'; | import 'dart:convert'; | ||||||
| import 'dart:io'; | import 'dart:io'; | ||||||
| 
 | 
 | ||||||
| import 'package:desktop_multi_window/desktop_multi_window.dart'; |  | ||||||
| import 'package:flutter/material.dart' hide MenuItem; | import 'package:flutter/material.dart' hide MenuItem; | ||||||
| import 'package:flutter/services.dart'; | import 'package:flutter/services.dart'; | ||||||
| import 'package:flutter_hbb/common.dart'; | import 'package:flutter_hbb/common.dart'; | ||||||
| @ -27,8 +26,8 @@ class DesktopHomePage extends StatefulWidget { | |||||||
| 
 | 
 | ||||||
| const borderColor = Color(0xFF2F65BA); | const borderColor = Color(0xFF2F65BA); | ||||||
| 
 | 
 | ||||||
| class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, WindowListener { | class _DesktopHomePageState extends State<DesktopHomePage> | ||||||
| 
 |     with TrayListener, WindowListener { | ||||||
|   @override |   @override | ||||||
|   void onWindowClose() async { |   void onWindowClose() async { | ||||||
|     super.onWindowClose(); |     super.onWindowClose(); | ||||||
| @ -132,18 +131,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, Wi | |||||||
|                         style: TextStyle( |                         style: TextStyle( | ||||||
|                             fontSize: 18, fontWeight: FontWeight.w500), |                             fontSize: 18, fontWeight: FontWeight.w500), | ||||||
|                       ), |                       ), | ||||||
|                       FutureBuilder<Widget>( |                       buildPopupMenu(context) | ||||||
|                           future: buildPopupMenu(context), |  | ||||||
|                           builder: (context, snapshot) { |  | ||||||
|                             if (snapshot.hasError) { |  | ||||||
|                               print("${snapshot.error}"); |  | ||||||
|                             } |  | ||||||
|                             if (snapshot.hasData) { |  | ||||||
|                               return snapshot.data!; |  | ||||||
|                             } else { |  | ||||||
|                               return Offstage(); |  | ||||||
|                             } |  | ||||||
|                           }) |  | ||||||
|                     ], |                     ], | ||||||
|                   ), |                   ), | ||||||
|                   GestureDetector( |                   GestureDetector( | ||||||
| @ -165,7 +153,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, Wi | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Future<Widget> buildPopupMenu(BuildContext context) async { |   Widget buildPopupMenu(BuildContext context) { | ||||||
|     var position; |     var position; | ||||||
|     return GestureDetector( |     return GestureDetector( | ||||||
|         onTapDown: (detail) { |         onTapDown: (detail) { | ||||||
| @ -178,19 +166,19 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, Wi | |||||||
|           final enabledInput = await bind.mainGetOption(key: 'enable-audio'); |           final enabledInput = await bind.mainGetOption(key: 'enable-audio'); | ||||||
|           final defaultInput = await gFFI.getDefaultAudioInput(); |           final defaultInput = await gFFI.getDefaultAudioInput(); | ||||||
|           var menu = <PopupMenuEntry>[ |           var menu = <PopupMenuEntry>[ | ||||||
|             genEnablePopupMenuItem( |             await genEnablePopupMenuItem( | ||||||
|               translate("Enable Keyboard/Mouse"), |               translate("Enable Keyboard/Mouse"), | ||||||
|               'enable-keyboard', |               'enable-keyboard', | ||||||
|             ), |             ), | ||||||
|             genEnablePopupMenuItem( |             await genEnablePopupMenuItem( | ||||||
|               translate("Enable Clipboard"), |               translate("Enable Clipboard"), | ||||||
|               'enable-clipboard', |               'enable-clipboard', | ||||||
|             ), |             ), | ||||||
|             genEnablePopupMenuItem( |             await genEnablePopupMenuItem( | ||||||
|               translate("Enable File Transfer"), |               translate("Enable File Transfer"), | ||||||
|               'enable-file-transfer', |               'enable-file-transfer', | ||||||
|             ), |             ), | ||||||
|             genEnablePopupMenuItem( |             await genEnablePopupMenuItem( | ||||||
|               translate("Enable TCP Tunneling"), |               translate("Enable TCP Tunneling"), | ||||||
|               'enable-tunnel', |               'enable-tunnel', | ||||||
|             ), |             ), | ||||||
| @ -209,16 +197,16 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, Wi | |||||||
|               value: 'socks5-proxy', |               value: 'socks5-proxy', | ||||||
|             ), |             ), | ||||||
|             PopupMenuDivider(), |             PopupMenuDivider(), | ||||||
|             genEnablePopupMenuItem( |             await genEnablePopupMenuItem( | ||||||
|               translate("Enable Service"), |               translate("Enable Service"), | ||||||
|               'stop-service', |               'stop-service', | ||||||
|             ), |             ), | ||||||
|             // TODO: direct server |             // TODO: direct server | ||||||
|             genEnablePopupMenuItem( |             await genEnablePopupMenuItem( | ||||||
|               translate("Always connected via relay"), |               translate("Always connected via relay"), | ||||||
|               'allow-always-relay', |               'allow-always-relay', | ||||||
|             ), |             ), | ||||||
|             genEnablePopupMenuItem( |             await genEnablePopupMenuItem( | ||||||
|               translate("Start ID/relay service"), |               translate("Start ID/relay service"), | ||||||
|               'stop-rendezvous-service', |               'stop-rendezvous-service', | ||||||
|             ), |             ), | ||||||
| @ -237,7 +225,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, Wi | |||||||
|               value: 'change-id', |               value: 'change-id', | ||||||
|             ), |             ), | ||||||
|             PopupMenuDivider(), |             PopupMenuDivider(), | ||||||
|             genEnablePopupMenuItem( |             await genEnablePopupMenuItem( | ||||||
|               translate("Dark Theme"), |               translate("Dark Theme"), | ||||||
|               'allow-darktheme', |               'allow-darktheme', | ||||||
|             ), |             ), | ||||||
| @ -491,6 +479,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, Wi | |||||||
|       Get.changeTheme(MyTheme.lightTheme); |       Get.changeTheme(MyTheme.lightTheme); | ||||||
|     } |     } | ||||||
|     Get.find<SharedPreferences>().setString("darkTheme", choice); |     Get.find<SharedPreferences>().setString("darkTheme", choice); | ||||||
|  |     Get.forceAppUpdate(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   void onSelectMenu(String key) async { |   void onSelectMenu(String key) async { | ||||||
| @ -501,7 +490,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, Wi | |||||||
|       final option = await bind.mainGetOption(key: key); |       final option = await bind.mainGetOption(key: key); | ||||||
|       final choice = option == "Y" ? "" : "Y"; |       final choice = option == "Y" ? "" : "Y"; | ||||||
|       bind.mainSetOption(key: key, value: choice); |       bind.mainSetOption(key: key, value: choice); | ||||||
|       changeTheme(choice); |       if (key == "allow-darktheme") changeTheme(choice); | ||||||
|     } else if (key == "stop-service") { |     } else if (key == "stop-service") { | ||||||
|       final option = await bind.mainGetOption(key: key); |       final option = await bind.mainGetOption(key: key); | ||||||
|       bind.mainSetOption(key: key, value: option == "Y" ? "" : "Y"); |       bind.mainSetOption(key: key, value: option == "Y" ? "" : "Y"); | ||||||
| @ -522,30 +511,29 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener, Wi | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   PopupMenuItem<String> genEnablePopupMenuItem(String label, String key) { |   Future<PopupMenuItem<String>> genEnablePopupMenuItem( | ||||||
|     Future<bool> getOptionEnable(String key) async { |       String label, String key) async { | ||||||
|     final v = await bind.mainGetOption(key: key); |     final v = await bind.mainGetOption(key: key); | ||||||
|       return key.startsWith('enable-') ? v != "N" : v == "Y"; |     bool enable; | ||||||
|  |     if (key == "stop-service") { | ||||||
|  |       enable = v != "Y"; | ||||||
|  |     } else if (key.startsWith("allow-")) { | ||||||
|  |       enable = v == "Y"; | ||||||
|  |     } else { | ||||||
|  |       enable = v != "N"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return PopupMenuItem( |     return PopupMenuItem( | ||||||
|       child: FutureBuilder<bool>( |       child: Row( | ||||||
|           future: getOptionEnable(key), |  | ||||||
|           builder: (context, snapshot) { |  | ||||||
|             var enable = false; |  | ||||||
|             if (snapshot.hasData && snapshot.data!) { |  | ||||||
|               enable = true; |  | ||||||
|             } |  | ||||||
|             return Row( |  | ||||||
|         children: [ |         children: [ | ||||||
|                 Offstage(offstage: !enable, child: Icon(Icons.check)), |           Icon(Icons.check, | ||||||
|  |               color: enable ? null : MyTheme.accent.withAlpha(00)), | ||||||
|           Text( |           Text( | ||||||
|             label, |             label, | ||||||
|             style: genTextStyle(enable), |             style: genTextStyle(enable), | ||||||
|           ), |           ), | ||||||
|         ], |         ], | ||||||
|             ); |       ), | ||||||
|           }), |  | ||||||
|       value: key, |       value: key, | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -187,10 +187,9 @@ class _PeerCardState extends State<_PeerCard> | |||||||
|       elevation: 8, |       elevation: 8, | ||||||
|     ); |     ); | ||||||
|     if (value == 'remove') { |     if (value == 'remove') { | ||||||
|       setState(() => bind.mainRemovePeer(id: id)); |       await bind.mainRemovePeer(id: id); | ||||||
|       () async { |  | ||||||
|       removePreference(id); |       removePreference(id); | ||||||
|       }(); |       Get.forceAppUpdate(); // TODO use inner model / state | ||||||
|     } else if (value == 'file') { |     } else if (value == 'file') { | ||||||
|       _connect(id, isFileTransfer: true); |       _connect(id, isFileTransfer: true); | ||||||
|     } else if (value == 'add-fav') { |     } else if (value == 'add-fav') { | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ import '../../models/platform_model.dart'; | |||||||
| import '../../models/server_model.dart'; | import '../../models/server_model.dart'; | ||||||
| import 'home_page.dart'; | import 'home_page.dart'; | ||||||
| 
 | 
 | ||||||
| class ServerPage extends StatelessWidget implements PageShape { | class ServerPage extends StatefulWidget implements PageShape { | ||||||
|   @override |   @override | ||||||
|   final title = translate("Share Screen"); |   final title = translate("Share Screen"); | ||||||
| 
 | 
 | ||||||
| @ -102,6 +102,17 @@ class ServerPage extends StatelessWidget implements PageShape { | |||||||
|         }) |         }) | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|  |   @override | ||||||
|  |   State<StatefulWidget> createState() => _ServerPageState(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class _ServerPageState extends State<ServerPage> { | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     super.initState(); | ||||||
|  |     gFFI.serverModel.checkAndroidPermission(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     checkService(); |     checkService(); | ||||||
|  | |||||||
| @ -85,40 +85,8 @@ class ServerModel with ChangeNotifier { | |||||||
|   WeakReference<FFI> parent; |   WeakReference<FFI> parent; | ||||||
| 
 | 
 | ||||||
|   ServerModel(this.parent) { |   ServerModel(this.parent) { | ||||||
|     () async { |  | ||||||
|     _emptyIdShow = translate("Generating ..."); |     _emptyIdShow = translate("Generating ..."); | ||||||
|     _serverId = TextEditingController(text: this._emptyIdShow); |     _serverId = TextEditingController(text: this._emptyIdShow); | ||||||
|       /** |  | ||||||
|        * 1. check android permission |  | ||||||
|        * 2. check config |  | ||||||
|        * audio true by default (if permission on) (false default < Android 10) |  | ||||||
|        * file true by default (if permission on) |  | ||||||
|        */ |  | ||||||
|       await Future.delayed(Duration(seconds: 1)); |  | ||||||
| 
 |  | ||||||
|       // audio |  | ||||||
|       if (androidVersion < 30 || !await PermissionManager.check("audio")) { |  | ||||||
|         _audioOk = false; |  | ||||||
|         bind.mainSetOption(key: "enable-audio", value: "N"); |  | ||||||
|       } else { |  | ||||||
|         final audioOption = await bind.mainGetOption(key: 'enable-audio'); |  | ||||||
|         _audioOk = audioOption.isEmpty; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       // file |  | ||||||
|       if (!await PermissionManager.check("file")) { |  | ||||||
|         _fileOk = false; |  | ||||||
|         bind.mainSetOption(key: "enable-file-transfer", value: "N"); |  | ||||||
|       } else { |  | ||||||
|         final fileOption = |  | ||||||
|             await bind.mainGetOption(key: 'enable-file-transfer'); |  | ||||||
|         _fileOk = fileOption.isEmpty; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       // input (mouse control) false by default |  | ||||||
|       bind.mainSetOption(key: "enable-keyboard", value: "N"); |  | ||||||
|       notifyListeners(); |  | ||||||
|     }(); |  | ||||||
| 
 | 
 | ||||||
|     Timer.periodic(Duration(seconds: 1), (timer) async { |     Timer.periodic(Duration(seconds: 1), (timer) async { | ||||||
|       var status = await bind.mainGetOnlineStatue(); |       var status = await bind.mainGetOnlineStatue(); | ||||||
| @ -139,6 +107,34 @@ class ServerModel with ChangeNotifier { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /// 1. check android permission | ||||||
|  |   /// 2. check config | ||||||
|  |   /// audio true by default (if permission on) (false default < Android 10) | ||||||
|  |   /// file true by default (if permission on) | ||||||
|  |   checkAndroidPermission() async { | ||||||
|  |     // audio | ||||||
|  |     if (androidVersion < 30 || !await PermissionManager.check("audio")) { | ||||||
|  |       _audioOk = false; | ||||||
|  |       bind.mainSetOption(key: "enable-audio", value: "N"); | ||||||
|  |     } else { | ||||||
|  |       final audioOption = await bind.mainGetOption(key: 'enable-audio'); | ||||||
|  |       _audioOk = audioOption.isEmpty; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // file | ||||||
|  |     if (!await PermissionManager.check("file")) { | ||||||
|  |       _fileOk = false; | ||||||
|  |       bind.mainSetOption(key: "enable-file-transfer", value: "N"); | ||||||
|  |     } else { | ||||||
|  |       final fileOption = await bind.mainGetOption(key: 'enable-file-transfer'); | ||||||
|  |       _fileOk = fileOption.isEmpty; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // input (mouse control) false by default | ||||||
|  |     bind.mainSetOption(key: "enable-keyboard", value: "N"); | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   updatePasswordModel() async { |   updatePasswordModel() async { | ||||||
|     var update = false; |     var update = false; | ||||||
|     final temporaryPassword = await bind.mainGetTemporaryPassword(); |     final temporaryPassword = await bind.mainGetTemporaryPassword(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user