From 2bfd13d843c2266b18095f8e0eeb748621e4c5b7 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Wed, 1 Oct 2025 12:41:48 +0800 Subject: [PATCH] :bug: Fixes bugs and optimization :heavy_plus_sign: Add app links --- lib/widgets/account/leveling_progress.dart | 2 +- lib/widgets/app_wrapper.dart | 49 ++++++++++++++----- lib/widgets/chat/chat_input.dart | 4 +- 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 + 10 files changed, 94 insertions(+), 13 deletions(-) diff --git a/lib/widgets/account/leveling_progress.dart b/lib/widgets/account/leveling_progress.dart index 09da713d..cdd5fc48 100644 --- a/lib/widgets/account/leveling_progress.dart +++ b/lib/widgets/account/leveling_progress.dart @@ -120,7 +120,7 @@ class LevelingProgressCard extends StatelessWidget { children: [ Expanded( child: Tooltip( - message: '${progress.toStringAsFixed(1)}%', + message: '${(progress * 100).toStringAsFixed(1)}%', child: LinearProgressIndicator( minHeight: progressHeight, value: progress, diff --git a/lib/widgets/app_wrapper.dart b/lib/widgets/app_wrapper.dart index a2965823..3607085b 100644 --- a/lib/widgets/app_wrapper.dart +++ b/lib/widgets/app_wrapper.dart @@ -1,9 +1,11 @@ import 'dart:async'; +import 'package:app_links/app_links.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:island/pods/activity/activity_rpc.dart'; import 'package:island/pods/websocket.dart'; +import 'package:island/route.dart'; import 'package:island/screens/tray_manager.dart'; import 'package:island/services/notify.dart'; import 'package:island/services/sharing_intent.dart'; @@ -21,24 +23,37 @@ class AppWrapper extends HookConsumerWidget with TrayListener { Widget build(BuildContext context, WidgetRef ref) { useEffect(() { StreamSubscription? ntySubs; - Future(() { + StreamSubscription? appLinksSubs; + Future(() async { + final appLinks = AppLinks(); + if (context.mounted) ntySubs = setupNotificationListener(context, ref); + + final sharingService = SharingIntentService(); + if (context.mounted) sharingService.initialize(context); + if (context.mounted) UpdateService().checkForUpdates(context); + + TrayService.instance.initialize(this); + + ref.read(rpcServerStateProvider.notifier).start(); + + final initialUri = await appLinks.getLatestLink(); + if (initialUri != null && context.mounted) { + WidgetsBinding.instance.addPostFrameCallback((_) { + _handleDeepLink(initialUri, ref); + }); + } + + appLinksSubs = appLinks.uriLinkStream.listen((uri) { + _handleDeepLink(uri, ref); + }); }); - final sharingService = SharingIntentService(); - sharingService.initialize(context); - - UpdateService().checkForUpdates(context); - - TrayService.instance.initialize(this); - - ref.read(rpcServerStateProvider.notifier).start(); - return () { ref.read(rpcServerProvider).stop(); TrayService.instance.dispose(this); - sharingService.dispose(); ntySubs?.cancel(); + appLinksSubs?.cancel(); }; }, const []); @@ -88,4 +103,16 @@ class AppWrapper extends HookConsumerWidget with TrayListener { void onTrayMenuItemClick(MenuItem menuItem) { TrayService.instance.handleAction(menuItem); } + + void _handleDeepLink(Uri uri, WidgetRef ref) { + final router = ref.read(routerProvider); + String path = '/${uri.path}'; + if (uri.queryParameters.isNotEmpty) { + path = + Uri.parse( + path, + ).replace(queryParameters: uri.queryParameters).toString(); + } + router.go(path); + } } diff --git a/lib/widgets/chat/chat_input.dart b/lib/widgets/chat/chat_input.dart index 5bb6ea92..a6f8adb1 100644 --- a/lib/widgets/chat/chat_input.dart +++ b/lib/widgets/chat/chat_input.dart @@ -275,6 +275,7 @@ class ChatInput extends HookConsumerWidget { ), ), Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, @@ -353,6 +354,7 @@ class ChatInput extends HookConsumerWidget { controller: messageController, keyboardType: TextInputType.multiline, decoration: InputDecoration( + hintMaxLines: 1, hintText: (chatRoom.type == 1 && chatRoom.name == null) ? 'chatDirectMessageHint'.tr( @@ -367,7 +369,7 @@ class ChatInput extends HookConsumerWidget { isDense: true, contentPadding: const EdgeInsets.symmetric( horizontal: 12, - vertical: 4, + vertical: 12, ), counterText: messageController.text.length > 1024 diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index d0550359..9b5ba0e9 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) flutter_webrtc_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterWebRTCPlugin"); flutter_web_r_t_c_plugin_register_with_registrar(flutter_webrtc_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 fe4cdeb5..c66d5982 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST flutter_timezone flutter_udid flutter_webrtc + gtk irondash_engine_context livekit_client media_kit_libs_linux diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 96cf76b6..9f7f9ed2 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,7 @@ import FlutterMacOS import Foundation +import app_links import connectivity_plus import device_info_plus import file_picker @@ -45,6 +46,7 @@ import wakelock_plus import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) diff --git a/pubspec.lock b/pubspec.lock index bb0bf1f2..53fc61b6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,38 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" + app_links: + dependency: "direct main" + description: + name: app_links + sha256: "5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8" + url: "https://pub.dev" + source: hosted + version: "6.4.1" + 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: "direct main" description: @@ -1181,6 +1213,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.3.4" + gtk: + dependency: transitive + description: + name: gtk + sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c + url: "https://pub.dev" + source: hosted + version: "2.1.0" highlight: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 585e5051..40ca8f14 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -158,6 +158,7 @@ dependencies: talker_logger: ^5.0.1 talker_dio_logger: ^5.0.1 talker_riverpod_logger: ^5.0.1 + app_links: ^6.4.1 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 1ca28477..1eb1ed01 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 @@ -36,6 +37,8 @@ #include void RegisterPlugins(flutter::PluginRegistry* registry) { + AppLinksPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AppLinksPluginCApi")); ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); DartIpcPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 5908cff3..ed2828b2 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + app_links connectivity_plus dart_ipc file_saver