| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | import 'dart:async'; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | import 'dart:convert'; | 
					
						
							| 
									
										
										
										
											2022-05-25 00:28:59 +08:00
										 |  |  | import 'dart:io'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  | import 'package:flutter_hbb/main.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:53:51 +08:00
										 |  |  | import 'package:flutter_hbb/models/platform_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  | import 'package:get/get.dart'; | 
					
						
							| 
									
										
										
										
											2022-04-19 23:43:55 +08:00
										 |  |  | import 'package:wakelock/wakelock.dart'; | 
					
						
							| 
									
										
										
										
											2022-10-26 21:39:28 +09:00
										 |  |  | import 'package:window_manager/window_manager.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-25 00:28:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | import '../common.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-02 17:19:44 +08:00
										 |  |  | import '../common/formatter/id_formatter.dart'; | 
					
						
							| 
									
										
										
										
											2022-11-03 21:58:25 +08:00
										 |  |  | import '../desktop/pages/server_page.dart' as desktop; | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  | import '../desktop/widgets/tabbar_widget.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-24 23:33:00 +08:00
										 |  |  | import '../mobile/pages/server_page.dart'; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | import 'model.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 13:07:20 +08:00
										 |  |  | const kLoginDialogTag = "LOGIN"; | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  | const kUseTemporaryPassword = "use-temporary-password"; | 
					
						
							|  |  |  | const kUsePermanentPassword = "use-permanent-password"; | 
					
						
							|  |  |  | const kUseBothPasswords = "use-both-passwords"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | class ServerModel with ChangeNotifier { | 
					
						
							| 
									
										
										
										
											2022-04-17 11:34:46 +08:00
										 |  |  |   bool _isStart = false; // Android MainService status
 | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |   bool _mediaOk = false; | 
					
						
							|  |  |  |   bool _inputOk = false; | 
					
						
							| 
									
										
										
										
											2022-03-28 17:24:52 +08:00
										 |  |  |   bool _audioOk = false; | 
					
						
							|  |  |  |   bool _fileOk = false; | 
					
						
							| 
									
										
										
										
											2022-11-10 10:27:13 +08:00
										 |  |  |   bool _showElevation = true; | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |   bool _hideCm = false; | 
					
						
							| 
									
										
										
										
											2022-04-17 11:34:46 +08:00
										 |  |  |   int _connectStatus = 0; // Rendezvous Server status
 | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |   String _verificationMethod = ""; | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |   String _temporaryPasswordLength = ""; | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |   String _approveMode = ""; | 
					
						
							| 
									
										
										
										
											2022-04-17 11:34:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |   late String _emptyIdShow; | 
					
						
							| 
									
										
										
										
											2022-09-02 17:19:44 +08:00
										 |  |  |   late final IDTextEditingController _serverId; | 
					
						
							| 
									
										
										
										
											2022-11-21 14:06:32 +08:00
										 |  |  |   final _serverPasswd = | 
					
						
							|  |  |  |       TextEditingController(text: translate("Generating ...")); | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-01 21:18:53 +08:00
										 |  |  |   final tabController = DesktopTabController(tabType: DesktopTabType.cm); | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-06 21:20:53 -07:00
										 |  |  |   final List<Client> _clients = []; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 21:39:28 +09:00
										 |  |  |   Timer? cmHiddenTimer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   bool get isStart => _isStart; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |   bool get mediaOk => _mediaOk; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool get inputOk => _inputOk; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |   bool get audioOk => _audioOk; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   bool get fileOk => _fileOk; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 10:27:13 +08:00
										 |  |  |   bool get showElevation => _showElevation; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |   bool get hideCm => _hideCm; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-17 11:34:46 +08:00
										 |  |  |   int get connectStatus => _connectStatus; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |   String get verificationMethod { | 
					
						
							|  |  |  |     final index = [ | 
					
						
							|  |  |  |       kUseTemporaryPassword, | 
					
						
							|  |  |  |       kUsePermanentPassword, | 
					
						
							|  |  |  |       kUseBothPasswords | 
					
						
							|  |  |  |     ].indexOf(_verificationMethod); | 
					
						
							|  |  |  |     if (index < 0) { | 
					
						
							| 
									
										
										
										
											2022-08-13 12:43:35 +08:00
										 |  |  |       return kUseBothPasswords; | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     return _verificationMethod; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |   String get approveMode => _approveMode; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-06 21:20:53 -07:00
										 |  |  |   setVerificationMethod(String method) async { | 
					
						
							|  |  |  |     await bind.mainSetOption(key: "verification-method", value: method); | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |     if (method != kUsePermanentPassword) { | 
					
						
							|  |  |  |       await bind.mainSetOption( | 
					
						
							|  |  |  |           key: 'allow-hide-cm', value: bool2option('allow-hide-cm', false)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String get temporaryPasswordLength { | 
					
						
							|  |  |  |     final lengthIndex = ["6", "8", "10"].indexOf(_temporaryPasswordLength); | 
					
						
							|  |  |  |     if (lengthIndex < 0) { | 
					
						
							| 
									
										
										
										
											2022-08-13 12:43:35 +08:00
										 |  |  |       return "6"; | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     return _temporaryPasswordLength; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-06 21:20:53 -07:00
										 |  |  |   setTemporaryPasswordLength(String length) async { | 
					
						
							|  |  |  |     await bind.mainSetOption(key: "temporary-password-length", value: length); | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |   setApproveMode(String mode) async { | 
					
						
							|  |  |  |     await bind.mainSetOption(key: 'approve-mode', value: mode); | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |     if (mode != 'password') { | 
					
						
							|  |  |  |       await bind.mainSetOption( | 
					
						
							|  |  |  |           key: 'allow-hide-cm', value: bool2option('allow-hide-cm', false)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   TextEditingController get serverId => _serverId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   TextEditingController get serverPasswd => _serverPasswd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |   List<Client> get clients => _clients; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-19 21:15:19 +08:00
										 |  |  |   final controller = ScrollController(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |   WeakReference<FFI> parent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ServerModel(this.parent) { | 
					
						
							| 
									
										
										
										
											2022-08-09 20:36:52 +08:00
										 |  |  |     _emptyIdShow = translate("Generating ..."); | 
					
						
							| 
									
										
										
										
											2022-09-02 17:19:44 +08:00
										 |  |  |     _serverId = IDTextEditingController(text: _emptyIdShow); | 
					
						
							| 
									
										
										
										
											2022-04-17 11:34:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |     timerCallback() async { | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |       var status = await bind.mainGetOnlineStatue(); | 
					
						
							| 
									
										
										
										
											2022-04-17 11:34:46 +08:00
										 |  |  |       if (status > 0) { | 
					
						
							|  |  |  |         status = 1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (status != _connectStatus) { | 
					
						
							|  |  |  |         _connectStatus = status; | 
					
						
							|  |  |  |         notifyListeners(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-09-05 19:41:09 +08:00
										 |  |  |       final res = await bind.cmCheckClientsLength(length: _clients.length); | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |       if (res != null) { | 
					
						
							| 
									
										
										
										
											2022-08-17 21:46:56 +08:00
										 |  |  |         debugPrint("clients not match!"); | 
					
						
							|  |  |  |         updateClientState(res); | 
					
						
							| 
									
										
										
										
											2022-04-19 21:15:19 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |       updatePasswordModel(); | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!isTest) { | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |       Future.delayed(Duration.zero, () async { | 
					
						
							|  |  |  |         if (await bind.optionSynced()) { | 
					
						
							|  |  |  |           await timerCallback(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |       Timer.periodic(Duration(milliseconds: 500), (timer) async { | 
					
						
							|  |  |  |         await timerCallback(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 20:36:52 +08:00
										 |  |  |   /// 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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 17:53:51 +08:00
										 |  |  |   updatePasswordModel() async { | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |     var update = false; | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |     final temporaryPassword = await bind.mainGetTemporaryPassword(); | 
					
						
							| 
									
										
										
										
											2022-08-08 17:53:51 +08:00
										 |  |  |     final verificationMethod = | 
					
						
							|  |  |  |         await bind.mainGetOption(key: "verification-method"); | 
					
						
							|  |  |  |     final temporaryPasswordLength = | 
					
						
							|  |  |  |         await bind.mainGetOption(key: "temporary-password-length"); | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |     final approveMode = await bind.mainGetOption(key: 'approve-mode'); | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |     var hideCm = option2bool( | 
					
						
							|  |  |  |         'allow-hide-cm', await bind.mainGetOption(key: 'allow-hide-cm')); | 
					
						
							|  |  |  |     if (!(approveMode == 'password' && | 
					
						
							|  |  |  |         verificationMethod == kUsePermanentPassword)) { | 
					
						
							|  |  |  |       hideCm = false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |     if (_approveMode != approveMode) { | 
					
						
							|  |  |  |       _approveMode = approveMode; | 
					
						
							|  |  |  |       update = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |     final oldPwdText = _serverPasswd.text; | 
					
						
							| 
									
										
										
										
											2022-11-21 14:06:32 +08:00
										 |  |  |     if (_serverPasswd.text != temporaryPassword && | 
					
						
							|  |  |  |         temporaryPassword.isNotEmpty) { | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |       _serverPasswd.text = temporaryPassword; | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-20 15:53:08 +08:00
										 |  |  |     if (verificationMethod == kUsePermanentPassword || | 
					
						
							|  |  |  |         _approveMode == 'click') { | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |       _serverPasswd.text = '-'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (oldPwdText != _serverPasswd.text) { | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |       update = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (_verificationMethod != verificationMethod) { | 
					
						
							|  |  |  |       _verificationMethod = verificationMethod; | 
					
						
							|  |  |  |       update = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-01 20:42:30 +08:00
										 |  |  |     if (_temporaryPasswordLength != temporaryPasswordLength) { | 
					
						
							|  |  |  |       _temporaryPasswordLength = temporaryPasswordLength; | 
					
						
							|  |  |  |       update = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |     if (_hideCm != hideCm) { | 
					
						
							|  |  |  |       _hideCm = hideCm; | 
					
						
							|  |  |  |       if (desktopType == DesktopType.cm) { | 
					
						
							|  |  |  |         if (hideCm) { | 
					
						
							|  |  |  |           hideCmWindow(); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           showCmWindow(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       update = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |     if (update) { | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |   toggleAudio() async { | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |     if (!_audioOk && !await PermissionManager.check("audio")) { | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |       final res = await PermissionManager.request("audio"); | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |       if (!res) { | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |         // TODO handle fail
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |     _audioOk = !_audioOk; | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |     bind.mainSetOption(key: "enable-audio", value: _audioOk ? '' : 'N'); | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |     notifyListeners(); | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |   toggleFile() async { | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |     if (!_fileOk && !await PermissionManager.check("file")) { | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |       final res = await PermissionManager.request("file"); | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |       if (!res) { | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |         // TODO handle fail
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     _fileOk = !_fileOk; | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |     bind.mainSetOption(key: "enable-file-transfer", value: _fileOk ? '' : 'N'); | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |   toggleInput() { | 
					
						
							|  |  |  |     if (_inputOk) { | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |       parent.target?.invokeMethod("stop_input"); | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |       if (parent.target != null) { | 
					
						
							|  |  |  |         showInputWarnAlert(parent.target!); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   /// Toggle the screen sharing service.
 | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |   toggleService() async { | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |     if (_isStart) { | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |       final res = | 
					
						
							|  |  |  |           await parent.target?.dialogManager.show<bool>((setState, close) { | 
					
						
							|  |  |  |         submit() => close(true); | 
					
						
							|  |  |  |         return CustomAlertDialog( | 
					
						
							|  |  |  |           title: Row(children: [ | 
					
						
							|  |  |  |             const Icon(Icons.warning_amber_sharp, | 
					
						
							|  |  |  |                 color: Colors.redAccent, size: 28), | 
					
						
							|  |  |  |             const SizedBox(width: 10), | 
					
						
							|  |  |  |             Text(translate("Warning")), | 
					
						
							|  |  |  |           ]), | 
					
						
							|  |  |  |           content: Text(translate("android_stop_service_tip")), | 
					
						
							|  |  |  |           actions: [ | 
					
						
							|  |  |  |             TextButton(onPressed: close, child: Text(translate("Cancel"))), | 
					
						
							|  |  |  |             ElevatedButton(onPressed: submit, child: Text(translate("OK"))), | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |           onSubmit: submit, | 
					
						
							|  |  |  |           onCancel: close, | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |       if (res == true) { | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |         stopService(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |       final res = | 
					
						
							|  |  |  |           await parent.target?.dialogManager.show<bool>((setState, close) { | 
					
						
							|  |  |  |         submit() => close(true); | 
					
						
							|  |  |  |         return CustomAlertDialog( | 
					
						
							|  |  |  |           title: Row(children: [ | 
					
						
							|  |  |  |             const Icon(Icons.warning_amber_sharp, | 
					
						
							|  |  |  |                 color: Colors.redAccent, size: 28), | 
					
						
							|  |  |  |             const SizedBox(width: 10), | 
					
						
							|  |  |  |             Text(translate("Warning")), | 
					
						
							|  |  |  |           ]), | 
					
						
							|  |  |  |           content: Text(translate("android_service_will_start_tip")), | 
					
						
							|  |  |  |           actions: [ | 
					
						
							|  |  |  |             TextButton(onPressed: close, child: Text(translate("Cancel"))), | 
					
						
							|  |  |  |             ElevatedButton(onPressed: submit, child: Text(translate("OK"))), | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |           onSubmit: submit, | 
					
						
							|  |  |  |           onCancel: close, | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |       if (res == true) { | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |         startService(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   /// Start the screen sharing service.
 | 
					
						
							| 
									
										
										
										
											2022-11-03 21:58:25 +08:00
										 |  |  |   Future<void> startService() async { | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     _isStart = true; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |     parent.target?.ffiModel.updateEventListener(""); | 
					
						
							|  |  |  |     await parent.target?.invokeMethod("init_service"); | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |     await bind.mainStartService(); | 
					
						
							| 
									
										
										
										
											2022-04-15 17:45:48 +08:00
										 |  |  |     updateClientState(); | 
					
						
							| 
									
										
										
										
											2022-05-25 00:28:59 +08:00
										 |  |  |     if (!Platform.isLinux) { | 
					
						
							|  |  |  |       // current linux is not supported
 | 
					
						
							|  |  |  |       Wakelock.enable(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   /// Stop the screen sharing service.
 | 
					
						
							| 
									
										
										
										
											2022-11-03 21:58:25 +08:00
										 |  |  |   Future<void> stopService() async { | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     _isStart = false; | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  |     closeAll(); | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |     await parent.target?.invokeMethod("stop_service"); | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |     await bind.mainStopService(); | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     notifyListeners(); | 
					
						
							| 
									
										
										
										
											2022-05-25 00:28:59 +08:00
										 |  |  |     if (!Platform.isLinux) { | 
					
						
							|  |  |  |       // current linux is not supported
 | 
					
						
							|  |  |  |       Wakelock.disable(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-03 21:58:25 +08:00
										 |  |  |   Future<void> initInput() async { | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |     await parent.target?.invokeMethod("init_input"); | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |   Future<bool> setPermanentPassword(String newPW) async { | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |     await bind.mainSetPermanentPassword(password: newPW); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |     await Future.delayed(Duration(milliseconds: 500)); | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |     final pw = await bind.mainGetPermanentPassword(); | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |     if (newPW == pw) { | 
					
						
							|  |  |  |       return true; | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-29 22:36:35 +08:00
										 |  |  |   fetchID() async { | 
					
						
							|  |  |  |     final id = await bind.mainGetMyId(); | 
					
						
							|  |  |  |     if (id != _serverId.id) { | 
					
						
							|  |  |  |       _serverId.id = id; | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |   changeStatue(String name, bool value) { | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     debugPrint("changeStatue value $value"); | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |     switch (name) { | 
					
						
							|  |  |  |       case "media": | 
					
						
							|  |  |  |         _mediaOk = value; | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |         if (value && !_isStart) { | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |           startService(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case "input": | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |         if (_inputOk != value) { | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |           bind.mainSetOption(key: "enable-keyboard", value: value ? '' : 'N'); | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |         _inputOk = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |   // force
 | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |   updateClientState([String? json]) async { | 
					
						
							| 
									
										
										
										
											2022-10-20 23:05:34 +09:00
										 |  |  |     if (isTest) return; | 
					
						
							| 
									
										
										
										
											2022-09-05 19:41:09 +08:00
										 |  |  |     var res = await bind.cmGetClientsState(); | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |     try { | 
					
						
							|  |  |  |       final List clientsJson = jsonDecode(res); | 
					
						
							| 
									
										
										
										
											2022-08-17 21:28:36 +08:00
										 |  |  |       _clients.clear(); | 
					
						
							| 
									
										
										
										
											2022-08-24 21:52:21 +08:00
										 |  |  |       tabController.state.value.tabs.clear(); | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |       for (var clientJson in clientsJson) { | 
					
						
							| 
									
										
										
										
											2022-04-15 17:45:48 +08:00
										 |  |  |         final client = Client.fromJson(clientJson); | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |         _clients.add(client); | 
					
						
							| 
									
										
										
										
											2022-10-26 21:39:28 +09:00
										 |  |  |         _addTab(client); | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |       notifyListeners(); | 
					
						
							| 
									
										
										
										
											2022-04-15 17:45:48 +08:00
										 |  |  |     } catch (e) { | 
					
						
							|  |  |  |       debugPrint("Failed to updateClientState:$e"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-05 19:41:09 +08:00
										 |  |  |   void addConnection(Map<String, dynamic> evt) { | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |       final client = Client.fromJson(jsonDecode(evt["client"])); | 
					
						
							| 
									
										
										
										
											2022-09-05 19:41:09 +08:00
										 |  |  |       if (client.authorized) { | 
					
						
							|  |  |  |         parent.target?.dialogManager.dismissByTag(getLoginDialogTag(client.id)); | 
					
						
							|  |  |  |         final index = _clients.indexWhere((c) => c.id == client.id); | 
					
						
							|  |  |  |         if (index < 0) { | 
					
						
							|  |  |  |           _clients.add(client); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           _clients[index].authorized = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         if (_clients.any((c) => c.id == client.id)) { | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         _clients.add(client); | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-10-26 21:39:28 +09:00
										 |  |  |       _addTab(client); | 
					
						
							| 
									
										
										
										
											2022-10-08 20:15:02 +08:00
										 |  |  |       // remove disconnected
 | 
					
						
							|  |  |  |       final index_disconnected = _clients | 
					
						
							|  |  |  |           .indexWhere((c) => c.disconnected && c.peerId == client.peerId); | 
					
						
							|  |  |  |       if (index_disconnected >= 0) { | 
					
						
							|  |  |  |         _clients.removeAt(index_disconnected); | 
					
						
							|  |  |  |         tabController.remove(index_disconnected); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       scrollToBottom(); | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |       if (isAndroid && !client.authorized) showLoginDialog(client); | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |     } catch (e) { | 
					
						
							|  |  |  |       debugPrint("Failed to call loginRequest,error:$e"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 21:39:28 +09:00
										 |  |  |   void _addTab(Client client) { | 
					
						
							|  |  |  |     tabController.add(TabInfo( | 
					
						
							|  |  |  |         key: client.id.toString(), | 
					
						
							|  |  |  |         label: client.name, | 
					
						
							|  |  |  |         closable: false, | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |         onTap: () { | 
					
						
							|  |  |  |           if (client.hasUnreadChatMessage.value) { | 
					
						
							|  |  |  |             client.hasUnreadChatMessage.value = false; | 
					
						
							|  |  |  |             final chatModel = parent.target!.chatModel; | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |             chatModel.showChatPage(client.id); | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |           } | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2022-11-03 21:58:25 +08:00
										 |  |  |         page: desktop.buildConnectionCard(client))); | 
					
						
							| 
									
										
										
										
											2022-10-26 21:39:28 +09:00
										 |  |  |     Future.delayed(Duration.zero, () async { | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |       if (!hideCm) window_on_top(null); | 
					
						
							| 
									
										
										
										
											2022-10-26 21:39:28 +09:00
										 |  |  |     }); | 
					
						
							|  |  |  |     if (client.authorized) { | 
					
						
							|  |  |  |       cmHiddenTimer = Timer(const Duration(seconds: 3), () { | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |         if (!hideCm) windowManager.minimize(); | 
					
						
							| 
									
										
										
										
											2022-10-26 21:39:28 +09:00
										 |  |  |         cmHiddenTimer = null; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |   void showLoginDialog(Client client) { | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |     parent.target?.dialogManager.show((setState, close) { | 
					
						
							|  |  |  |       cancel() { | 
					
						
							|  |  |  |         sendLoginResponse(client, false); | 
					
						
							|  |  |  |         close(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       submit() { | 
					
						
							|  |  |  |         sendLoginResponse(client, true); | 
					
						
							|  |  |  |         close(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return CustomAlertDialog( | 
					
						
							|  |  |  |         title: | 
					
						
							|  |  |  |             Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ | 
					
						
							|  |  |  |           Text(translate( | 
					
						
							|  |  |  |               client.isFileTransfer ? "File Connection" : "Screen Connection")), | 
					
						
							|  |  |  |           IconButton( | 
					
						
							|  |  |  |               onPressed: () { | 
					
						
							|  |  |  |                 close(); | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |               icon: const Icon(Icons.close)) | 
					
						
							|  |  |  |         ]), | 
					
						
							|  |  |  |         content: Column( | 
					
						
							|  |  |  |           mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |           mainAxisAlignment: MainAxisAlignment.center, | 
					
						
							|  |  |  |           crossAxisAlignment: CrossAxisAlignment.start, | 
					
						
							|  |  |  |           children: [ | 
					
						
							|  |  |  |             Text(translate("Do you accept?")), | 
					
						
							| 
									
										
										
										
											2022-09-29 21:53:50 +08:00
										 |  |  |             ClientInfo(client), | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |             Text( | 
					
						
							|  |  |  |               translate("android_new_connection_tip"), | 
					
						
							| 
									
										
										
										
											2022-09-26 11:21:40 +08:00
										 |  |  |               style: Theme.of(globalKey.currentContext!).textTheme.bodyMedium, | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |           ], | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         actions: [ | 
					
						
							|  |  |  |           TextButton(onPressed: cancel, child: Text(translate("Dismiss"))), | 
					
						
							|  |  |  |           ElevatedButton(onPressed: submit, child: Text(translate("Accept"))), | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         onSubmit: submit, | 
					
						
							|  |  |  |         onCancel: cancel, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }, tag: getLoginDialogTag(client.id)); | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-19 21:15:19 +08:00
										 |  |  |   scrollToBottom() { | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |     if (isDesktop) return; | 
					
						
							| 
									
										
										
										
											2022-04-19 21:15:19 +08:00
										 |  |  |     Future.delayed(Duration(milliseconds: 200), () { | 
					
						
							|  |  |  |       controller.animateTo(controller.position.maxScrollExtent, | 
					
						
							|  |  |  |           duration: Duration(milliseconds: 200), | 
					
						
							|  |  |  |           curve: Curves.fastLinearToSlowEaseIn); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |   void sendLoginResponse(Client client, bool res) async { | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |     if (res) { | 
					
						
							| 
									
										
										
										
											2022-08-17 17:23:55 +08:00
										 |  |  |       bind.cmLoginRes(connId: client.id, res: res); | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |       if (!client.isFileTransfer) { | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |         parent.target?.invokeMethod("start_capture"); | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |       parent.target?.invokeMethod("cancel_notification", client.id); | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |       client.authorized = true; | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2022-08-17 17:23:55 +08:00
										 |  |  |       bind.cmLoginRes(connId: client.id, res: res); | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |       parent.target?.invokeMethod("cancel_notification", client.id); | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |       final index = _clients.indexOf(client); | 
					
						
							| 
									
										
										
										
											2022-08-24 21:52:21 +08:00
										 |  |  |       tabController.remove(index); | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |       _clients.remove(client); | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void onClientRemove(Map<String, dynamic> evt) { | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |       final id = int.parse(evt['id'] as String); | 
					
						
							| 
									
										
										
										
											2022-10-08 20:15:02 +08:00
										 |  |  |       final close = (evt['close'] as String) == 'true'; | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |       if (_clients.any((c) => c.id == id)) { | 
					
						
							|  |  |  |         final index = _clients.indexWhere((client) => client.id == id); | 
					
						
							| 
									
										
										
										
											2022-09-01 21:18:53 +08:00
										 |  |  |         if (index >= 0) { | 
					
						
							| 
									
										
										
										
											2022-10-08 20:15:02 +08:00
										 |  |  |           if (close) { | 
					
						
							|  |  |  |             _clients.removeAt(index); | 
					
						
							|  |  |  |             tabController.remove(index); | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             _clients[index].disconnected = true; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-09-01 21:18:53 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  |         parent.target?.dialogManager.dismissByTag(getLoginDialogTag(id)); | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  |         parent.target?.invokeMethod("cancel_notification", id); | 
					
						
							| 
									
										
										
										
											2022-03-29 23:10:43 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |       notifyListeners(); | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     } catch (e) { | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |       debugPrint("onClientRemove failed,error:$e"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   closeAll() { | 
					
						
							| 
									
										
										
										
											2022-11-03 21:58:25 +08:00
										 |  |  |     for (var client in _clients) { | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |       bind.cmCloseConnection(connId: client.id); | 
					
						
							| 
									
										
										
										
											2022-11-03 21:58:25 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |     _clients.clear(); | 
					
						
							| 
									
										
										
										
											2022-08-24 21:52:21 +08:00
										 |  |  |     tabController.state.value.tabs.clear(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void jumpTo(int id) { | 
					
						
							|  |  |  |     final index = _clients.indexWhere((client) => client.id == id); | 
					
						
							|  |  |  |     tabController.jumpTo(index); | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-11-10 10:27:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void setShowElevation(bool show) { | 
					
						
							|  |  |  |     if (_showElevation != show) { | 
					
						
							|  |  |  |       _showElevation = show; | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 18:47:02 +08:00
										 |  |  | enum ClientType { | 
					
						
							|  |  |  |   remote, | 
					
						
							|  |  |  |   file, | 
					
						
							|  |  |  |   portForward, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | class Client { | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |   int id = 0; // client connections inner count id
 | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |   bool authorized = false; | 
					
						
							|  |  |  |   bool isFileTransfer = false; | 
					
						
							| 
									
										
										
										
											2022-12-04 18:47:02 +08:00
										 |  |  |   String portForward = ""; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |   String name = ""; | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |   String peerId = ""; // peer user's id,show at app
 | 
					
						
							|  |  |  |   bool keyboard = false; | 
					
						
							|  |  |  |   bool clipboard = false; | 
					
						
							|  |  |  |   bool audio = false; | 
					
						
							| 
									
										
										
										
											2022-08-18 19:49:41 +08:00
										 |  |  |   bool file = false; | 
					
						
							|  |  |  |   bool restart = false; | 
					
						
							| 
									
										
										
										
											2022-09-22 09:55:34 +08:00
										 |  |  |   bool recording = false; | 
					
						
							| 
									
										
										
										
											2022-10-08 20:15:02 +08:00
										 |  |  |   bool disconnected = false; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |   RxBool hasUnreadChatMessage = false.obs; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-22 20:18:31 +08:00
										 |  |  |   Client(this.id, this.authorized, this.isFileTransfer, this.name, this.peerId, | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |       this.keyboard, this.clipboard, this.audio); | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Client.fromJson(Map<String, dynamic> json) { | 
					
						
							|  |  |  |     id = json['id']; | 
					
						
							|  |  |  |     authorized = json['authorized']; | 
					
						
							|  |  |  |     isFileTransfer = json['is_file_transfer']; | 
					
						
							| 
									
										
										
										
											2022-12-04 18:47:02 +08:00
										 |  |  |     portForward = json['port_forward']; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |     name = json['name']; | 
					
						
							|  |  |  |     peerId = json['peer_id']; | 
					
						
							| 
									
										
										
										
											2022-04-13 15:33:23 +08:00
										 |  |  |     keyboard = json['keyboard']; | 
					
						
							|  |  |  |     clipboard = json['clipboard']; | 
					
						
							|  |  |  |     audio = json['audio']; | 
					
						
							| 
									
										
										
										
											2022-08-18 19:49:41 +08:00
										 |  |  |     file = json['file']; | 
					
						
							|  |  |  |     restart = json['restart']; | 
					
						
							| 
									
										
										
										
											2022-09-22 09:55:34 +08:00
										 |  |  |     recording = json['recording']; | 
					
						
							| 
									
										
										
										
											2022-10-08 20:15:02 +08:00
										 |  |  |     disconnected = json['disconnected']; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Map<String, dynamic> toJson() { | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |     final Map<String, dynamic> data = <String, dynamic>{}; | 
					
						
							| 
									
										
										
										
											2022-10-08 20:15:02 +08:00
										 |  |  |     data['id'] = id; | 
					
						
							|  |  |  |     data['is_start'] = authorized; | 
					
						
							|  |  |  |     data['is_file_transfer'] = isFileTransfer; | 
					
						
							| 
									
										
										
										
											2022-12-04 18:47:02 +08:00
										 |  |  |     data['port_forward'] = portForward; | 
					
						
							| 
									
										
										
										
											2022-10-08 20:15:02 +08:00
										 |  |  |     data['name'] = name; | 
					
						
							|  |  |  |     data['peer_id'] = peerId; | 
					
						
							|  |  |  |     data['keyboard'] = keyboard; | 
					
						
							|  |  |  |     data['clipboard'] = clipboard; | 
					
						
							|  |  |  |     data['audio'] = audio; | 
					
						
							| 
									
										
										
										
											2022-10-16 12:32:52 +08:00
										 |  |  |     data['file'] = file; | 
					
						
							|  |  |  |     data['restart'] = restart; | 
					
						
							|  |  |  |     data['recording'] = recording; | 
					
						
							| 
									
										
										
										
											2022-10-08 20:15:02 +08:00
										 |  |  |     data['disconnected'] = disconnected; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |     return data; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-12-04 18:47:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ClientType type_() { | 
					
						
							|  |  |  |     if (isFileTransfer) { | 
					
						
							|  |  |  |       return ClientType.file; | 
					
						
							|  |  |  |     } else if (portForward.isNotEmpty) { | 
					
						
							|  |  |  |       return ClientType.portForward; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return ClientType.remote; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  | String getLoginDialogTag(int id) { | 
					
						
							| 
									
										
										
										
											2022-09-29 13:07:20 +08:00
										 |  |  |   return kLoginDialogTag + id.toString(); | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  | showInputWarnAlert(FFI ffi) { | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |   ffi.dialogManager.show((setState, close) { | 
					
						
							|  |  |  |     submit() { | 
					
						
							|  |  |  |       ffi.serverModel.initInput(); | 
					
						
							|  |  |  |       close(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return CustomAlertDialog( | 
					
						
							|  |  |  |       title: Text(translate("How to get Android input permission?")), | 
					
						
							|  |  |  |       content: Column( | 
					
						
							|  |  |  |         mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |         children: [ | 
					
						
							|  |  |  |           Text(translate("android_input_permission_tip1")), | 
					
						
							|  |  |  |           const SizedBox(height: 10), | 
					
						
							|  |  |  |           Text(translate("android_input_permission_tip2")), | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |         ], | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |       ), | 
					
						
							|  |  |  |       actions: [ | 
					
						
							|  |  |  |         TextButton(onPressed: close, child: Text(translate("Cancel"))), | 
					
						
							|  |  |  |         ElevatedButton( | 
					
						
							|  |  |  |             onPressed: submit, child: Text(translate("Open System Setting"))), | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |       onSubmit: submit, | 
					
						
							|  |  |  |       onCancel: close, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  | } |