| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  | import 'dart:convert'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-28 18:29:25 +08:00
										 |  |  | import 'package:flutter_hbb/models/model.dart'; | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  | import 'package:flutter_hbb/widgets/dialog.dart'; | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  | import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-02 17:25:56 +08:00
										 |  |  | import 'package:provider/provider.dart'; | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-28 18:29:25 +08:00
										 |  |  | import '../common.dart'; | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | import '../models/server_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-28 18:29:25 +08:00
										 |  |  | import 'home_page.dart'; | 
					
						
							|  |  |  | import '../models/model.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ServerPage extends StatelessWidget implements PageShape { | 
					
						
							|  |  |  |   @override | 
					
						
							| 
									
										
										
										
											2022-03-23 15:28:21 +08:00
										 |  |  |   final title = translate("Share Screen"); | 
					
						
							| 
									
										
										
										
											2022-02-28 18:29:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   final icon = Icon(Icons.mobile_screen_share); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   final appBarActions = [ | 
					
						
							| 
									
										
										
										
											2022-04-04 01:38:53 +08:00
										 |  |  |     PopupMenuButton<String>( | 
					
						
							|  |  |  |         icon: Icon(Icons.more_vert), | 
					
						
							|  |  |  |         itemBuilder: (context) { | 
					
						
							|  |  |  |           return [ | 
					
						
							|  |  |  |             PopupMenuItem( | 
					
						
							|  |  |  |               child: Text(translate("Change ID")), | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |               padding: EdgeInsets.symmetric(horizontal: 16.0), | 
					
						
							| 
									
										
										
										
											2022-04-04 01:38:53 +08:00
										 |  |  |               value: "changeID", | 
					
						
							|  |  |  |               enabled: false, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             PopupMenuItem( | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |               child: Text(translate("Set permanent password")), | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |               padding: EdgeInsets.symmetric(horizontal: 16.0), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |               value: "setPermanentPassword", | 
					
						
							|  |  |  |               enabled: | 
					
						
							|  |  |  |                   FFI.serverModel.verificationMethod != kUseTemporaryPassword, | 
					
						
							| 
									
										
										
										
											2022-04-04 01:38:53 +08:00
										 |  |  |             ), | 
					
						
							|  |  |  |             PopupMenuItem( | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |               child: Text(translate("Set temporary password length")), | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |               padding: EdgeInsets.symmetric(horizontal: 16.0), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |               value: "setTemporaryPasswordLength", | 
					
						
							|  |  |  |               enabled: | 
					
						
							|  |  |  |                   FFI.serverModel.verificationMethod != kUsePermanentPassword, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             const PopupMenuDivider(), | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |             PopupMenuItem( | 
					
						
							|  |  |  |               padding: EdgeInsets.symmetric(horizontal: 0.0), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |               value: kUseTemporaryPassword, | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |               child: Container( | 
					
						
							|  |  |  |                   child: ListTile( | 
					
						
							|  |  |  |                       title: Text(translate("Use temporary password")), | 
					
						
							|  |  |  |                       trailing: Icon( | 
					
						
							|  |  |  |                         Icons.check, | 
					
						
							|  |  |  |                         color: FFI.serverModel.verificationMethod == | 
					
						
							|  |  |  |                                 kUseTemporaryPassword | 
					
						
							|  |  |  |                             ? null | 
					
						
							|  |  |  |                             : Color(0xFFFFFFFF), | 
					
						
							|  |  |  |                       ))), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |             PopupMenuItem( | 
					
						
							|  |  |  |               padding: EdgeInsets.symmetric(horizontal: 0.0), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |               value: kUsePermanentPassword, | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |               child: ListTile( | 
					
						
							|  |  |  |                   title: Text(translate("Use permanent password")), | 
					
						
							|  |  |  |                   trailing: Icon( | 
					
						
							|  |  |  |                     Icons.check, | 
					
						
							|  |  |  |                     color: FFI.serverModel.verificationMethod == | 
					
						
							|  |  |  |                             kUsePermanentPassword | 
					
						
							|  |  |  |                         ? null | 
					
						
							|  |  |  |                         : Color(0xFFFFFFFF), | 
					
						
							|  |  |  |                   )), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |             PopupMenuItem( | 
					
						
							|  |  |  |               padding: EdgeInsets.symmetric(horizontal: 0.0), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |               value: kUseBothPasswords, | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |               child: ListTile( | 
					
						
							|  |  |  |                   title: Text(translate("Use both passwords")), | 
					
						
							|  |  |  |                   trailing: Icon( | 
					
						
							|  |  |  |                     Icons.check, | 
					
						
							|  |  |  |                     color: FFI.serverModel.verificationMethod != | 
					
						
							|  |  |  |                                 kUseTemporaryPassword && | 
					
						
							|  |  |  |                             FFI.serverModel.verificationMethod != | 
					
						
							|  |  |  |                                 kUsePermanentPassword | 
					
						
							|  |  |  |                         ? null | 
					
						
							|  |  |  |                         : Color(0xFFFFFFFF), | 
					
						
							|  |  |  |                   )), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-04-04 01:38:53 +08:00
										 |  |  |           ]; | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         onSelected: (value) { | 
					
						
							|  |  |  |           if (value == "changeID") { | 
					
						
							|  |  |  |             // TODO
 | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |           } else if (value == "setPermanentPassword") { | 
					
						
							|  |  |  |             setPermanentPasswordDialog(); | 
					
						
							|  |  |  |           } else if (value == "setTemporaryPasswordLength") { | 
					
						
							|  |  |  |             setTemporaryPasswordLengthDialog(); | 
					
						
							|  |  |  |           } else if (value == kUsePermanentPassword || | 
					
						
							|  |  |  |               value == kUseTemporaryPassword || | 
					
						
							|  |  |  |               value == kUseBothPasswords) { | 
					
						
							|  |  |  |             Map<String, String> msg = Map() | 
					
						
							|  |  |  |               ..["name"] = "verification-method" | 
					
						
							|  |  |  |               ..["value"] = value; | 
					
						
							|  |  |  |             FFI.setByName('option', jsonEncode(msg)); | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |             FFI.serverModel.updatePasswordModel(); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-04-04 01:38:53 +08:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-02-28 18:29:25 +08:00
										 |  |  |   ]; | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2022-02-08 22:45:48 +08:00
										 |  |  |     checkService(); | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |     return ChangeNotifierProvider.value( | 
					
						
							|  |  |  |         value: FFI.serverModel, | 
					
						
							|  |  |  |         child: Consumer<ServerModel>( | 
					
						
							|  |  |  |             builder: (context, serverModel, child) => SingleChildScrollView( | 
					
						
							| 
									
										
										
										
											2022-04-19 21:15:19 +08:00
										 |  |  |                   controller: FFI.serverModel.controller, | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |                   child: Center( | 
					
						
							|  |  |  |                     child: Column( | 
					
						
							|  |  |  |                       mainAxisAlignment: MainAxisAlignment.start, | 
					
						
							|  |  |  |                       children: [ | 
					
						
							|  |  |  |                         ServerInfo(), | 
					
						
							|  |  |  |                         PermissionChecker(), | 
					
						
							|  |  |  |                         ConnectionManager(), | 
					
						
							|  |  |  |                         SizedBox.fromSize(size: Size(0, 15.0)), | 
					
						
							|  |  |  |                       ], | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                   ), | 
					
						
							|  |  |  |                 ))); | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  | void checkService() async { | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |   FFI.invokeMethod("check_service"); // jvm
 | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |   // for Android 10/11,MANAGE_EXTERNAL_STORAGE permission from a system setting page
 | 
					
						
							| 
									
										
										
										
											2022-04-12 20:54:29 +08:00
										 |  |  |   if (PermissionManager.isWaitingFile() && !FFI.serverModel.fileOk) { | 
					
						
							|  |  |  |     PermissionManager.complete("file", await PermissionManager.check("file")); | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |     debugPrint("file permission finished"); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-02-08 22:45:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  | class ServerInfo extends StatelessWidget { | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   final model = FFI.serverModel; | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |   final emptyController = TextEditingController(text: "-"); | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |     final isPermanent = model.verificationMethod == kUsePermanentPassword; | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     return model.isStart | 
					
						
							|  |  |  |         ? PaddingCard( | 
					
						
							|  |  |  |             child: Column( | 
					
						
							|  |  |  |             mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |             children: [ | 
					
						
							|  |  |  |               TextFormField( | 
					
						
							|  |  |  |                 readOnly: true, | 
					
						
							|  |  |  |                 style: TextStyle( | 
					
						
							|  |  |  |                     fontSize: 25.0, | 
					
						
							|  |  |  |                     fontWeight: FontWeight.bold, | 
					
						
							|  |  |  |                     color: MyTheme.accent), | 
					
						
							|  |  |  |                 controller: model.serverId, | 
					
						
							|  |  |  |                 decoration: InputDecoration( | 
					
						
							|  |  |  |                   icon: const Icon(Icons.perm_identity), | 
					
						
							|  |  |  |                   labelText: translate("ID"), | 
					
						
							|  |  |  |                   labelStyle: TextStyle( | 
					
						
							|  |  |  |                       fontWeight: FontWeight.bold, color: MyTheme.accent50), | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |                 onSaved: (String? value) {}, | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |               TextFormField( | 
					
						
							|  |  |  |                 readOnly: true, | 
					
						
							|  |  |  |                 style: TextStyle( | 
					
						
							|  |  |  |                     fontSize: 25.0, | 
					
						
							|  |  |  |                     fontWeight: FontWeight.bold, | 
					
						
							|  |  |  |                     color: MyTheme.accent), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |                 controller: isPermanent ? emptyController : model.serverPasswd, | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                 decoration: InputDecoration( | 
					
						
							|  |  |  |                     icon: const Icon(Icons.lock), | 
					
						
							|  |  |  |                     labelText: translate("Password"), | 
					
						
							|  |  |  |                     labelStyle: TextStyle( | 
					
						
							|  |  |  |                         fontWeight: FontWeight.bold, color: MyTheme.accent50), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |                     suffix: isPermanent | 
					
						
							|  |  |  |                         ? null | 
					
						
							|  |  |  |                         : IconButton( | 
					
						
							|  |  |  |                             icon: const Icon(Icons.refresh), | 
					
						
							|  |  |  |                             onPressed: () { | 
					
						
							|  |  |  |                               FFI.setByName("temporary_password"); | 
					
						
							|  |  |  |                             })), | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                 onSaved: (String? value) {}, | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |           )) | 
					
						
							|  |  |  |         : PaddingCard( | 
					
						
							|  |  |  |             child: Column( | 
					
						
							|  |  |  |             crossAxisAlignment: CrossAxisAlignment.center, | 
					
						
							|  |  |  |             children: [ | 
					
						
							|  |  |  |               Center( | 
					
						
							|  |  |  |                   child: Row( | 
					
						
							|  |  |  |                 children: [ | 
					
						
							|  |  |  |                   Icon(Icons.warning_amber_sharp, | 
					
						
							|  |  |  |                       color: Colors.redAccent, size: 24), | 
					
						
							|  |  |  |                   SizedBox(width: 10), | 
					
						
							|  |  |  |                   Text( | 
					
						
							| 
									
										
										
										
											2022-03-23 15:28:21 +08:00
										 |  |  |                     translate("Service is not running"), | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                     style: TextStyle( | 
					
						
							|  |  |  |                       fontFamily: 'WorkSans', | 
					
						
							|  |  |  |                       fontWeight: FontWeight.bold, | 
					
						
							|  |  |  |                       fontSize: 18, | 
					
						
							|  |  |  |                       color: MyTheme.accent80, | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                   ) | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |               )), | 
					
						
							|  |  |  |               SizedBox(height: 5), | 
					
						
							|  |  |  |               Center( | 
					
						
							|  |  |  |                   child: Text( | 
					
						
							| 
									
										
										
										
											2022-03-23 15:28:21 +08:00
										 |  |  |                 translate("android_start_service_tip"), | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                 style: TextStyle(fontSize: 12, color: MyTheme.darkGray), | 
					
						
							|  |  |  |               )) | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |           )); | 
					
						
							| 
									
										
										
										
											2022-02-09 17:04:13 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PermissionChecker extends StatefulWidget { | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   _PermissionCheckerState createState() => _PermissionCheckerState(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _PermissionCheckerState extends State<PermissionChecker> { | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2022-02-02 17:25:56 +08:00
										 |  |  |     final serverModel = Provider.of<ServerModel>(context); | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |     final hasAudioPermission = androidVersion >= 30; | 
					
						
							| 
									
										
										
										
											2022-04-17 11:34:46 +08:00
										 |  |  |     final status; | 
					
						
							|  |  |  |     if (serverModel.connectStatus == -1) { | 
					
						
							|  |  |  |       status = 'not_ready_status'; | 
					
						
							|  |  |  |     } else if (serverModel.connectStatus == 0) { | 
					
						
							|  |  |  |       status = 'connecting_status'; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       status = 'Ready'; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     return PaddingCard( | 
					
						
							| 
									
										
										
										
											2022-04-20 15:45:51 +08:00
										 |  |  |         title: translate("Permissions"), | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |         child: Column( | 
					
						
							|  |  |  |           crossAxisAlignment: CrossAxisAlignment.start, | 
					
						
							|  |  |  |           children: [ | 
					
						
							|  |  |  |             PermissionRow(translate("Screen Capture"), serverModel.mediaOk, | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |                 serverModel.toggleService), | 
					
						
							| 
									
										
										
										
											2022-04-20 15:45:51 +08:00
										 |  |  |             PermissionRow(translate("Input Control"), serverModel.inputOk, | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |                 serverModel.toggleInput), | 
					
						
							| 
									
										
										
										
											2022-06-08 22:35:06 +08:00
										 |  |  |             PermissionRow(translate("Transfer File"), serverModel.fileOk, | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                 serverModel.toggleFile), | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |             hasAudioPermission | 
					
						
							|  |  |  |                 ? PermissionRow(translate("Audio Capture"), serverModel.audioOk, | 
					
						
							|  |  |  |                     serverModel.toggleAudio) | 
					
						
							|  |  |  |                 : Text( | 
					
						
							|  |  |  |                     "* ${translate("android_version_audio_tip")}", | 
					
						
							|  |  |  |                     style: TextStyle(color: MyTheme.darkGray), | 
					
						
							|  |  |  |                   ), | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |             SizedBox(height: 8), | 
					
						
							| 
									
										
										
										
											2022-04-12 22:38:39 +08:00
										 |  |  |             Row( | 
					
						
							|  |  |  |               crossAxisAlignment: CrossAxisAlignment.center, | 
					
						
							|  |  |  |               children: [ | 
					
						
							| 
									
										
										
										
											2022-04-17 11:34:46 +08:00
										 |  |  |                 Expanded( | 
					
						
							|  |  |  |                     flex: 0, | 
					
						
							|  |  |  |                     child: serverModel.mediaOk | 
					
						
							|  |  |  |                         ? ElevatedButton.icon( | 
					
						
							|  |  |  |                             style: ButtonStyle( | 
					
						
							|  |  |  |                                 backgroundColor: | 
					
						
							|  |  |  |                                     MaterialStateProperty.all(Colors.red)), | 
					
						
							|  |  |  |                             icon: Icon(Icons.stop), | 
					
						
							|  |  |  |                             onPressed: serverModel.toggleService, | 
					
						
							|  |  |  |                             label: Text(translate("Stop service"))) | 
					
						
							|  |  |  |                         : ElevatedButton.icon( | 
					
						
							|  |  |  |                             icon: Icon(Icons.play_arrow), | 
					
						
							|  |  |  |                             onPressed: serverModel.toggleService, | 
					
						
							|  |  |  |                             label: Text(translate("Start Service")))), | 
					
						
							|  |  |  |                 Expanded( | 
					
						
							|  |  |  |                     child: serverModel.mediaOk | 
					
						
							|  |  |  |                         ? Row( | 
					
						
							|  |  |  |                             children: [ | 
					
						
							|  |  |  |                               Expanded( | 
					
						
							|  |  |  |                                   flex: 0, | 
					
						
							|  |  |  |                                   child: Padding( | 
					
						
							|  |  |  |                                       padding: | 
					
						
							|  |  |  |                                           EdgeInsets.only(left: 20, right: 5), | 
					
						
							|  |  |  |                                       child: Icon(Icons.circle, | 
					
						
							|  |  |  |                                           color: serverModel.connectStatus > 0 | 
					
						
							|  |  |  |                                               ? Colors.greenAccent | 
					
						
							|  |  |  |                                               : Colors.deepOrangeAccent, | 
					
						
							|  |  |  |                                           size: 10))), | 
					
						
							|  |  |  |                               Expanded( | 
					
						
							|  |  |  |                                   child: Text(translate(status), | 
					
						
							|  |  |  |                                       softWrap: true, | 
					
						
							|  |  |  |                                       style: TextStyle( | 
					
						
							|  |  |  |                                           fontSize: 14.0, | 
					
						
							|  |  |  |                                           color: MyTheme.accent50))) | 
					
						
							|  |  |  |                             ], | 
					
						
							|  |  |  |                           ) | 
					
						
							|  |  |  |                         : SizedBox.shrink()) | 
					
						
							| 
									
										
										
										
											2022-04-12 22:38:39 +08:00
										 |  |  |               ], | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |           ], | 
					
						
							|  |  |  |         )); | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-02-02 17:25:56 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class PermissionRow extends StatelessWidget { | 
					
						
							|  |  |  |   PermissionRow(this.name, this.isOk, this.onPressed); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   final String name; | 
					
						
							|  |  |  |   final bool isOk; | 
					
						
							|  |  |  |   final VoidCallback onPressed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     return Row( | 
					
						
							|  |  |  |       mainAxisAlignment: MainAxisAlignment.spaceBetween, | 
					
						
							|  |  |  |       children: [ | 
					
						
							| 
									
										
										
										
											2022-02-25 22:16:51 +08:00
										 |  |  |         Row( | 
					
						
							|  |  |  |           children: [ | 
					
						
							|  |  |  |             SizedBox( | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                 width: 140, | 
					
						
							| 
									
										
										
										
											2022-02-28 21:26:44 +08:00
										 |  |  |                 child: Text(name, | 
					
						
							| 
									
										
										
										
											2022-02-25 22:16:51 +08:00
										 |  |  |                     style: TextStyle(fontSize: 16.0, color: MyTheme.accent50))), | 
					
						
							|  |  |  |             SizedBox( | 
					
						
							|  |  |  |               width: 50, | 
					
						
							|  |  |  |               child: Text(isOk ? translate("ON") : translate("OFF"), | 
					
						
							|  |  |  |                   style: TextStyle( | 
					
						
							|  |  |  |                       fontSize: 16.0, | 
					
						
							|  |  |  |                       color: isOk ? Colors.green : Colors.grey)), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         ), | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  |         TextButton( | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |             onPressed: onPressed, | 
					
						
							| 
									
										
										
										
											2022-02-16 23:08:23 +08:00
										 |  |  |             child: Text( | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |               translate(isOk ? "CLOSE" : "OPEN"), | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  |               style: TextStyle(fontWeight: FontWeight.bold), | 
					
						
							|  |  |  |             )), | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |         const Divider(height: 0) | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  |       ], | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-02 17:25:56 +08:00
										 |  |  | class ConnectionManager extends StatelessWidget { | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     final serverModel = Provider.of<ServerModel>(context); | 
					
						
							| 
									
										
										
										
											2022-03-19 23:28:29 +08:00
										 |  |  |     return Column( | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |         children: serverModel.clients.entries | 
					
						
							|  |  |  |             .map((entry) => PaddingCard( | 
					
						
							|  |  |  |                 title: translate(entry.value.isFileTransfer | 
					
						
							|  |  |  |                     ? "File Connection" | 
					
						
							|  |  |  |                     : "Screen Connection"), | 
					
						
							|  |  |  |                 titleIcon: entry.value.isFileTransfer | 
					
						
							|  |  |  |                     ? Icons.folder_outlined | 
					
						
							|  |  |  |                     : Icons.mobile_screen_share, | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                 child: Column( | 
					
						
							|  |  |  |                   crossAxisAlignment: CrossAxisAlignment.start, | 
					
						
							|  |  |  |                   children: [ | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |                     Row( | 
					
						
							|  |  |  |                       mainAxisAlignment: MainAxisAlignment.spaceBetween, | 
					
						
							|  |  |  |                       children: [ | 
					
						
							| 
									
										
										
										
											2022-04-28 22:44:54 +08:00
										 |  |  |                         Expanded(child: clientInfo(entry.value)), | 
					
						
							|  |  |  |                         Expanded( | 
					
						
							|  |  |  |                             flex: -1, | 
					
						
							|  |  |  |                             child: entry.value.isFileTransfer || | 
					
						
							|  |  |  |                                     !entry.value.authorized | 
					
						
							|  |  |  |                                 ? SizedBox.shrink() | 
					
						
							|  |  |  |                                 : IconButton( | 
					
						
							|  |  |  |                                     onPressed: () { | 
					
						
							|  |  |  |                                       FFI.chatModel | 
					
						
							|  |  |  |                                           .changeCurrentID(entry.value.id); | 
					
						
							|  |  |  |                                       final bar = | 
					
						
							|  |  |  |                                           navigationBarKey.currentWidget; | 
					
						
							|  |  |  |                                       if (bar != null) { | 
					
						
							|  |  |  |                                         bar as BottomNavigationBar; | 
					
						
							|  |  |  |                                         bar.onTap!(1); | 
					
						
							|  |  |  |                                       } | 
					
						
							|  |  |  |                                     }, | 
					
						
							|  |  |  |                                     icon: Icon( | 
					
						
							|  |  |  |                                       Icons.chat, | 
					
						
							|  |  |  |                                       color: MyTheme.accent80, | 
					
						
							|  |  |  |                                     ))) | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |                       ], | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                     ), | 
					
						
							| 
									
										
										
										
											2022-04-19 21:15:19 +08:00
										 |  |  |                     entry.value.authorized | 
					
						
							|  |  |  |                         ? SizedBox.shrink() | 
					
						
							|  |  |  |                         : Text( | 
					
						
							|  |  |  |                             translate("android_new_connection_tip"), | 
					
						
							|  |  |  |                             style: TextStyle(color: Colors.black54), | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                     entry.value.authorized | 
					
						
							|  |  |  |                         ? ElevatedButton.icon( | 
					
						
							|  |  |  |                             style: ButtonStyle( | 
					
						
							|  |  |  |                                 backgroundColor: | 
					
						
							|  |  |  |                                     MaterialStateProperty.all(Colors.red)), | 
					
						
							|  |  |  |                             icon: Icon(Icons.close), | 
					
						
							|  |  |  |                             onPressed: () { | 
					
						
							|  |  |  |                               FFI.setByName("close_conn", entry.key.toString()); | 
					
						
							|  |  |  |                               FFI.invokeMethod( | 
					
						
							|  |  |  |                                   "cancel_notification", entry.key); | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                             label: Text(translate("Close"))) | 
					
						
							|  |  |  |                         : Row(children: [ | 
					
						
							|  |  |  |                             TextButton( | 
					
						
							|  |  |  |                                 child: Text(translate("Dismiss")), | 
					
						
							|  |  |  |                                 onPressed: () { | 
					
						
							|  |  |  |                                   serverModel.sendLoginResponse( | 
					
						
							|  |  |  |                                       entry.value, false); | 
					
						
							|  |  |  |                                 }), | 
					
						
							|  |  |  |                             SizedBox(width: 20), | 
					
						
							|  |  |  |                             ElevatedButton( | 
					
						
							|  |  |  |                                 child: Text(translate("Accept")), | 
					
						
							|  |  |  |                                 onPressed: () { | 
					
						
							|  |  |  |                                   serverModel.sendLoginResponse( | 
					
						
							|  |  |  |                                       entry.value, true); | 
					
						
							|  |  |  |                                 }), | 
					
						
							|  |  |  |                           ]), | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |                   ], | 
					
						
							|  |  |  |                 ))) | 
					
						
							|  |  |  |             .toList()); | 
					
						
							| 
									
										
										
										
											2022-02-02 17:25:56 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | class PaddingCard extends StatelessWidget { | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |   PaddingCard({required this.child, this.title, this.titleIcon}); | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   final String? title; | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |   final IconData? titleIcon; | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   final Widget child; | 
					
						
							| 
									
										
										
										
											2022-02-02 17:25:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     final children = [child]; | 
					
						
							|  |  |  |     if (title != null) { | 
					
						
							|  |  |  |       children.insert( | 
					
						
							|  |  |  |           0, | 
					
						
							|  |  |  |           Padding( | 
					
						
							|  |  |  |               padding: EdgeInsets.symmetric(vertical: 5.0), | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |               child: Row( | 
					
						
							|  |  |  |                 children: [ | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |                   titleIcon != null | 
					
						
							|  |  |  |                       ? Padding( | 
					
						
							|  |  |  |                           padding: EdgeInsets.only(right: 10), | 
					
						
							|  |  |  |                           child: Icon(titleIcon, | 
					
						
							|  |  |  |                               color: MyTheme.accent80, size: 30)) | 
					
						
							|  |  |  |                       : SizedBox.shrink(), | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |                   Text( | 
					
						
							|  |  |  |                     title!, | 
					
						
							|  |  |  |                     style: TextStyle( | 
					
						
							|  |  |  |                       fontFamily: 'WorkSans', | 
					
						
							|  |  |  |                       fontWeight: FontWeight.bold, | 
					
						
							| 
									
										
										
										
											2022-03-23 16:28:37 +08:00
										 |  |  |                       fontSize: 20, | 
					
						
							| 
									
										
										
										
											2022-03-22 21:47:42 +08:00
										 |  |  |                       color: MyTheme.accent80, | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                   ) | 
					
						
							|  |  |  |                 ], | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |               ))); | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     return Container( | 
					
						
							|  |  |  |         width: double.maxFinite, | 
					
						
							|  |  |  |         child: Card( | 
					
						
							|  |  |  |           margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0), | 
					
						
							|  |  |  |           child: Padding( | 
					
						
							|  |  |  |             padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 30.0), | 
					
						
							|  |  |  |             child: Column( | 
					
						
							|  |  |  |               crossAxisAlignment: CrossAxisAlignment.start, | 
					
						
							|  |  |  |               children: children, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         )); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-02-02 17:25:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | Widget clientInfo(Client client) { | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |   return Padding( | 
					
						
							|  |  |  |       padding: EdgeInsets.symmetric(vertical: 8), | 
					
						
							|  |  |  |       child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ | 
					
						
							| 
									
										
										
										
											2022-04-12 20:54:29 +08:00
										 |  |  |         Row( | 
					
						
							|  |  |  |           children: [ | 
					
						
							| 
									
										
										
										
											2022-04-28 22:44:54 +08:00
										 |  |  |             Expanded( | 
					
						
							|  |  |  |                 flex: -1, | 
					
						
							|  |  |  |                 child: Padding( | 
					
						
							|  |  |  |                     padding: EdgeInsets.only(right: 12), | 
					
						
							|  |  |  |                     child: CircleAvatar( | 
					
						
							|  |  |  |                         child: Text(client.name[0]), | 
					
						
							|  |  |  |                         backgroundColor: MyTheme.border))), | 
					
						
							|  |  |  |             Expanded( | 
					
						
							|  |  |  |                 child: Column( | 
					
						
							|  |  |  |                     crossAxisAlignment: CrossAxisAlignment.start, | 
					
						
							|  |  |  |                     mainAxisAlignment: MainAxisAlignment.center, | 
					
						
							|  |  |  |                     children: [ | 
					
						
							| 
									
										
										
										
											2022-04-12 20:54:29 +08:00
										 |  |  |                   Text(client.name, | 
					
						
							| 
									
										
										
										
											2022-04-28 22:44:54 +08:00
										 |  |  |                       style: TextStyle(color: MyTheme.idColor, fontSize: 18)), | 
					
						
							| 
									
										
										
										
											2022-04-12 20:54:29 +08:00
										 |  |  |                   SizedBox(width: 8), | 
					
						
							|  |  |  |                   Text(client.peerId, | 
					
						
							|  |  |  |                       style: TextStyle(color: MyTheme.idColor, fontSize: 10)) | 
					
						
							| 
									
										
										
										
											2022-04-28 22:44:54 +08:00
										 |  |  |                 ])) | 
					
						
							| 
									
										
										
										
											2022-04-12 20:54:29 +08:00
										 |  |  |           ], | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ])); | 
					
						
							| 
									
										
										
										
											2022-01-23 21:37:19 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | void toAndroidChannelInit() { | 
					
						
							|  |  |  |   FFI.setMethodCallHandler((method, arguments) { | 
					
						
							| 
									
										
										
										
											2022-02-25 21:54:05 +08:00
										 |  |  |     debugPrint("flutter got android msg,$method,$arguments"); | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |     try { | 
					
						
							|  |  |  |       switch (method) { | 
					
						
							|  |  |  |         case "start_capture": | 
					
						
							|  |  |  |           { | 
					
						
							| 
									
										
										
										
											2022-04-19 13:07:45 +08:00
										 |  |  |             SmartDialog.dismiss(); | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |             FFI.serverModel.updateClientState(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |         case "on_state_changed": | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |           { | 
					
						
							|  |  |  |             var name = arguments["name"] as String; | 
					
						
							|  |  |  |             var value = arguments["value"] as String == "true"; | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |             debugPrint("from jvm:on_state_changed,$name:$value"); | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |             FFI.serverModel.changeStatue(name, value); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |         case "on_android_permission_result": | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             var type = arguments["type"] as String; | 
					
						
							|  |  |  |             var result = arguments["result"] as bool; | 
					
						
							|  |  |  |             PermissionManager.complete(type, result); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-04-12 20:54:29 +08:00
										 |  |  |         case "on_media_projection_canceled": | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             FFI.serverModel.stopService(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       debugPrint("MethodCallHandler err:$e"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ""; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } |