diff --git a/lib/core/app_routes.dart b/lib/core/app_routes.dart index 05f89cf1d..78f8db49d 100644 --- a/lib/core/app_routes.dart +++ b/lib/core/app_routes.dart @@ -31,6 +31,11 @@ GoRouter createRouter(WidgetRef ref) { navigatorKey: GlobalKey(), initialLocation: '/', redirect: (context, state) { + // Redirect custom schemes to home to prevent assertion failures + if (state.uri.scheme == 'mostro' || + (!state.uri.scheme.startsWith('http') && state.uri.scheme.isNotEmpty)) { + return '/'; + } final firstRunState = ref.read(firstRunProvider); return firstRunState.when( diff --git a/lib/core/deep_link_handler.dart b/lib/core/deep_link_handler.dart index c729475a4..c5ba5afdb 100644 --- a/lib/core/deep_link_handler.dart +++ b/lib/core/deep_link_handler.dart @@ -72,7 +72,7 @@ class DeepLinkHandler { try { // Show loading indicator context = router.routerDelegate.navigatorKey.currentContext; - if (context != null) { + if (context != null && context.mounted) { _showLoadingDialog(context); } @@ -80,8 +80,15 @@ class DeepLinkHandler { final nostrService = _ref.read(nostrServiceProvider); final deepLinkService = _ref.read(deepLinkServiceProvider); + // Ensure we have a valid context for processing + final processingContext = context ?? router.routerDelegate.navigatorKey.currentContext; + if (processingContext == null || !processingContext.mounted) { + _logger.e('No valid context available for deep link processing'); + return; + } + // Process the mostro link - final result = await deepLinkService.processMostroLink(url, nostrService, context!); + final result = await deepLinkService.processMostroLink(url, nostrService, processingContext); // Get fresh context after async operation final currentContext = router.routerDelegate.navigatorKey.currentContext; diff --git a/lib/core/deep_link_interceptor.dart b/lib/core/deep_link_interceptor.dart index 2a9862d4f..edc209dca 100644 --- a/lib/core/deep_link_interceptor.dart +++ b/lib/core/deep_link_interceptor.dart @@ -21,11 +21,11 @@ class DeepLinkInterceptor extends WidgetsBindingObserver { @override Future didPushRouteInformation(RouteInformation routeInformation) async { final uri = routeInformation.uri; - _logger.i('Route information received: $uri'); + _logger.i('DeepLinkInterceptor: Route information received: $uri'); // Check if this is a custom scheme URL if (_isCustomScheme(uri)) { - _logger.i('Custom scheme detected: ${uri.scheme}, intercepting'); + _logger.i('DeepLinkInterceptor: Custom scheme detected: ${uri.scheme}, intercepting and preventing GoRouter processing'); // Emit the custom URL for processing _customUrlController.add(uri.toString()); @@ -35,12 +35,32 @@ class DeepLinkInterceptor extends WidgetsBindingObserver { return true; } + _logger.i('DeepLinkInterceptor: Allowing normal URL to pass through: $uri'); // Let normal URLs pass through to GoRouter return super.didPushRouteInformation(routeInformation); } // Note: didPushRoute is deprecated, but we keep it for compatibility // The main handling is done in didPushRouteInformation above + @override + // ignore: deprecated_member_use + Future didPushRoute(String route) async { + _logger.i('DeepLinkInterceptor: didPushRoute called with: $route'); + + try { + final uri = Uri.parse(route); + if (_isCustomScheme(uri)) { + _logger.i('DeepLinkInterceptor: Custom scheme detected in didPushRoute: ${uri.scheme}, intercepting'); + _customUrlController.add(route); + return true; + } + } catch (e) { + _logger.w('DeepLinkInterceptor: Error parsing route in didPushRoute: $e'); + } + + // ignore: deprecated_member_use + return super.didPushRoute(route); + } /// Check if the URI uses a custom scheme bool _isCustomScheme(Uri uri) {