diff --git a/flutter/android/app/src/main/AndroidManifest.xml b/flutter/android/app/src/main/AndroidManifest.xml index b3c655917..1b99801bf 100644 --- a/flutter/android/app/src/main/AndroidManifest.xml +++ b/flutter/android/app/src/main/AndroidManifest.xml @@ -61,6 +61,14 @@ + + + + + + + + - \ No newline at end of file + diff --git a/flutter/ios/Runner/Info.plist b/flutter/ios/Runner/Info.plist index 892561ae7..496fb17c2 100644 --- a/flutter/ios/Runner/Info.plist +++ b/flutter/ios/Runner/Info.plist @@ -24,6 +24,21 @@ ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLIconFile + + CFBundleURLName + com.carriez.rustdesk + CFBundleURLSchemes + + rustdesk + + + LSRequiresIPhoneOS UIApplicationSupportsIndirectInputEvents diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 9c8404c56..4d23614ca 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -1955,6 +1955,7 @@ bool handleUriLink({List? cmdArgs, Uri? uri, String? uriString}) { List? urlLinkToCmdArgs(Uri uri) { String? command; String? id; + final options = ["connect", "play", "file-transfer", "port-forward", "rdp"]; if (uri.authority.isEmpty && uri.path.split('').every((char) => char == '/')) { return []; @@ -1962,18 +1963,33 @@ List? urlLinkToCmdArgs(Uri uri) { // For compatibility command = '--connect'; id = uri.path.substring("/new/".length); - } else if (['connect', "play", 'file-transfer', 'port-forward', 'rdp'] - .contains(uri.authority)) { + } else if (options.contains(uri.authority)) { + final optionIndex = options.indexOf(uri.authority); command = '--${uri.authority}'; if (uri.path.length > 1) { id = uri.path.substring(1); } + if (isMobile && id != null) { + if (optionIndex == 0 || optionIndex == 1) { + connect(Get.context!, id); + } else if (optionIndex == 2) { + connect(Get.context!, id, isFileTransfer: true); + } + return null; + } } else if (uri.authority.length > 2 && uri.path.length <= 1) { // rustdesk:// command = '--connect'; id = uri.authority; } + if (isMobile){ + if (id != null){ + connect(Get.context!, id); + return null; + } + } + List args = List.empty(growable: true); if (command != null && id != null) { args.add(command); diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index d7dd5acee..b8a7a8e45 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -156,6 +156,7 @@ void runMobileApp() async { await Future.wait([gFFI.abModel.loadCache(), gFFI.groupModel.loadCache()]); gFFI.userModel.refreshCurrentUser(); runApp(App()); + await initUniLinks(); } void runMultiWindow( diff --git a/flutter/lib/mobile/pages/connection_page.dart b/flutter/lib/mobile/pages/connection_page.dart index a4e3c7f4d..824ceafec 100644 --- a/flutter/lib/mobile/pages/connection_page.dart +++ b/flutter/lib/mobile/pages/connection_page.dart @@ -54,10 +54,12 @@ class _ConnectionPageState extends State { } bool isPeersLoading = false; bool isPeersLoaded = false; + StreamSubscription? _uniLinksSubscription; @override void initState() { super.initState(); + _uniLinksSubscription = listenUniLinks(); if (_idController.text.isEmpty) { () async { final lastRemoteId = await bind.mainGetLastRemoteId(); @@ -312,6 +314,7 @@ class _ConnectionPageState extends State { @override void dispose() { + _uniLinksSubscription?.cancel(); _idController.dispose(); if (Get.isRegistered()) { Get.delete();