From fb30d49e120fe6fc279edb5fecd08781d4168fe3 Mon Sep 17 00:00:00 2001 From: miximixihuabulaji Date: Thu, 26 Dec 2024 15:30:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=80=82=E9=85=8Dapp=20&=20deep=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 21 +++++++ ios/Runner/Info.plist | 15 +++++ lib/app/services/deep_link_service.dart | 59 +++++++++++++++++++ .../widgets/custom_markdown_body_widget.dart | 15 ++++- lib/common/constants.dart | 3 + lib/main.dart | 5 ++ linux/flutter/generated_plugin_registrant.cc | 4 ++ linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 40 +++++++++++++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 13 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 lib/app/services/deep_link_service.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 42e623c..8373c5f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,6 +27,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index bb1f8d6..4df4d17 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -64,10 +64,25 @@ UIRequiresPersistentWiFi + LSApplicationQueriesSchemes sms tel + + + CFBundleURLTypes + + + CFBundleURLSchemes + + iwara + + + + FlutterDeepLinkingEnabled + + diff --git a/lib/app/services/deep_link_service.dart b/lib/app/services/deep_link_service.dart new file mode 100644 index 0000000..494522b --- /dev/null +++ b/lib/app/services/deep_link_service.dart @@ -0,0 +1,59 @@ +import 'package:app_links/app_links.dart'; +import 'package:get/get.dart'; +import 'package:i_iwara/app/services/app_service.dart'; + +class DeepLinkService extends GetxService { + final _appLinks = AppLinks(); + + Future init() async { + // 监听所有链接事件 + _appLinks.uriLinkStream.listen((Uri? uri) { + if (uri != null) { + _handleLink(uri); + } + }); + + // 检查初始链接(从外部打开应用时) + final uri = await _appLinks.getInitialLink(); + if (uri != null) { + _handleLink(uri); + } + } + + void _handleLink(Uri uri) { + // 处理不同类型的链接 + final pathSegments = uri.pathSegments; + + if (pathSegments.isEmpty) return; + + switch (pathSegments[0]) { + case 'video': + if (pathSegments.length > 1) { + final videoId = pathSegments[1]; + NaviService.navigateToVideoDetailPage(videoId); + } + break; + + case 'profile': + if (pathSegments.length > 1) { + final userName = pathSegments[1]; + NaviService.navigateToAuthorProfilePage(userName); + } + break; + + case 'playlist': + if (pathSegments.length > 1) { + final playlistId = pathSegments[1]; + NaviService.navigateToPlayListDetail(playlistId, isMine: false); + } + break; + + case 'image': + if (pathSegments.length > 1) { + final imageId = pathSegments[1]; + NaviService.navigateToGalleryDetailPage(imageId); + } + break; + } + } +} diff --git a/lib/app/ui/widgets/custom_markdown_body_widget.dart b/lib/app/ui/widgets/custom_markdown_body_widget.dart index aa36459..6d50d96 100644 --- a/lib/app/ui/widgets/custom_markdown_body_widget.dart +++ b/lib/app/ui/widgets/custom_markdown_body_widget.dart @@ -220,19 +220,28 @@ class _CustomMarkdownBodyState extends State { } void _onTapLink(String text, String? href, String title) async { + print('senko 点击的链接是:$href'); if (href == null) return; try { + Uri uri = Uri.parse(href); if (href.startsWith( '${CommonConstants.iwaraBaseUrl}${ApiConstants.profilePrefix()}')) { - final userName = href.split('/').last; + final userName = uri.pathSegments.last; NaviService.navigateToAuthorProfilePage(userName); } else if (href.startsWith( '${CommonConstants.iwaraBaseUrl}${ApiConstants.galleryDetail()}')) { - final imageId = href.split('/').last; + final imageId = uri.pathSegments.last; NaviService.navigateToGalleryDetailPage(imageId); + } else if (href.startsWith( + '${CommonConstants.iwaraBaseUrl}/video/')) { + final videoId = uri.pathSegments[1]; + NaviService.navigateToVideoDetailPage(videoId); + } else if (href.startsWith( + '${CommonConstants.iwaraBaseUrl}/playlist/')) { + final playlistId = uri.pathSegments.last; + NaviService.navigateToPlayListDetail(playlistId, isMine: false); } else { - final uri = Uri.parse(href); if (await canLaunchUrl(uri)) { await launchUrl(uri); } else { diff --git a/lib/common/constants.dart b/lib/common/constants.dart index 41f71f3..e25419e 100644 --- a/lib/common/constants.dart +++ b/lib/common/constants.dart @@ -100,6 +100,9 @@ class ApiConstants { // 图库详情 static String galleryDetail() => '/image'; + // 视频详情 + static String videoDetail() => '/video'; + // 用户详情 static String userProfile(String userName) => '/profile/$userName'; diff --git a/lib/main.dart b/lib/main.dart index b86cc37..7aa2e9d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:i_iwara/app/services/app_service.dart'; import 'package:i_iwara/app/services/comment_service.dart'; +import 'package:i_iwara/app/services/deep_link_service.dart'; import 'package:i_iwara/app/services/gallery_service.dart'; import 'package:i_iwara/app/services/light_service.dart'; import 'package:i_iwara/app/services/play_list_service.dart'; @@ -48,6 +49,10 @@ void main() { // 确保Flutter初始化 WidgetsFlutterBinding.ensureInitialized(); + // 初始化深度链接服务 + final deepLinkService = DeepLinkService(); + await deepLinkService.init(); + Get.put(deepLinkService); // 现在有 简中、英文、日文 // 获取系统语言,如果是支持的语言,则使用,如果不是,则使用英文; String systemLanguage = Get.deviceLocale?.languageCode ?? 'en'; diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 4be5191..ec3e67b 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); + g_autoptr(FlPluginRegistrar) gtk_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin"); + gtk_plugin_register_with_registrar(gtk_registrar); g_autoptr(FlPluginRegistrar) irondash_engine_context_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "IrondashEngineContextPlugin"); irondash_engine_context_plugin_register_with_registrar(irondash_engine_context_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index c3c79c0..0c67daf 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST dynamic_color file_selector_linux flutter_secure_storage_linux + gtk irondash_engine_context media_kit_libs_linux media_kit_video diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index a5d0f06..83dc90a 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,7 @@ import FlutterMacOS import Foundation +import app_links import device_info_plus import dynamic_color import file_selector_macos @@ -25,6 +26,7 @@ import wakelock_plus import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 93c33e1..420c8a4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -22,6 +22,38 @@ packages: url: "https://pub.dev" source: hosted version: "6.11.0" + app_links: + dependency: "direct main" + description: + name: app_links + sha256: "433df2e61b10519407475d7f69e470789d23d593f28224c38ba1068597be7950" + url: "https://pub.dev" + source: hosted + version: "6.3.3" + app_links_linux: + dependency: transitive + description: + name: app_links_linux + sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81 + url: "https://pub.dev" + source: hosted + version: "1.0.3" + app_links_platform_interface: + dependency: transitive + description: + name: app_links_platform_interface + sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + app_links_web: + dependency: transitive + description: + name: app_links_web + sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555 + url: "https://pub.dev" + source: hosted + version: "1.0.4" archive: dependency: transitive description: @@ -586,6 +618,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" + gtk: + dependency: transitive + description: + name: gtk + sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c + url: "https://pub.dev" + source: hosted + version: "2.1.0" http: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 92b1912..8799cd4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,6 +48,7 @@ dependencies: slang_flutter: ^4.4.0 dynamic_color: ^1.7.0 oktoast: ^3.4.0 + app_links: ^6.3.3 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 076f5e1..82e8feb 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,7 @@ #include "generated_plugin_registrant.h" +#include #include #include #include @@ -21,6 +22,8 @@ #include void RegisterPlugins(flutter::PluginRegistry* registry) { + AppLinksPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AppLinksPluginCApi")); DynamicColorPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); FileSelectorWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index cf61c22..c1d21de 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + app_links dynamic_color file_selector_windows flutter_secure_storage_windows