| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  | import 'dart:async'; | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-24 23:33:00 +08:00
										 |  |  | import '../../common.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-15 19:31:58 +08:00
										 |  |  | import '../../models/model.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  | import '../../models/platform_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-15 16:49:55 +08:00
										 |  |  | void clientClose(String id, OverlayDialogManager dialogManager) { | 
					
						
							|  |  |  |   msgBox(id, '', 'Close', 'Are you sure to close the connection?', '', | 
					
						
							|  |  |  |       dialogManager); | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-15 14:39:31 +08:00
										 |  |  | void showSuccess() { | 
					
						
							|  |  |  |   showToast(translate("Successful")); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-15 14:39:31 +08:00
										 |  |  | void showError() { | 
					
						
							|  |  |  |   showToast(translate("Error")); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-15 19:31:58 +08:00
										 |  |  | void showRestartRemoteDevice( | 
					
						
							|  |  |  |     PeerInfo pi, String id, OverlayDialogManager dialogManager) async { | 
					
						
							|  |  |  |   final res = | 
					
						
							|  |  |  |       await dialogManager.show<bool>((setState, close) => CustomAlertDialog( | 
					
						
							|  |  |  |             title: Row(children: [ | 
					
						
							|  |  |  |               Icon(Icons.warning_amber_sharp, | 
					
						
							|  |  |  |                   color: Colors.redAccent, size: 28), | 
					
						
							|  |  |  |               SizedBox(width: 10), | 
					
						
							|  |  |  |               Text(translate("Restart Remote Device")), | 
					
						
							|  |  |  |             ]), | 
					
						
							|  |  |  |             content: Text( | 
					
						
							|  |  |  |                 "${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"), | 
					
						
							|  |  |  |             actions: [ | 
					
						
							|  |  |  |               TextButton( | 
					
						
							|  |  |  |                   onPressed: () => close(), child: Text(translate("Cancel"))), | 
					
						
							|  |  |  |               ElevatedButton( | 
					
						
							|  |  |  |                   onPressed: () => close(true), child: Text(translate("OK"))), | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |           )); | 
					
						
							|  |  |  |   if (res == true) bind.sessionRestartRemoteDevice(id: id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  | void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async { | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |   final pw = await bind.mainGetPermanentPassword(); | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |   final p0 = TextEditingController(text: pw); | 
					
						
							|  |  |  |   final p1 = TextEditingController(text: pw); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |   var validateLength = false; | 
					
						
							|  |  |  |   var validateSame = false; | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  |   dialogManager.show((setState, close) { | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |     return CustomAlertDialog( | 
					
						
							|  |  |  |       title: Text(translate('Set your own password')), | 
					
						
							|  |  |  |       content: Form( | 
					
						
							|  |  |  |           autovalidateMode: AutovalidateMode.onUserInteraction, | 
					
						
							|  |  |  |           child: Column(mainAxisSize: MainAxisSize.min, children: [ | 
					
						
							|  |  |  |             TextFormField( | 
					
						
							|  |  |  |               autofocus: true, | 
					
						
							|  |  |  |               obscureText: true, | 
					
						
							|  |  |  |               keyboardType: TextInputType.visiblePassword, | 
					
						
							|  |  |  |               decoration: InputDecoration( | 
					
						
							|  |  |  |                 labelText: translate('Password'), | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |               controller: p0, | 
					
						
							|  |  |  |               validator: (v) { | 
					
						
							|  |  |  |                 if (v == null) return null; | 
					
						
							|  |  |  |                 final val = v.trim().length > 5; | 
					
						
							|  |  |  |                 if (validateLength != val) { | 
					
						
							|  |  |  |                   // use delay to make setState success
 | 
					
						
							|  |  |  |                   Future.delayed(Duration(microseconds: 1), | 
					
						
							| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  |                       () => setState(() => validateLength = val)); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 return val | 
					
						
							|  |  |  |                     ? null | 
					
						
							|  |  |  |                     : translate('Too short, at least 6 characters.'); | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             TextFormField( | 
					
						
							|  |  |  |               obscureText: true, | 
					
						
							|  |  |  |               keyboardType: TextInputType.visiblePassword, | 
					
						
							|  |  |  |               decoration: InputDecoration( | 
					
						
							|  |  |  |                 labelText: translate('Confirmation'), | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |               controller: p1, | 
					
						
							|  |  |  |               validator: (v) { | 
					
						
							|  |  |  |                 if (v == null) return null; | 
					
						
							|  |  |  |                 final val = p0.text == v; | 
					
						
							|  |  |  |                 if (validateSame != val) { | 
					
						
							|  |  |  |                   Future.delayed(Duration(microseconds: 1), | 
					
						
							| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  |                       () => setState(() => validateSame = val)); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 return val | 
					
						
							|  |  |  |                     ? null | 
					
						
							|  |  |  |                     : translate('The confirmation is not identical.'); | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ])), | 
					
						
							|  |  |  |       actions: [ | 
					
						
							|  |  |  |         TextButton( | 
					
						
							|  |  |  |           style: flatButtonStyle, | 
					
						
							|  |  |  |           onPressed: () { | 
					
						
							|  |  |  |             close(); | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           child: Text(translate('Cancel')), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         TextButton( | 
					
						
							|  |  |  |           style: flatButtonStyle, | 
					
						
							|  |  |  |           onPressed: (validateLength && validateSame) | 
					
						
							|  |  |  |               ? () async { | 
					
						
							| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  |                   close(); | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  |                   dialogManager.showLoading(translate("Waiting")); | 
					
						
							| 
									
										
										
										
											2022-08-01 10:44:05 +08:00
										 |  |  |                   if (await gFFI.serverModel.setPermanentPassword(p0.text)) { | 
					
						
							| 
									
										
										
										
											2022-08-15 14:43:08 +08:00
										 |  |  |                     dialogManager.dismissAll(); | 
					
						
							| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  |                     showSuccess(); | 
					
						
							|  |  |  |                   } else { | 
					
						
							| 
									
										
										
										
											2022-08-15 14:43:08 +08:00
										 |  |  |                     dialogManager.dismissAll(); | 
					
						
							| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  |                     showError(); | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |               : null, | 
					
						
							|  |  |  |           child: Text(translate('OK')), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  | void setTemporaryPasswordLengthDialog( | 
					
						
							|  |  |  |     OverlayDialogManager dialogManager) async { | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |   List<String> lengths = ['6', '8', '10']; | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |   String length = await bind.mainGetOption(key: "temporary-password-length"); | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |   var index = lengths.indexOf(length); | 
					
						
							|  |  |  |   if (index < 0) index = 0; | 
					
						
							|  |  |  |   length = lengths[index]; | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  |   dialogManager.show((setState, close) { | 
					
						
							| 
									
										
										
										
											2022-09-22 17:38:18 +08:00
										 |  |  |     setLength(newValue) { | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |       final oldValue = length; | 
					
						
							|  |  |  |       if (oldValue == newValue) return; | 
					
						
							|  |  |  |       setState(() { | 
					
						
							|  |  |  |         length = newValue; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  |       bind.mainSetOption(key: "temporary-password-length", value: newValue); | 
					
						
							|  |  |  |       bind.mainUpdateTemporaryPassword(); | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |       Future.delayed(Duration(milliseconds: 200), () { | 
					
						
							|  |  |  |         close(); | 
					
						
							|  |  |  |         showSuccess(); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2022-09-22 17:38:18 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |     return CustomAlertDialog( | 
					
						
							|  |  |  |       title: Text(translate("Set temporary password length")), | 
					
						
							|  |  |  |       content: Column( | 
					
						
							|  |  |  |           mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |           children: | 
					
						
							|  |  |  |               lengths.map((e) => getRadio(e, e, length, setLength)).toList()), | 
					
						
							|  |  |  |       actions: [], | 
					
						
							|  |  |  |       contentPadding: 14, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }, backDismiss: true, clickMaskDismiss: true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  | void enterPasswordDialog(String id, OverlayDialogManager dialogManager) async { | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  |   final controller = TextEditingController(); | 
					
						
							| 
									
										
										
										
											2022-08-16 15:22:57 +08:00
										 |  |  |   var remember = await bind.sessionGetRemember(id: id) ?? false; | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  |   dialogManager.dismissAll(); | 
					
						
							|  |  |  |   dialogManager.show((setState, close) { | 
					
						
							| 
									
										
										
										
											2022-09-29 10:48:27 +08:00
										 |  |  |     cancel() { | 
					
						
							|  |  |  |       close(); | 
					
						
							|  |  |  |       closeConnection(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     submit() { | 
					
						
							|  |  |  |       var text = controller.text.trim(); | 
					
						
							|  |  |  |       if (text == '') return; | 
					
						
							|  |  |  |       gFFI.login(id, text, remember); | 
					
						
							|  |  |  |       close(); | 
					
						
							|  |  |  |       dialogManager.showLoading(translate('Logging in...'), | 
					
						
							|  |  |  |           onCancel: closeConnection); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |     return CustomAlertDialog( | 
					
						
							|  |  |  |       title: Text(translate('Password Required')), | 
					
						
							|  |  |  |       content: Column(mainAxisSize: MainAxisSize.min, children: [ | 
					
						
							|  |  |  |         PasswordWidget(controller: controller), | 
					
						
							|  |  |  |         CheckboxListTile( | 
					
						
							|  |  |  |           contentPadding: const EdgeInsets.all(0), | 
					
						
							|  |  |  |           dense: true, | 
					
						
							|  |  |  |           controlAffinity: ListTileControlAffinity.leading, | 
					
						
							|  |  |  |           title: Text( | 
					
						
							|  |  |  |             translate('Remember password'), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           value: remember, | 
					
						
							|  |  |  |           onChanged: (v) { | 
					
						
							|  |  |  |             if (v != null) { | 
					
						
							|  |  |  |               setState(() => remember = v); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  |         ), | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |       ]), | 
					
						
							|  |  |  |       actions: [ | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  |         TextButton( | 
					
						
							|  |  |  |           style: flatButtonStyle, | 
					
						
							| 
									
										
										
										
											2022-09-29 10:48:27 +08:00
										 |  |  |           onPressed: cancel, | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  |           child: Text(translate('Cancel')), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         TextButton( | 
					
						
							|  |  |  |           style: flatButtonStyle, | 
					
						
							| 
									
										
										
										
											2022-09-29 10:48:27 +08:00
										 |  |  |           onPressed: submit, | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |           child: Text(translate('OK')), | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  |         ), | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |       ], | 
					
						
							| 
									
										
										
										
											2022-09-29 10:48:27 +08:00
										 |  |  |       onSubmit: submit, | 
					
						
							|  |  |  |       onCancel: cancel, | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  | void wrongPasswordDialog(String id, OverlayDialogManager dialogManager) { | 
					
						
							|  |  |  |   dialogManager.show((setState, close) => CustomAlertDialog( | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |           title: Text(translate('Wrong Password')), | 
					
						
							|  |  |  |           content: Text(translate('Do you want to enter again?')), | 
					
						
							|  |  |  |           actions: [ | 
					
						
							|  |  |  |             TextButton( | 
					
						
							|  |  |  |               style: flatButtonStyle, | 
					
						
							|  |  |  |               onPressed: () { | 
					
						
							| 
									
										
										
										
											2022-03-13 23:07:52 +08:00
										 |  |  |                 close(); | 
					
						
							| 
									
										
										
										
											2022-08-16 21:27:21 +08:00
										 |  |  |                 closeConnection(); | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |               }, | 
					
						
							|  |  |  |               child: Text(translate('Cancel')), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             TextButton( | 
					
						
							|  |  |  |               style: flatButtonStyle, | 
					
						
							|  |  |  |               onPressed: () { | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  |                 enterPasswordDialog(id, dialogManager); | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |               }, | 
					
						
							|  |  |  |               child: Text(translate('Retry')), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ])); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PasswordWidget extends StatefulWidget { | 
					
						
							| 
									
										
										
										
											2022-09-22 17:38:18 +08:00
										 |  |  |   PasswordWidget({Key? key, required this.controller, this.autoFocus = true}) | 
					
						
							|  |  |  |       : super(key: key); | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   final TextEditingController controller; | 
					
						
							| 
									
										
										
										
											2022-09-22 17:38:18 +08:00
										 |  |  |   final bool autoFocus; | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							| 
									
										
										
										
											2022-09-22 17:38:18 +08:00
										 |  |  |   State<PasswordWidget> createState() => _PasswordWidgetState(); | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _PasswordWidgetState extends State<PasswordWidget> { | 
					
						
							|  |  |  |   bool _passwordVisible = false; | 
					
						
							| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  |   final _focusNode = FocusNode(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void initState() { | 
					
						
							|  |  |  |     super.initState(); | 
					
						
							| 
									
										
										
										
											2022-09-22 17:38:18 +08:00
										 |  |  |     if (widget.autoFocus) { | 
					
						
							|  |  |  |       Timer(Duration(milliseconds: 50), () => _focusNode.requestFocus()); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void dispose() { | 
					
						
							|  |  |  |     _focusNode.unfocus(); | 
					
						
							|  |  |  |     _focusNode.dispose(); | 
					
						
							|  |  |  |     super.dispose(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     return TextField( | 
					
						
							| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  |       focusNode: _focusNode, | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |       controller: widget.controller, | 
					
						
							|  |  |  |       obscureText: !_passwordVisible, | 
					
						
							|  |  |  |       //This will obscure text dynamically
 | 
					
						
							|  |  |  |       keyboardType: TextInputType.visiblePassword, | 
					
						
							|  |  |  |       decoration: InputDecoration( | 
					
						
							| 
									
										
										
										
											2022-08-12 18:42:02 +08:00
										 |  |  |         labelText: translate('Password'), | 
					
						
							|  |  |  |         hintText: translate('Enter your password'), | 
					
						
							| 
									
										
										
										
											2022-03-13 00:32:44 +08:00
										 |  |  |         // Here is key idea
 | 
					
						
							|  |  |  |         suffixIcon: IconButton( | 
					
						
							|  |  |  |           icon: Icon( | 
					
						
							|  |  |  |             // Based on passwordVisible state choose the icon
 | 
					
						
							|  |  |  |             _passwordVisible ? Icons.visibility : Icons.visibility_off, | 
					
						
							|  |  |  |             color: Theme.of(context).primaryColorDark, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           onPressed: () { | 
					
						
							|  |  |  |             // Update the state i.e. toogle the state of passwordVisible variable
 | 
					
						
							|  |  |  |             setState(() { | 
					
						
							|  |  |  |               _passwordVisible = !_passwordVisible; | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |