| 
									
										
										
										
											2022-04-26 21:21:08 +08:00
										 |  |  | import 'dart:async'; | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  | import 'package:flutter_hbb/common/widgets/setting_widgets.dart'; | 
					
						
							| 
									
										
										
										
											2023-01-12 21:03:05 +08:00
										 |  |  | import 'package:get/get.dart'; | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-24 23:33:00 +08:00
										 |  |  | import '../../common.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-08 22:27:27 +08:00
										 |  |  | import '../../models/platform_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-03-07 22:54:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-24 15:21:14 +08:00
										 |  |  | void _showSuccess() { | 
					
						
							| 
									
										
										
										
											2022-08-15 14:39:31 +08:00
										 |  |  |   showToast(translate("Successful")); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-24 15:21:14 +08:00
										 |  |  | void _showError() { | 
					
						
							| 
									
										
										
										
											2022-08-15 14:39:31 +08:00
										 |  |  |   showToast(translate("Error")); | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2023-05-08 12:34:19 +08:00
										 |  |  |   dialogManager.show((setState, close, context) { | 
					
						
							| 
									
										
										
										
											2023-01-30 17:56:35 +08:00
										 |  |  |     submit() async { | 
					
						
							|  |  |  |       close(); | 
					
						
							|  |  |  |       dialogManager.showLoading(translate("Waiting")); | 
					
						
							|  |  |  |       if (await gFFI.serverModel.setPermanentPassword(p0.text)) { | 
					
						
							|  |  |  |         dialogManager.dismissAll(); | 
					
						
							| 
									
										
										
										
											2023-03-24 15:21:14 +08:00
										 |  |  |         _showSuccess(); | 
					
						
							| 
									
										
										
										
											2023-01-30 17:56:35 +08:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         dialogManager.dismissAll(); | 
					
						
							| 
									
										
										
										
											2023-03-24 15:21:14 +08:00
										 |  |  |         _showError(); | 
					
						
							| 
									
										
										
										
											2023-01-30 17:56:35 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |     return CustomAlertDialog( | 
					
						
							| 
									
										
										
										
											2023-02-28 16:36:44 +01:00
										 |  |  |       title: Column( | 
					
						
							|  |  |  |         mainAxisAlignment: MainAxisAlignment.center, | 
					
						
							|  |  |  |         children: [ | 
					
						
							|  |  |  |           Icon(Icons.password_rounded, color: MyTheme.accent), | 
					
						
							|  |  |  |           Text(translate('Set your own password')).paddingOnly(left: 10), | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |       ), | 
					
						
							| 
									
										
										
										
											2023-03-01 14:50:50 +01:00
										 |  |  |       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), | 
					
						
							|  |  |  |                       () => setState(() => validateLength = val)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return val | 
					
						
							|  |  |  |                     ? null | 
					
						
							|  |  |  |                     : translate('Too short, at least 6 characters.'); | 
					
						
							|  |  |  |               }, | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2023-03-01 14:50:50 +01:00
										 |  |  |             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), | 
					
						
							|  |  |  |                       () => setState(() => validateSame = val)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return val | 
					
						
							|  |  |  |                     ? null | 
					
						
							|  |  |  |                     : translate('The confirmation is not identical.'); | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ])), | 
					
						
							| 
									
										
										
										
											2023-01-30 17:56:35 +08:00
										 |  |  |       onCancel: close, | 
					
						
							|  |  |  |       onSubmit: (validateLength && validateSame) ? submit : null, | 
					
						
							| 
									
										
										
										
											2023-03-01 14:50:50 +01:00
										 |  |  |       actions: [ | 
					
						
							|  |  |  |         dialogButton( | 
					
						
							|  |  |  |           'Cancel', | 
					
						
							|  |  |  |           icon: Icon(Icons.close_rounded), | 
					
						
							|  |  |  |           onPressed: close, | 
					
						
							|  |  |  |           isOutline: true, | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         dialogButton( | 
					
						
							|  |  |  |           'OK', | 
					
						
							|  |  |  |           icon: Icon(Icons.done_rounded), | 
					
						
							|  |  |  |           onPressed: (validateLength && validateSame) ? submit : null, | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ], | 
					
						
							| 
									
										
										
										
											2022-03-30 23:09:19 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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]; | 
					
						
							| 
									
										
										
										
											2023-05-08 12:34:19 +08:00
										 |  |  |   dialogManager.show((setState, close, context) { | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							| 
									
										
										
										
											2023-03-24 15:21:14 +08:00
										 |  |  |         _showSuccess(); | 
					
						
							| 
									
										
										
										
											2022-07-29 22:07:45 +08:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2022-09-22 17:38:18 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |     return CustomAlertDialog( | 
					
						
							| 
									
										
										
										
											2023-03-06 11:25:49 +08:00
										 |  |  |       title: Text(translate("Set one-time password length")), | 
					
						
							| 
									
										
										
										
											2023-03-30 04:11:48 +02:00
										 |  |  |       content: Row( | 
					
						
							|  |  |  |           mainAxisAlignment: MainAxisAlignment.spaceEvenly, | 
					
						
							|  |  |  |           children: lengths | 
					
						
							|  |  |  |               .map( | 
					
						
							|  |  |  |                 (value) => Row( | 
					
						
							|  |  |  |                   children: [ | 
					
						
							|  |  |  |                     Text(value), | 
					
						
							|  |  |  |                     Radio( | 
					
						
							|  |  |  |                         value: value, groupValue: length, onChanged: setLength), | 
					
						
							|  |  |  |                   ], | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |               .toList()), | 
					
						
							| 
									
										
										
										
											2022-07-29 18:34:25 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   }, backDismiss: true, clickMaskDismiss: true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 16:24:01 +09:00
										 |  |  | void showServerSettingsWithValue( | 
					
						
							|  |  |  |     ServerConfig serverConfig, OverlayDialogManager dialogManager) async { | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |   var isInProgress = false; | 
					
						
							| 
									
										
										
										
											2022-12-21 16:24:01 +09:00
										 |  |  |   final idCtrl = TextEditingController(text: serverConfig.idServer); | 
					
						
							|  |  |  |   final relayCtrl = TextEditingController(text: serverConfig.relayServer); | 
					
						
							|  |  |  |   final apiCtrl = TextEditingController(text: serverConfig.apiServer); | 
					
						
							|  |  |  |   final keyCtrl = TextEditingController(text: serverConfig.key); | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |   RxString idServerMsg = ''.obs; | 
					
						
							|  |  |  |   RxString relayServerMsg = ''.obs; | 
					
						
							|  |  |  |   RxString apiServerMsg = ''.obs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   final controllers = [idCtrl, relayCtrl, apiCtrl, keyCtrl]; | 
					
						
							|  |  |  |   final errMsgs = [ | 
					
						
							|  |  |  |     idServerMsg, | 
					
						
							|  |  |  |     relayServerMsg, | 
					
						
							|  |  |  |     apiServerMsg, | 
					
						
							|  |  |  |   ]; | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-08 12:34:19 +08:00
										 |  |  |   dialogManager.show((setState, close, context) { | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |     Future<bool> submit() async { | 
					
						
							|  |  |  |       setState(() { | 
					
						
							|  |  |  |         isInProgress = true; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       bool ret = await setServerConfig( | 
					
						
							|  |  |  |           controllers, | 
					
						
							|  |  |  |           errMsgs, | 
					
						
							|  |  |  |           ServerConfig( | 
					
						
							|  |  |  |               idServer: idCtrl.text.trim(), | 
					
						
							|  |  |  |               relayServer: relayCtrl.text.trim(), | 
					
						
							|  |  |  |               apiServer: apiCtrl.text.trim(), | 
					
						
							|  |  |  |               key: keyCtrl.text.trim())); | 
					
						
							|  |  |  |       setState(() { | 
					
						
							|  |  |  |         isInProgress = false; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       return ret; | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return CustomAlertDialog( | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |       title: Row( | 
					
						
							|  |  |  |         children: [ | 
					
						
							|  |  |  |           Expanded(child: Text(translate('ID/Relay Server'))), | 
					
						
							|  |  |  |           ...ServerConfigImportExportWidgets(controllers, errMsgs), | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |       ), | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |       content: Form( | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |           child: Obx(() => Column( | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |               mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |               children: <Widget>[ | 
					
						
							|  |  |  |                     TextFormField( | 
					
						
							| 
									
										
										
										
											2022-12-21 16:24:01 +09:00
										 |  |  |                       controller: idCtrl, | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |                       decoration: InputDecoration( | 
					
						
							|  |  |  |                           labelText: translate('ID Server'), | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |                           errorText: idServerMsg.value.isEmpty | 
					
						
							|  |  |  |                               ? null | 
					
						
							|  |  |  |                               : idServerMsg.value), | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                   ] + | 
					
						
							|  |  |  |                   [ | 
					
						
							|  |  |  |                     TextFormField( | 
					
						
							|  |  |  |                       controller: relayCtrl, | 
					
						
							|  |  |  |                       decoration: InputDecoration( | 
					
						
							|  |  |  |                           labelText: translate('Relay Server'), | 
					
						
							|  |  |  |                           errorText: relayServerMsg.value.isEmpty | 
					
						
							|  |  |  |                               ? null | 
					
						
							|  |  |  |                               : relayServerMsg.value), | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |                     ) | 
					
						
							|  |  |  |                   ] + | 
					
						
							|  |  |  |                   [ | 
					
						
							|  |  |  |                     TextFormField( | 
					
						
							| 
									
										
										
										
											2022-12-21 16:24:01 +09:00
										 |  |  |                       controller: apiCtrl, | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |                       decoration: InputDecoration( | 
					
						
							|  |  |  |                         labelText: translate('API Server'), | 
					
						
							|  |  |  |                       ), | 
					
						
							|  |  |  |                       autovalidateMode: AutovalidateMode.onUserInteraction, | 
					
						
							|  |  |  |                       validator: (v) { | 
					
						
							|  |  |  |                         if (v != null && v.isNotEmpty) { | 
					
						
							|  |  |  |                           if (!(v.startsWith('http://') || | 
					
						
							|  |  |  |                               v.startsWith("https://"))) { | 
					
						
							|  |  |  |                             return translate("invalid_http"); | 
					
						
							|  |  |  |                           } | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |                         return null; | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |                       }, | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                     TextFormField( | 
					
						
							| 
									
										
										
										
											2022-12-21 16:24:01 +09:00
										 |  |  |                       controller: keyCtrl, | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |                       decoration: InputDecoration( | 
					
						
							|  |  |  |                         labelText: 'Key', | 
					
						
							|  |  |  |                       ), | 
					
						
							|  |  |  |                     ), | 
					
						
							| 
									
										
										
										
											2023-08-18 16:13:24 +08:00
										 |  |  |                     // NOT use Offstage to wrap LinearProgressIndicator
 | 
					
						
							|  |  |  |                     if (isInProgress) const LinearProgressIndicator(), | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |                   ]))), | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |       actions: [ | 
					
						
							| 
									
										
										
										
											2023-01-15 19:46:16 +08:00
										 |  |  |         dialogButton('Cancel', onPressed: () { | 
					
						
							|  |  |  |           close(); | 
					
						
							|  |  |  |         }, isOutline: true), | 
					
						
							|  |  |  |         dialogButton( | 
					
						
							|  |  |  |           'OK', | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |           onPressed: () async { | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |             if (await submit()) { | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |               close(); | 
					
						
							| 
									
										
										
										
											2022-12-26 10:12:01 +09:00
										 |  |  |               showToast(translate('Successful')); | 
					
						
							| 
									
										
										
										
											2023-08-31 20:30:20 +08:00
										 |  |  |             } else { | 
					
						
							|  |  |  |               showToast(translate('Failed')); | 
					
						
							| 
									
										
										
										
											2022-12-21 15:41:07 +09:00
										 |  |  |             } | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Future<String?> validateAsync(String value) async { | 
					
						
							|  |  |  |   value = value.trim(); | 
					
						
							|  |  |  |   if (value.isEmpty) { | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   final res = await bind.mainTestIfValidServer(server: value); | 
					
						
							|  |  |  |   return res.isEmpty ? null : res; | 
					
						
							|  |  |  | } |