| 
									
										
										
										
											2022-09-19 18:38:19 +08:00
										 |  |  | // main window right pane
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-25 16:23:45 +08:00
										 |  |  | import 'dart:async'; | 
					
						
							| 
									
										
										
										
											2023-06-23 18:25:42 +08:00
										 |  |  | import 'dart:convert'; | 
					
						
							| 
									
										
										
										
											2022-07-22 23:12:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  | import 'package:auto_size_text/auto_size_text.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-23 15:12:50 +08:00
										 |  |  | import 'package:flutter_hbb/consts.dart'; | 
					
						
							| 
									
										
										
										
											2023-01-30 21:42:58 +08:00
										 |  |  | import 'package:flutter_hbb/models/state_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  | import 'package:get/get.dart'; | 
					
						
							| 
									
										
										
										
											2022-07-25 16:23:45 +08:00
										 |  |  | import 'package:url_launcher/url_launcher_string.dart'; | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  | import 'package:window_manager/window_manager.dart'; | 
					
						
							| 
									
										
										
										
											2023-10-13 23:10:31 +05:30
										 |  |  | import 'package:flutter_hbb/models/peer_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  | import '../../common.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-02 17:19:44 +08:00
										 |  |  | import '../../common/formatter/id_formatter.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-19 20:26:39 +08:00
										 |  |  | import '../../common/widgets/peer_tab_page.dart'; | 
					
						
							| 
									
										
										
										
											2023-10-24 05:30:43 +05:30
										 |  |  | import '../../common/widgets/autocomplete.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-03 22:03:31 +08:00
										 |  |  | import '../../models/platform_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-23 17:28:22 +08:00
										 |  |  | import '../widgets/button.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												Feat. Quick support, ui (#7267)
* Feat. QS ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Remove 'Quick support'
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* add help card
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* use addPostFrameCallback to get child size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Fix. qs, set home window size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, set setResizable for settings page
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, help cards margin bottom
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, use margin instead of padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, fix, start cm window
Signed-off-by: fufesou <shuanglongchen@yeah.net>
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
											
										 
											2024-02-27 17:02:10 +08:00
										 |  |  | class OnlineStatusWidget extends StatefulWidget { | 
					
						
							| 
									
										
											  
											
												Fix/custom client styles (#7373)
* Fix. qs styles
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* custom client, options
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Move logo.svg to icon.svg
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Refact. Custom client, connection status ui.
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client ui. Disable settings, hide "Change password"
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, logo align center
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, refact, outgoing ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, outgoing, settings icon
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, powered by RustDesk
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, remove unused SizeBox
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Update config.rs
* Update flutter_ffi.rs
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
											
										 
											2024-03-14 11:36:14 +08:00
										 |  |  |   const OnlineStatusWidget({Key? key, this.onSvcStatusChanged}) | 
					
						
							|  |  |  |       : super(key: key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   final VoidCallback? onSvcStatusChanged; | 
					
						
							| 
									
										
										
											
												Feat. Quick support, ui (#7267)
* Feat. QS ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Remove 'Quick support'
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* add help card
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* use addPostFrameCallback to get child size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Fix. qs, set home window size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, set setResizable for settings page
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, help cards margin bottom
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, use margin instead of padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, fix, start cm window
Signed-off-by: fufesou <shuanglongchen@yeah.net>
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
											
										 
											2024-02-27 17:02:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   State<OnlineStatusWidget> createState() => _OnlineStatusWidgetState(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// State for the connection page.
 | 
					
						
							|  |  |  | class _OnlineStatusWidgetState extends State<OnlineStatusWidget> { | 
					
						
							|  |  |  |   final _svcStopped = Get.find<RxBool>(tag: 'stop-service'); | 
					
						
							|  |  |  |   final _svcIsUsingPublicServer = true.obs; | 
					
						
							|  |  |  |   Timer? _updateTimer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   double get em => 14.0; | 
					
						
							| 
									
										
											  
											
												Fix/custom client styles (#7373)
* Fix. qs styles
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* custom client, options
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Move logo.svg to icon.svg
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Refact. Custom client, connection status ui.
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client ui. Disable settings, hide "Change password"
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, logo align center
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, refact, outgoing ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, outgoing, settings icon
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, powered by RustDesk
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, remove unused SizeBox
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Update config.rs
* Update flutter_ffi.rs
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
											
										 
											2024-03-14 11:36:14 +08:00
										 |  |  |   double? get height => bind.isIncomingOnly() ? null : em * 3; | 
					
						
							| 
									
										
										
											
												Feat. Quick support, ui (#7267)
* Feat. QS ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Remove 'Quick support'
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* add help card
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* use addPostFrameCallback to get child size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Fix. qs, set home window size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, set setResizable for settings page
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, help cards margin bottom
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, use margin instead of padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, fix, start cm window
Signed-off-by: fufesou <shuanglongchen@yeah.net>
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
											
										 
											2024-02-27 17:02:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void onUsePublicServerGuide() { | 
					
						
							|  |  |  |     const url = "https://rustdesk.com/pricing.html"; | 
					
						
							|  |  |  |     canLaunchUrlString(url).then((can) { | 
					
						
							|  |  |  |       if (can) { | 
					
						
							|  |  |  |         launchUrlString(url); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void initState() { | 
					
						
							|  |  |  |     super.initState(); | 
					
						
							|  |  |  |     _updateTimer = periodic_immediate(Duration(seconds: 1), () async { | 
					
						
							|  |  |  |       updateStatus(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void dispose() { | 
					
						
							|  |  |  |     _updateTimer?.cancel(); | 
					
						
							|  |  |  |     super.dispose(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2024-03-15 00:26:53 +08:00
										 |  |  |     final isIncomingOnly = bind.isIncomingOnly(); | 
					
						
							| 
									
										
										
										
											2024-04-02 21:59:17 +08:00
										 |  |  |     startServiceWidget() => Offstage( | 
					
						
							|  |  |  |           offstage: !_svcStopped.value, | 
					
						
							|  |  |  |           child: InkWell( | 
					
						
							|  |  |  |                   onTap: () async { | 
					
						
							|  |  |  |                     await start_service(true); | 
					
						
							|  |  |  |                   }, | 
					
						
							|  |  |  |                   child: Text(translate("Start service"), | 
					
						
							|  |  |  |                       style: TextStyle( | 
					
						
							|  |  |  |                           decoration: TextDecoration.underline, fontSize: em))) | 
					
						
							|  |  |  |               .marginOnly(left: em), | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setupServerWidget() => Flexible( | 
					
						
							|  |  |  |           child: Offstage( | 
					
						
							|  |  |  |             offstage: !(!_svcStopped.value && | 
					
						
							|  |  |  |                 stateGlobal.svcStatus.value == SvcStatus.ready && | 
					
						
							|  |  |  |                 _svcIsUsingPublicServer.value), | 
					
						
							|  |  |  |             child: Row( | 
					
						
							|  |  |  |               crossAxisAlignment: CrossAxisAlignment.center, | 
					
						
							|  |  |  |               children: [ | 
					
						
							|  |  |  |                 Text(', ', style: TextStyle(fontSize: em)), | 
					
						
							| 
									
										
										
										
											2024-03-15 00:26:53 +08:00
										 |  |  |                 Flexible( | 
					
						
							| 
									
										
										
										
											2024-04-02 21:59:17 +08:00
										 |  |  |                   child: InkWell( | 
					
						
							|  |  |  |                     onTap: onUsePublicServerGuide, | 
					
						
							| 
									
										
										
										
											2024-03-15 00:26:53 +08:00
										 |  |  |                     child: Row( | 
					
						
							|  |  |  |                       children: [ | 
					
						
							|  |  |  |                         Flexible( | 
					
						
							| 
									
										
										
										
											2024-04-02 21:59:17 +08:00
										 |  |  |                           child: Text( | 
					
						
							|  |  |  |                             translate('setup_server_tip'), | 
					
						
							|  |  |  |                             style: TextStyle( | 
					
						
							|  |  |  |                                 decoration: TextDecoration.underline, | 
					
						
							|  |  |  |                                 fontSize: em), | 
					
						
							| 
									
										
										
											
												Feat. Quick support, ui (#7267)
* Feat. QS ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Remove 'Quick support'
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* add help card
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* use addPostFrameCallback to get child size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Fix. qs, set home window size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, set setResizable for settings page
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, help cards margin bottom
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, use margin instead of padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, fix, start cm window
Signed-off-by: fufesou <shuanglongchen@yeah.net>
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
											
										 
											2024-02-27 17:02:10 +08:00
										 |  |  |                           ), | 
					
						
							| 
									
										
										
										
											2024-04-02 21:59:17 +08:00
										 |  |  |                         ), | 
					
						
							| 
									
										
										
										
											2024-03-15 00:26:53 +08:00
										 |  |  |                       ], | 
					
						
							|  |  |  |                     ), | 
					
						
							| 
									
										
										
											
												Feat. Quick support, ui (#7267)
* Feat. QS ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Remove 'Quick support'
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* add help card
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* use addPostFrameCallback to get child size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Fix. qs, set home window size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, set setResizable for settings page
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, help cards margin bottom
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, use margin instead of padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, fix, start cm window
Signed-off-by: fufesou <shuanglongchen@yeah.net>
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
											
										 
											2024-02-27 17:02:10 +08:00
										 |  |  |                   ), | 
					
						
							| 
									
										
										
										
											2024-03-15 00:26:53 +08:00
										 |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-04-02 21:59:17 +08:00
										 |  |  |               ], | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     basicWidget() => Row( | 
					
						
							|  |  |  |           crossAxisAlignment: CrossAxisAlignment.center, | 
					
						
							|  |  |  |           children: [ | 
					
						
							|  |  |  |             Container( | 
					
						
							|  |  |  |               height: 8, | 
					
						
							|  |  |  |               width: 8, | 
					
						
							|  |  |  |               decoration: BoxDecoration( | 
					
						
							|  |  |  |                 borderRadius: BorderRadius.circular(4), | 
					
						
							|  |  |  |                 color: _svcStopped.value || | 
					
						
							|  |  |  |                         stateGlobal.svcStatus.value == SvcStatus.connecting | 
					
						
							|  |  |  |                     ? kColorWarn | 
					
						
							|  |  |  |                     : (stateGlobal.svcStatus.value == SvcStatus.ready | 
					
						
							|  |  |  |                         ? Color.fromARGB(255, 50, 190, 166) | 
					
						
							|  |  |  |                         : Color.fromARGB(255, 224, 79, 95)), | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |             ).marginSymmetric(horizontal: em), | 
					
						
							|  |  |  |             Container( | 
					
						
							|  |  |  |               width: isIncomingOnly ? 226 : null, | 
					
						
							|  |  |  |               child: _buildConnStatusMsg(), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             // stop
 | 
					
						
							|  |  |  |             if (!isIncomingOnly) startServiceWidget(), | 
					
						
							|  |  |  |             // ready && public
 | 
					
						
							|  |  |  |             // No need to show the guide if is custom client.
 | 
					
						
							|  |  |  |             if (!isIncomingOnly) setupServerWidget(), | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Container( | 
					
						
							|  |  |  |       height: height, | 
					
						
							|  |  |  |       child: Obx(() => isIncomingOnly | 
					
						
							|  |  |  |           ? Column( | 
					
						
							|  |  |  |               children: [ | 
					
						
							|  |  |  |                 basicWidget(), | 
					
						
							|  |  |  |                 Align( | 
					
						
							|  |  |  |                         child: startServiceWidget(), | 
					
						
							|  |  |  |                         alignment: Alignment.centerLeft) | 
					
						
							|  |  |  |                     .marginOnly(top: 2.0, left: 22.0), | 
					
						
							|  |  |  |               ], | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |           : basicWidget()), | 
					
						
							| 
									
										
										
										
											2024-03-15 00:26:53 +08:00
										 |  |  |     ).paddingOnly(right: isIncomingOnly ? 8 : 0); | 
					
						
							| 
									
										
										
											
												Feat. Quick support, ui (#7267)
* Feat. QS ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Remove 'Quick support'
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* add help card
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* use addPostFrameCallback to get child size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Fix. qs, set home window size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, set setResizable for settings page
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, help cards margin bottom
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, use margin instead of padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, fix, start cm window
Signed-off-by: fufesou <shuanglongchen@yeah.net>
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
											
										 
											2024-02-27 17:02:10 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Fix/custom client styles (#7373)
* Fix. qs styles
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* custom client, options
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Move logo.svg to icon.svg
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Refact. Custom client, connection status ui.
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client ui. Disable settings, hide "Change password"
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, logo align center
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, refact, outgoing ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, outgoing, settings icon
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, powered by RustDesk
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Custom client, remove unused SizeBox
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Update config.rs
* Update flutter_ffi.rs
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
											
										 
											2024-03-14 11:36:14 +08:00
										 |  |  |   _buildConnStatusMsg() { | 
					
						
							|  |  |  |     widget.onSvcStatusChanged?.call(); | 
					
						
							|  |  |  |     return Text( | 
					
						
							|  |  |  |       _svcStopped.value | 
					
						
							|  |  |  |           ? translate("Service is not running") | 
					
						
							|  |  |  |           : stateGlobal.svcStatus.value == SvcStatus.connecting | 
					
						
							|  |  |  |               ? translate("connecting_status") | 
					
						
							|  |  |  |               : stateGlobal.svcStatus.value == SvcStatus.notReady | 
					
						
							|  |  |  |                   ? translate("not_ready_status") | 
					
						
							|  |  |  |                   : translate('Ready'), | 
					
						
							|  |  |  |       style: TextStyle(fontSize: em), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Feat. Quick support, ui (#7267)
* Feat. QS ui
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Remove 'Quick support'
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* add help card
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* use addPostFrameCallback to get child size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Fix. qs, set home window size
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, set setResizable for settings page
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, help cards margin bottom
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, online status, use margin instead of padding
Signed-off-by: fufesou <shuanglongchen@yeah.net>
* Qs, fix, start cm window
Signed-off-by: fufesou <shuanglongchen@yeah.net>
---------
Signed-off-by: fufesou <shuanglongchen@yeah.net>
											
										 
											2024-02-27 17:02:10 +08:00
										 |  |  |   updateStatus() async { | 
					
						
							|  |  |  |     final status = | 
					
						
							|  |  |  |         jsonDecode(await bind.mainGetConnectStatus()) as Map<String, dynamic>; | 
					
						
							|  |  |  |     final statusNum = status['status_num'] as int; | 
					
						
							|  |  |  |     final preStatus = stateGlobal.svcStatus.value; | 
					
						
							|  |  |  |     if (statusNum == 0) { | 
					
						
							|  |  |  |       stateGlobal.svcStatus.value = SvcStatus.connecting; | 
					
						
							|  |  |  |     } else if (statusNum == -1) { | 
					
						
							|  |  |  |       stateGlobal.svcStatus.value = SvcStatus.notReady; | 
					
						
							|  |  |  |     } else if (statusNum == 1) { | 
					
						
							|  |  |  |       stateGlobal.svcStatus.value = SvcStatus.ready; | 
					
						
							|  |  |  |       if (preStatus != SvcStatus.ready) { | 
					
						
							|  |  |  |         gFFI.userModel.refreshCurrentUser(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       stateGlobal.svcStatus.value = SvcStatus.notReady; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _svcIsUsingPublicServer.value = await bind.mainIsUsingPublicServer(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  | /// Connection page for connecting to a remote peer.
 | 
					
						
							| 
									
										
										
										
											2022-08-09 20:36:52 +08:00
										 |  |  | class ConnectionPage extends StatefulWidget { | 
					
						
							| 
									
										
										
										
											2022-09-06 02:08:59 -07:00
										 |  |  |   const ConnectionPage({Key? key}) : super(key: key); | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							| 
									
										
										
										
											2022-09-06 02:08:59 -07:00
										 |  |  |   State<ConnectionPage> createState() => _ConnectionPageState(); | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// State for the connection page.
 | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  | class _ConnectionPageState extends State<ConnectionPage> | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  |     with SingleTickerProviderStateMixin, WindowListener { | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   /// Controller for the id input bar.
 | 
					
						
							| 
									
										
										
										
											2022-09-02 17:19:44 +08:00
										 |  |  |   final _idController = IDTextEditingController(); | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 12:32:52 +08:00
										 |  |  |   final RxBool _idInputFocused = false.obs; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-09 02:30:31 -05:00
										 |  |  |   bool isWindowMinimized = false; | 
					
						
							| 
									
										
										
										
											2023-10-13 23:10:31 +05:30
										 |  |  |   List<Peer> peers = []; | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-17 18:22:27 +05:30
										 |  |  |   bool isPeersLoading = false; | 
					
						
							| 
									
										
										
										
											2023-10-23 05:03:44 +05:30
										 |  |  |   bool isPeersLoaded = false; | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   void initState() { | 
					
						
							|  |  |  |     super.initState(); | 
					
						
							| 
									
										
										
										
											2022-08-08 17:53:51 +08:00
										 |  |  |     if (_idController.text.isEmpty) { | 
					
						
							|  |  |  |       () async { | 
					
						
							|  |  |  |         final lastRemoteId = await bind.mainGetLastRemoteId(); | 
					
						
							| 
									
										
										
										
											2022-09-02 17:19:44 +08:00
										 |  |  |         if (lastRemoteId != _idController.id) { | 
					
						
							| 
									
										
										
										
											2022-08-08 17:53:51 +08:00
										 |  |  |           setState(() { | 
					
						
							| 
									
										
										
										
											2022-09-02 17:19:44 +08:00
										 |  |  |             _idController.id = lastRemoteId; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:53:51 +08:00
										 |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-08-08 17:22:25 +08:00
										 |  |  |     Get.put<IDTextEditingController>(_idController); | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  |     windowManager.addListener(this); | 
					
						
							| 
									
										
										
										
											2022-10-20 09:21:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void dispose() { | 
					
						
							|  |  |  |     _idController.dispose(); | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  |     windowManager.removeListener(this); | 
					
						
							| 
									
										
										
										
											2023-08-09 13:54:09 +08:00
										 |  |  |     if (Get.isRegistered<IDTextEditingController>()) { | 
					
						
							|  |  |  |       Get.delete<IDTextEditingController>(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |     if (Get.isRegistered<TextEditingController>()) { | 
					
						
							| 
									
										
										
										
											2023-10-25 02:36:23 +05:30
										 |  |  |       Get.delete<TextEditingController>(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-10-20 09:21:02 +08:00
										 |  |  |     super.dispose(); | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   void onWindowEvent(String eventName) { | 
					
						
							|  |  |  |     super.onWindowEvent(eventName); | 
					
						
							|  |  |  |     if (eventName == 'minimize') { | 
					
						
							| 
									
										
										
										
											2023-01-09 02:30:31 -05:00
										 |  |  |       isWindowMinimized = true; | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  |     } else if (eventName == 'maximize' || eventName == 'restore') { | 
					
						
							| 
									
										
										
										
											2024-03-24 11:23:06 +08:00
										 |  |  |       if (isWindowMinimized && isWindows) { | 
					
						
							| 
									
										
										
										
											2023-01-09 02:30:31 -05:00
										 |  |  |         // windows can't update when minimized.
 | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  |         Get.forceAppUpdate(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-01-09 02:30:31 -05:00
										 |  |  |       isWindowMinimized = false; | 
					
						
							| 
									
										
										
										
											2022-10-22 21:55:36 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-30 21:42:58 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   void onWindowEnterFullScreen() { | 
					
						
							|  |  |  |     // Remove edge border by setting the value to zero.
 | 
					
						
							|  |  |  |     stateGlobal.resizeEdgeSize.value = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void onWindowLeaveFullScreen() { | 
					
						
							|  |  |  |     // Restore edge border to default edge size.
 | 
					
						
							| 
									
										
										
										
											2023-09-03 22:18:48 +08:00
										 |  |  |     stateGlobal.resizeEdgeSize.value = | 
					
						
							| 
									
										
										
										
											2024-05-09 22:51:53 +08:00
										 |  |  |         stateGlobal.isMaximized.isTrue ? kMaximizeEdgeSize : windowEdgeSize; | 
					
						
							| 
									
										
										
										
											2023-01-30 21:42:58 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-19 10:57:17 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   void onWindowClose() { | 
					
						
							|  |  |  |     super.onWindowClose(); | 
					
						
							|  |  |  |     bind.mainOnMainWindowClose(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2024-03-15 00:26:53 +08:00
										 |  |  |     final isOutgoingOnly = bind.isOutgoingOnly(); | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  |     return Column( | 
					
						
							|  |  |  |       children: [ | 
					
						
							|  |  |  |         Expanded( | 
					
						
							| 
									
										
										
										
											2023-09-25 21:04:40 +08:00
										 |  |  |             child: Column( | 
					
						
							|  |  |  |           children: [ | 
					
						
							|  |  |  |             Row( | 
					
						
							|  |  |  |               children: [ | 
					
						
							|  |  |  |                 Flexible(child: _buildRemoteIDTextField(context)), | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  |               ], | 
					
						
							| 
									
										
										
										
											2023-09-25 21:04:40 +08:00
										 |  |  |             ).marginOnly(top: 22), | 
					
						
							|  |  |  |             SizedBox(height: 12), | 
					
						
							|  |  |  |             Divider().paddingOnly(right: 12), | 
					
						
							|  |  |  |             Expanded(child: PeerTabPage()), | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         ).paddingOnly(left: 12.0)), | 
					
						
							| 
									
										
										
										
											2024-03-15 00:26:53 +08:00
										 |  |  |         if (!isOutgoingOnly) const Divider(height: 1), | 
					
						
							|  |  |  |         if (!isOutgoingOnly) OnlineStatusWidget() | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  |       ], | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Callback for the connect button.
 | 
					
						
							|  |  |  |   /// Connects to the selected peer.
 | 
					
						
							| 
									
										
										
										
											2022-05-30 13:25:06 +08:00
										 |  |  |   void onConnect({bool isFileTransfer = false}) { | 
					
						
							| 
									
										
										
										
											2023-02-13 16:40:24 +08:00
										 |  |  |     var id = _idController.id; | 
					
						
							| 
									
										
										
										
											2023-02-26 11:23:43 +08:00
										 |  |  |     connect(context, id, isFileTransfer: isFileTransfer); | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-17 18:22:27 +05:30
										 |  |  |   Future<void> _fetchPeers() async { | 
					
						
							|  |  |  |     setState(() { | 
					
						
							|  |  |  |       isPeersLoading = true; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-10-17 18:23:44 +05:30
										 |  |  |     await Future.delayed(Duration(milliseconds: 100)); | 
					
						
							| 
									
										
										
										
											2023-10-24 05:30:43 +05:30
										 |  |  |     peers = await getAllPeers(); | 
					
						
							| 
									
										
										
										
											2023-10-17 18:23:44 +05:30
										 |  |  |     setState(() { | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |       isPeersLoading = false; | 
					
						
							|  |  |  |       isPeersLoaded = true; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-10-17 18:22:27 +05:30
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 17:54:47 +08:00
										 |  |  |   /// UI for the remote ID TextField.
 | 
					
						
							| 
									
										
										
										
											2023-10-15 04:53:57 +05:30
										 |  |  |   /// Search for a peer.
 | 
					
						
							| 
									
										
										
										
											2022-09-21 17:54:47 +08:00
										 |  |  |   Widget _buildRemoteIDTextField(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  |     var w = Container( | 
					
						
							| 
									
										
										
										
											2022-08-22 17:58:48 +08:00
										 |  |  |       width: 320 + 20 * 2, | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |       padding: const EdgeInsets.fromLTRB(20, 24, 20, 22), | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  |       decoration: BoxDecoration( | 
					
						
							| 
									
										
										
										
											2023-03-04 13:23:35 +08:00
										 |  |  |           borderRadius: const BorderRadius.all(Radius.circular(13)), | 
					
						
							|  |  |  |           border: Border.all(color: Theme.of(context).colorScheme.background)), | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  |       child: Ink( | 
					
						
							|  |  |  |         child: Column( | 
					
						
							|  |  |  |           children: [ | 
					
						
							|  |  |  |             Row( | 
					
						
							| 
									
										
										
										
											2022-08-23 19:55:58 +08:00
										 |  |  |               children: [ | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  |                 Expanded( | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                     child: Row( | 
					
						
							|  |  |  |                   children: [ | 
					
						
							|  |  |  |                     AutoSizeText( | 
					
						
							|  |  |  |                       translate('Control Remote Desktop'), | 
					
						
							|  |  |  |                       maxLines: 1, | 
					
						
							|  |  |  |                       style: Theme.of(context) | 
					
						
							|  |  |  |                           .textTheme | 
					
						
							|  |  |  |                           .titleLarge | 
					
						
							|  |  |  |                           ?.merge(TextStyle(height: 1)), | 
					
						
							|  |  |  |                     ).marginOnly(right: 4), | 
					
						
							|  |  |  |                     Tooltip( | 
					
						
							| 
									
										
										
										
											2024-06-27 16:18:41 +08:00
										 |  |  |                       waitDuration: Duration(milliseconds: 300), | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                       message: translate("id_input_tip"), | 
					
						
							|  |  |  |                       child: Icon( | 
					
						
							|  |  |  |                         Icons.help_outline_outlined, | 
					
						
							|  |  |  |                         size: 16, | 
					
						
							|  |  |  |                         color: Theme.of(context) | 
					
						
							|  |  |  |                             .textTheme | 
					
						
							|  |  |  |                             .titleLarge | 
					
						
							|  |  |  |                             ?.color | 
					
						
							|  |  |  |                             ?.withOpacity(0.5), | 
					
						
							|  |  |  |                       ), | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                   ], | 
					
						
							|  |  |  |                 )), | 
					
						
							| 
									
										
										
										
											2022-08-23 19:55:58 +08:00
										 |  |  |               ], | 
					
						
							|  |  |  |             ).marginOnly(bottom: 15), | 
					
						
							|  |  |  |             Row( | 
					
						
							|  |  |  |               children: [ | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  |                 Expanded( | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                     child: Autocomplete<Peer>( | 
					
						
							|  |  |  |                   optionsBuilder: (TextEditingValue textEditingValue) { | 
					
						
							|  |  |  |                     if (textEditingValue.text == '') { | 
					
						
							|  |  |  |                       return const Iterable<Peer>.empty(); | 
					
						
							|  |  |  |                     } else if (peers.isEmpty && !isPeersLoaded) { | 
					
						
							|  |  |  |                       Peer emptyPeer = Peer( | 
					
						
							|  |  |  |                         id: '', | 
					
						
							|  |  |  |                         username: '', | 
					
						
							|  |  |  |                         hostname: '', | 
					
						
							|  |  |  |                         alias: '', | 
					
						
							|  |  |  |                         platform: '', | 
					
						
							|  |  |  |                         tags: [], | 
					
						
							|  |  |  |                         hash: '', | 
					
						
							| 
									
										
										
										
											2024-03-20 15:05:54 +08:00
										 |  |  |                         password: '', | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                         forceAlwaysRelay: false, | 
					
						
							|  |  |  |                         rdpPort: '', | 
					
						
							|  |  |  |                         rdpUsername: '', | 
					
						
							|  |  |  |                         loginName: '', | 
					
						
							|  |  |  |                       ); | 
					
						
							|  |  |  |                       return [emptyPeer]; | 
					
						
							|  |  |  |                     } else { | 
					
						
							|  |  |  |                       String textWithoutSpaces = | 
					
						
							|  |  |  |                           textEditingValue.text.replaceAll(" ", ""); | 
					
						
							|  |  |  |                       if (int.tryParse(textWithoutSpaces) != null) { | 
					
						
							|  |  |  |                         textEditingValue = TextEditingValue( | 
					
						
							|  |  |  |                           text: textWithoutSpaces, | 
					
						
							|  |  |  |                           selection: textEditingValue.selection, | 
					
						
							| 
									
										
										
										
											2023-10-17 18:22:27 +05:30
										 |  |  |                         ); | 
					
						
							|  |  |  |                       } | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                       String textToFind = textEditingValue.text.toLowerCase(); | 
					
						
							| 
									
										
										
										
											2023-10-13 23:28:54 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                       return peers | 
					
						
							|  |  |  |                           .where((peer) => | 
					
						
							|  |  |  |                               peer.id.toLowerCase().contains(textToFind) || | 
					
						
							|  |  |  |                               peer.username | 
					
						
							|  |  |  |                                   .toLowerCase() | 
					
						
							|  |  |  |                                   .contains(textToFind) || | 
					
						
							|  |  |  |                               peer.hostname | 
					
						
							|  |  |  |                                   .toLowerCase() | 
					
						
							|  |  |  |                                   .contains(textToFind) || | 
					
						
							|  |  |  |                               peer.alias.toLowerCase().contains(textToFind)) | 
					
						
							|  |  |  |                           .toList(); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                   }, | 
					
						
							|  |  |  |                   fieldViewBuilder: ( | 
					
						
							|  |  |  |                     BuildContext context, | 
					
						
							|  |  |  |                     TextEditingController fieldTextEditingController, | 
					
						
							|  |  |  |                     FocusNode fieldFocusNode, | 
					
						
							|  |  |  |                     VoidCallback onFieldSubmitted, | 
					
						
							|  |  |  |                   ) { | 
					
						
							|  |  |  |                     fieldTextEditingController.text = _idController.text; | 
					
						
							|  |  |  |                     Get.put<TextEditingController>(fieldTextEditingController); | 
					
						
							|  |  |  |                     fieldFocusNode.addListener(() async { | 
					
						
							|  |  |  |                       _idInputFocused.value = fieldFocusNode.hasFocus; | 
					
						
							|  |  |  |                       if (fieldFocusNode.hasFocus && !isPeersLoading) { | 
					
						
							|  |  |  |                         _fetchPeers(); | 
					
						
							| 
									
										
										
										
											2023-10-13 23:10:31 +05:30
										 |  |  |                       } | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                     }); | 
					
						
							|  |  |  |                     final textLength = | 
					
						
							|  |  |  |                         fieldTextEditingController.value.text.length; | 
					
						
							|  |  |  |                     // select all to facilitate removing text, just following the behavior of address input of chrome
 | 
					
						
							|  |  |  |                     fieldTextEditingController.selection = | 
					
						
							|  |  |  |                         TextSelection(baseOffset: 0, extentOffset: textLength); | 
					
						
							|  |  |  |                     return Obx(() => TextField( | 
					
						
							|  |  |  |                           autocorrect: false, | 
					
						
							|  |  |  |                           enableSuggestions: false, | 
					
						
							|  |  |  |                           keyboardType: TextInputType.visiblePassword, | 
					
						
							|  |  |  |                           focusNode: fieldFocusNode, | 
					
						
							|  |  |  |                           style: const TextStyle( | 
					
						
							|  |  |  |                             fontFamily: 'WorkSans', | 
					
						
							|  |  |  |                             fontSize: 22, | 
					
						
							|  |  |  |                             height: 1.4, | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                           maxLines: 1, | 
					
						
							|  |  |  |                           cursorColor: | 
					
						
							|  |  |  |                               Theme.of(context).textTheme.titleLarge?.color, | 
					
						
							|  |  |  |                           decoration: InputDecoration( | 
					
						
							|  |  |  |                               filled: false, | 
					
						
							|  |  |  |                               counterText: '', | 
					
						
							|  |  |  |                               hintText: _idInputFocused.value | 
					
						
							|  |  |  |                                   ? null | 
					
						
							|  |  |  |                                   : translate('Enter Remote ID'), | 
					
						
							|  |  |  |                               contentPadding: const EdgeInsets.symmetric( | 
					
						
							|  |  |  |                                   horizontal: 15, vertical: 13)), | 
					
						
							|  |  |  |                           controller: fieldTextEditingController, | 
					
						
							|  |  |  |                           inputFormatters: [IDTextInputFormatter()], | 
					
						
							|  |  |  |                           onChanged: (v) { | 
					
						
							|  |  |  |                             _idController.id = v; | 
					
						
							|  |  |  |                           }, | 
					
						
							| 
									
										
										
										
											2024-03-03 17:31:21 +08:00
										 |  |  |                           onSubmitted: (_) { | 
					
						
							|  |  |  |                             onConnect(); | 
					
						
							|  |  |  |                           }, | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                         )); | 
					
						
							|  |  |  |                   }, | 
					
						
							|  |  |  |                   onSelected: (option) { | 
					
						
							|  |  |  |                     setState(() { | 
					
						
							|  |  |  |                       _idController.id = option.id; | 
					
						
							|  |  |  |                       FocusScope.of(context).unfocus(); | 
					
						
							|  |  |  |                     }); | 
					
						
							|  |  |  |                   }, | 
					
						
							|  |  |  |                   optionsViewBuilder: (BuildContext context, | 
					
						
							|  |  |  |                       AutocompleteOnSelected<Peer> onSelected, | 
					
						
							|  |  |  |                       Iterable<Peer> options) { | 
					
						
							|  |  |  |                     double maxHeight = options.length * 50; | 
					
						
							| 
									
										
										
										
											2023-12-17 06:52:18 +05:30
										 |  |  |                     if (options.length == 1) { | 
					
						
							|  |  |  |                       maxHeight = 52; | 
					
						
							|  |  |  |                     } else if (options.length == 3) { | 
					
						
							|  |  |  |                       maxHeight = 146; | 
					
						
							|  |  |  |                     } else if (options.length == 4) { | 
					
						
							|  |  |  |                       maxHeight = 193; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     maxHeight = maxHeight.clamp(0, 200); | 
					
						
							| 
									
										
										
										
											2023-10-23 05:28:15 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                     return Align( | 
					
						
							|  |  |  |                       alignment: Alignment.topLeft, | 
					
						
							| 
									
										
										
										
											2023-12-17 06:52:18 +05:30
										 |  |  |                       child: Container( | 
					
						
							|  |  |  |                           decoration: BoxDecoration( | 
					
						
							|  |  |  |                             boxShadow: [ | 
					
						
							|  |  |  |                               BoxShadow( | 
					
						
							|  |  |  |                                 color: Colors.black.withOpacity(0.3), | 
					
						
							|  |  |  |                                 blurRadius: 5, | 
					
						
							|  |  |  |                                 spreadRadius: 1, | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                               ), | 
					
						
							| 
									
										
										
										
											2023-12-17 06:52:18 +05:30
										 |  |  |                             ], | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                           child: ClipRRect( | 
					
						
							|  |  |  |                               borderRadius: BorderRadius.circular(5), | 
					
						
							|  |  |  |                               child: Material( | 
					
						
							|  |  |  |                                 elevation: 4, | 
					
						
							|  |  |  |                                 child: ConstrainedBox( | 
					
						
							|  |  |  |                                   constraints: BoxConstraints( | 
					
						
							|  |  |  |                                     maxHeight: maxHeight, | 
					
						
							|  |  |  |                                     maxWidth: 319, | 
					
						
							|  |  |  |                                   ), | 
					
						
							|  |  |  |                                   child: peers.isEmpty && isPeersLoading | 
					
						
							|  |  |  |                                       ? Container( | 
					
						
							|  |  |  |                                           height: 80, | 
					
						
							|  |  |  |                                           child: Center( | 
					
						
							|  |  |  |                                             child: CircularProgressIndicator( | 
					
						
							|  |  |  |                                               strokeWidth: 2, | 
					
						
							|  |  |  |                                             ), | 
					
						
							|  |  |  |                                           )) | 
					
						
							|  |  |  |                                       : Padding( | 
					
						
							|  |  |  |                                           padding: | 
					
						
							|  |  |  |                                               const EdgeInsets.only(top: 5), | 
					
						
							|  |  |  |                                           child: ListView( | 
					
						
							|  |  |  |                                             children: options | 
					
						
							|  |  |  |                                                 .map((peer) => | 
					
						
							|  |  |  |                                                     AutocompletePeerTile( | 
					
						
							|  |  |  |                                                         onSelect: () => | 
					
						
							|  |  |  |                                                             onSelected(peer), | 
					
						
							|  |  |  |                                                         peer: peer)) | 
					
						
							|  |  |  |                                                 .toList(), | 
					
						
							|  |  |  |                                           ), | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                                         ), | 
					
						
							| 
									
										
										
										
											2023-12-17 06:52:18 +05:30
										 |  |  |                                 ), | 
					
						
							|  |  |  |                               ))), | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                     ); | 
					
						
							|  |  |  |                   }, | 
					
						
							|  |  |  |                 )), | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  |               ], | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             Padding( | 
					
						
							| 
									
										
										
										
											2022-08-22 17:58:48 +08:00
										 |  |  |               padding: const EdgeInsets.only(top: 13.0), | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  |               child: Row( | 
					
						
							|  |  |  |                 mainAxisAlignment: MainAxisAlignment.end, | 
					
						
							|  |  |  |                 children: [ | 
					
						
							| 
									
										
										
										
											2022-09-23 17:28:22 +08:00
										 |  |  |                   Button( | 
					
						
							|  |  |  |                     isOutline: true, | 
					
						
							| 
									
										
										
										
											2023-03-30 11:47:32 +08:00
										 |  |  |                     onTap: () => onConnect(isFileTransfer: true), | 
					
						
							| 
									
										
										
										
											2023-11-06 20:12:01 +08:00
										 |  |  |                     text: "Transfer file", | 
					
						
							| 
									
										
										
										
											2022-09-23 17:28:22 +08:00
										 |  |  |                   ), | 
					
						
							| 
									
										
										
										
											2022-09-03 18:19:50 +08:00
										 |  |  |                   const SizedBox( | 
					
						
							| 
									
										
										
										
											2022-08-22 17:58:48 +08:00
										 |  |  |                     width: 17, | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  |                   ), | 
					
						
							| 
									
										
										
										
											2023-03-30 11:17:24 +08:00
										 |  |  |                   Button(onTap: onConnect, text: "Connect"), | 
					
						
							| 
									
										
										
										
											2022-07-14 12:32:01 +08:00
										 |  |  |                 ], | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |           ], | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |         ), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2022-11-30 11:13:02 +08:00
										 |  |  |     return Container( | 
					
						
							|  |  |  |         constraints: const BoxConstraints(maxWidth: 600), child: w); | 
					
						
							| 
									
										
										
										
											2022-05-29 04:39:12 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-08-02 13:10:09 +08:00
										 |  |  | } |