| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | import 'dart:convert'; | 
					
						
							| 
									
										
										
										
											2022-09-19 10:14:14 +08:00
										 |  |  | import 'dart:io'; | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 16:37:11 +08:00
										 |  |  | import 'package:desktop_multi_window/desktop_multi_window.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2022-06-28 22:04:10 +08:00
										 |  |  | import 'package:flutter_hbb/common.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-29 18:48:12 +08:00
										 |  |  | import 'package:flutter_hbb/common/shared_state.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-03 15:31:19 +08:00
										 |  |  | import 'package:flutter_hbb/consts.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | import 'package:flutter_hbb/desktop/pages/remote_page.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-06 17:08:48 +08:00
										 |  |  | import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | import 'package:flutter_hbb/utils/multi_window_manager.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-27 19:42:05 +08:00
										 |  |  | import 'package:flutter_svg/flutter_svg.dart'; | 
					
						
							| 
									
										
										
										
											2022-06-28 22:04:10 +08:00
										 |  |  | import 'package:get/get.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-13 21:19:05 +09:00
										 |  |  | import '../../models/platform_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-08 19:26:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | class ConnectionTabPage extends StatefulWidget { | 
					
						
							|  |  |  |   final Map<String, dynamic> params; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const ConnectionTabPage({Key? key, required this.params}) : super(key: key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   State<ConnectionTabPage> createState() => _ConnectionTabPageState(params); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 10:54:09 +08:00
										 |  |  | class _ConnectionTabPageState extends State<ConnectionTabPage> { | 
					
						
							| 
									
										
										
										
											2022-10-27 15:52:40 +08:00
										 |  |  |   final tabController = Get.put(DesktopTabController( | 
					
						
							|  |  |  |       tabType: DesktopTabType.remoteScreen, | 
					
						
							|  |  |  |       onSelected: (_, id) => bind.setCurSessionId(id: id))); | 
					
						
							| 
									
										
										
										
											2022-08-29 18:48:12 +08:00
										 |  |  |   static const IconData selectedIcon = Icons.desktop_windows_sharp; | 
					
						
							|  |  |  |   static const IconData unselectedIcon = Icons.desktop_windows_outlined; | 
					
						
							| 
									
										
										
										
											2022-08-05 10:27:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   var connectionMap = RxList<Widget>.empty(growable: true); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   _ConnectionTabPageState(Map<String, dynamic> params) { | 
					
						
							| 
									
										
										
										
											2022-10-08 17:27:30 +08:00
										 |  |  |     RemoteCountState.init(); | 
					
						
							| 
									
										
										
										
											2022-08-26 23:28:08 +08:00
										 |  |  |     final RxBool fullscreen = Get.find(tag: 'fullscreen'); | 
					
						
							| 
									
										
										
										
											2022-08-29 22:46:19 +08:00
										 |  |  |     final peerId = params['id']; | 
					
						
							|  |  |  |     if (peerId != null) { | 
					
						
							|  |  |  |       ConnectionTypeState.init(peerId); | 
					
						
							| 
									
										
										
										
											2022-08-26 12:14:14 +08:00
										 |  |  |       tabController.add(TabInfo( | 
					
						
							| 
									
										
										
										
											2022-08-29 22:46:19 +08:00
										 |  |  |           key: peerId, | 
					
						
							|  |  |  |           label: peerId, | 
					
						
							| 
									
										
										
										
											2022-08-18 10:54:09 +08:00
										 |  |  |           selectedIcon: selectedIcon, | 
					
						
							| 
									
										
										
										
											2022-08-24 20:56:42 +08:00
										 |  |  |           unselectedIcon: unselectedIcon, | 
					
						
							| 
									
										
										
										
											2022-10-13 21:19:05 +09:00
										 |  |  |           onTabCloseButton: () => tabController.closeBy(peerId), | 
					
						
							| 
									
										
										
										
											2022-10-04 21:19:31 +08:00
										 |  |  |           page: Obx(() => RemotePage( | 
					
						
							|  |  |  |                 key: ValueKey(peerId), | 
					
						
							|  |  |  |                 id: peerId, | 
					
						
							| 
									
										
										
										
											2022-10-08 17:27:30 +08:00
										 |  |  |                 windowId: windowId(), | 
					
						
							| 
									
										
										
										
											2022-10-04 21:19:31 +08:00
										 |  |  |                 tabBarHeight: | 
					
						
							|  |  |  |                     fullscreen.isTrue ? 0 : kDesktopRemoteTabBarHeight, | 
					
						
							|  |  |  |                 windowBorderWidth: fullscreen.isTrue ? 0 : kWindowBorderWidth, | 
					
						
							|  |  |  |               )))); | 
					
						
							| 
									
										
										
										
											2022-10-08 17:27:30 +08:00
										 |  |  |       _update_remote_count(); | 
					
						
							| 
									
										
										
										
											2022-05-31 16:27:54 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void initState() { | 
					
						
							|  |  |  |     super.initState(); | 
					
						
							| 
									
										
										
										
											2022-08-24 20:56:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-27 10:56:14 +08:00
										 |  |  |     tabController.onRemoved = (_, id) => onRemoveId(id); | 
					
						
							| 
									
										
										
										
											2022-08-24 20:56:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  |     rustDeskWinManager.setMethodHandler((call, fromWindowId) async { | 
					
						
							|  |  |  |       print( | 
					
						
							| 
									
										
										
										
											2022-10-27 10:56:14 +08:00
										 |  |  |           "call ${call.method} with args ${call.arguments} from window $fromWindowId"); | 
					
						
							| 
									
										
										
										
											2022-08-26 23:28:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       final RxBool fullscreen = Get.find(tag: 'fullscreen'); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  |       // for simplify, just replace connectionId
 | 
					
						
							|  |  |  |       if (call.method == "new_remote_desktop") { | 
					
						
							| 
									
										
										
										
											2022-08-05 10:27:06 +08:00
										 |  |  |         final args = jsonDecode(call.arguments); | 
					
						
							|  |  |  |         final id = args['id']; | 
					
						
							| 
									
										
										
										
											2022-09-01 21:18:53 +08:00
										 |  |  |         ConnectionTypeState.init(id); | 
					
						
							| 
									
										
										
										
											2022-08-09 19:32:19 +08:00
										 |  |  |         window_on_top(windowId()); | 
					
						
							| 
									
										
										
										
											2022-08-31 18:41:55 +08:00
										 |  |  |         ConnectionTypeState.init(id); | 
					
						
							| 
									
										
										
										
											2022-08-24 20:56:42 +08:00
										 |  |  |         tabController.add(TabInfo( | 
					
						
							|  |  |  |             key: id, | 
					
						
							|  |  |  |             label: id, | 
					
						
							|  |  |  |             selectedIcon: selectedIcon, | 
					
						
							|  |  |  |             unselectedIcon: unselectedIcon, | 
					
						
							| 
									
										
										
										
											2022-10-13 21:19:05 +09:00
										 |  |  |             onTabCloseButton: () => tabController.closeBy(id), | 
					
						
							| 
									
										
										
										
											2022-10-04 21:19:31 +08:00
										 |  |  |             page: Obx(() => RemotePage( | 
					
						
							|  |  |  |                   key: ValueKey(id), | 
					
						
							|  |  |  |                   id: id, | 
					
						
							| 
									
										
										
										
											2022-10-08 17:27:30 +08:00
										 |  |  |                   windowId: windowId(), | 
					
						
							| 
									
										
										
										
											2022-10-04 21:19:31 +08:00
										 |  |  |                   tabBarHeight: | 
					
						
							|  |  |  |                       fullscreen.isTrue ? 0 : kDesktopRemoteTabBarHeight, | 
					
						
							|  |  |  |                   windowBorderWidth: fullscreen.isTrue ? 0 : kWindowBorderWidth, | 
					
						
							|  |  |  |                 )))); | 
					
						
							| 
									
										
										
										
											2022-06-28 22:04:10 +08:00
										 |  |  |       } else if (call.method == "onDestroy") { | 
					
						
							| 
									
										
										
										
											2022-08-30 20:48:03 +08:00
										 |  |  |         tabController.clear(); | 
					
						
							| 
									
										
										
										
											2022-10-26 14:39:13 +08:00
										 |  |  |       } else if (call.method == kWindowActionRebuild) { | 
					
						
							|  |  |  |         reloadCurrentWindow(); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-10-08 17:27:30 +08:00
										 |  |  |       _update_remote_count(); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-10-22 22:43:26 +08:00
										 |  |  |     Future.delayed(Duration.zero, () { | 
					
						
							|  |  |  |       restoreWindowPosition(WindowType.RemoteDesktop, windowId: windowId()); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2022-08-26 23:28:08 +08:00
										 |  |  |     final RxBool fullscreen = Get.find(tag: 'fullscreen'); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:14:14 +08:00
										 |  |  |     final tabWidget = Container( | 
					
						
							|  |  |  |       decoration: BoxDecoration( | 
					
						
							| 
									
										
										
										
											2022-10-04 21:19:31 +08:00
										 |  |  |           border: Border.all( | 
					
						
							|  |  |  |               color: MyTheme.color(context).border!, | 
					
						
							|  |  |  |               width: kWindowBorderWidth)), | 
					
						
							| 
									
										
										
										
											2022-09-19 10:14:14 +08:00
										 |  |  |       child: Scaffold( | 
					
						
							| 
									
										
										
										
											2022-09-23 16:31:50 +08:00
										 |  |  |           backgroundColor: Theme.of(context).backgroundColor, | 
					
						
							| 
									
										
										
										
											2022-09-27 20:17:18 +08:00
										 |  |  |           body: Obx(() => DesktopTab( | 
					
						
							|  |  |  |                 controller: tabController, | 
					
						
							|  |  |  |                 showTabBar: fullscreen.isFalse, | 
					
						
							|  |  |  |                 onWindowCloseButton: handleWindowCloseButton, | 
					
						
							|  |  |  |                 tail: const AddButton().paddingOnly(left: 10), | 
					
						
							|  |  |  |                 pageViewBuilder: (pageView) { | 
					
						
							|  |  |  |                   WindowController.fromWindowId(windowId()) | 
					
						
							|  |  |  |                       .setFullscreen(fullscreen.isTrue); | 
					
						
							|  |  |  |                   return pageView; | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 tabBuilder: (key, icon, label, themeConf) => Obx(() { | 
					
						
							|  |  |  |                   final connectionType = ConnectionTypeState.find(key); | 
					
						
							|  |  |  |                   if (!connectionType.isValid()) { | 
					
						
							|  |  |  |                     return Row( | 
					
						
							|  |  |  |                       mainAxisAlignment: MainAxisAlignment.center, | 
					
						
							|  |  |  |                       children: [ | 
					
						
							|  |  |  |                         icon, | 
					
						
							|  |  |  |                         label, | 
					
						
							|  |  |  |                       ], | 
					
						
							|  |  |  |                     ); | 
					
						
							|  |  |  |                   } else { | 
					
						
							|  |  |  |                     final msgDirect = translate( | 
					
						
							|  |  |  |                         connectionType.direct.value == ConnectionType.strDirect | 
					
						
							|  |  |  |                             ? 'Direct Connection' | 
					
						
							|  |  |  |                             : 'Relay Connection'); | 
					
						
							|  |  |  |                     final msgSecure = translate( | 
					
						
							|  |  |  |                         connectionType.secure.value == ConnectionType.strSecure | 
					
						
							|  |  |  |                             ? 'Secure Connection' | 
					
						
							|  |  |  |                             : 'Insecure Connection'); | 
					
						
							|  |  |  |                     return Row( | 
					
						
							|  |  |  |                       mainAxisAlignment: MainAxisAlignment.center, | 
					
						
							|  |  |  |                       children: [ | 
					
						
							|  |  |  |                         icon, | 
					
						
							|  |  |  |                         Tooltip( | 
					
						
							|  |  |  |                           message: '$msgDirect\n$msgSecure', | 
					
						
							|  |  |  |                           child: SvgPicture.asset( | 
					
						
							|  |  |  |                             'assets/${connectionType.secure.value}${connectionType.direct.value}.svg', | 
					
						
							|  |  |  |                             width: themeConf.iconSize, | 
					
						
							|  |  |  |                             height: themeConf.iconSize, | 
					
						
							|  |  |  |                           ).paddingOnly(right: 5), | 
					
						
							|  |  |  |                         ), | 
					
						
							|  |  |  |                         label, | 
					
						
							|  |  |  |                       ], | 
					
						
							|  |  |  |                     ); | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 }), | 
					
						
							|  |  |  |               ))), | 
					
						
							| 
									
										
										
										
											2022-09-19 10:14:14 +08:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2022-09-19 11:09:29 +08:00
										 |  |  |     return Platform.isMacOS | 
					
						
							| 
									
										
										
										
											2022-09-19 10:14:14 +08:00
										 |  |  |         ? tabWidget | 
					
						
							| 
									
										
										
										
											2022-09-19 11:09:29 +08:00
										 |  |  |         : Obx(() => SubWindowDragToResizeArea( | 
					
						
							| 
									
										
										
										
											2022-09-19 17:10:12 +08:00
										 |  |  |             resizeEdgeSize: | 
					
						
							|  |  |  |                 fullscreen.value ? kFullScreenEdgeSize : kWindowEdgeSize, | 
					
						
							| 
									
										
										
										
											2022-09-19 10:14:14 +08:00
										 |  |  |             windowId: windowId(), | 
					
						
							|  |  |  |             child: tabWidget)); | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-05-31 16:27:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void onRemoveId(String id) { | 
					
						
							| 
									
										
										
										
											2022-08-30 16:45:47 +08:00
										 |  |  |     if (tabController.state.value.tabs.isEmpty) { | 
					
						
							|  |  |  |       WindowController.fromWindowId(windowId()).hide(); | 
					
						
							| 
									
										
										
										
											2022-08-09 09:01:06 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-29 22:46:19 +08:00
										 |  |  |     ConnectionTypeState.delete(id); | 
					
						
							| 
									
										
										
										
											2022-10-08 17:27:30 +08:00
										 |  |  |     _update_remote_count(); | 
					
						
							| 
									
										
										
										
											2022-05-31 16:27:54 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-08-09 16:37:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   int windowId() { | 
					
						
							|  |  |  |     return widget.params["windowId"]; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:03:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-09 19:29:19 +08:00
										 |  |  |   Future<bool> handleWindowCloseButton() async { | 
					
						
							| 
									
										
										
										
											2022-10-08 17:27:30 +08:00
										 |  |  |     final connLength = tabController.length; | 
					
						
							| 
									
										
										
										
											2022-10-13 21:19:05 +09:00
										 |  |  |     if (connLength <= 1) { | 
					
						
							|  |  |  |       tabController.clear(); | 
					
						
							| 
									
										
										
										
											2022-09-09 19:29:19 +08:00
										 |  |  |       return true; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2022-10-13 21:19:05 +09:00
										 |  |  |       final opt = "enable-confirm-closing-tabs"; | 
					
						
							|  |  |  |       final bool res; | 
					
						
							|  |  |  |       if (!option2bool(opt, await bind.mainGetOption(key: opt))) { | 
					
						
							|  |  |  |         res = true; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         res = await closeConfirmDialog(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-09-09 19:29:19 +08:00
										 |  |  |       if (res) { | 
					
						
							|  |  |  |         tabController.clear(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-10-08 17:27:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   _update_remote_count() => | 
					
						
							|  |  |  |       RemoteCountState.find().value = tabController.length; | 
					
						
							| 
									
										
										
										
											2022-05-29 17:19:50 +08:00
										 |  |  | } |