diff --git a/packages/smooth_app/lib/helpers/launch_url_helper.dart b/packages/smooth_app/lib/helpers/launch_url_helper.dart index 42edfe2d2e3..f4d7dd276a2 100644 --- a/packages/smooth_app/lib/helpers/launch_url_helper.dart +++ b/packages/smooth_app/lib/helpers/launch_url_helper.dart @@ -18,22 +18,26 @@ class LaunchUrlHelper { 'http(s)?://[a-z]*.open(food|beauty|products|petfood)facts.(net|org)', ))) { AnalyticsHelper.trackOutlink(url: url); - GoRouter.of(context).go(url); + GoRouter.of(context).push(url); } else { return launchURL(url); } } /// Launches the url in an external browser. - static Future launchURL(String url) async { + static Future launchURL( + String url, { + LaunchMode? mode, + }) async { AnalyticsHelper.trackOutlink(url: url); try { await launchUrl( Uri.parse(url), - mode: Platform.isAndroid - ? LaunchMode.externalApplication - : LaunchMode.platformDefault, + mode: mode ?? + (Platform.isAndroid + ? LaunchMode.externalApplication + : LaunchMode.platformDefault), ); } catch (e) { throw 'Could not launch $url,Error: $e'; diff --git a/packages/smooth_app/lib/pages/navigator/app_navigator.dart b/packages/smooth_app/lib/pages/navigator/app_navigator.dart index 260d1b06da4..270404ed6cb 100644 --- a/packages/smooth_app/lib/pages/navigator/app_navigator.dart +++ b/packages/smooth_app/lib/pages/navigator/app_navigator.dart @@ -1,5 +1,5 @@ import 'package:collection/collection.dart'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:openfoodfacts/openfoodfacts.dart'; import 'package:provider/provider.dart'; @@ -79,8 +79,15 @@ class AppNavigator extends InheritedWidget { } } - void pop([dynamic result]) { - _router.router.pop(result); + /// Returns [true] if the pop was successful + /// Returns [false] if there is nothing to pop (= no history) + bool pop([dynamic result]) { + try { + _router.router.pop(result); + return true; + } on GoError catch (_) { + return false; + } } } @@ -242,9 +249,11 @@ class _SmoothGoRouter { ], ), GoRoute( - path: '/${_InternalAppRoutes.EXTERNAL_PAGE}/:page', + path: '/${_InternalAppRoutes.EXTERNAL_PAGE}', builder: (BuildContext context, GoRouterState state) { - return ExternalPage(path: state.pathParameters['page']!); + return ExternalPage( + path: Uri.decodeFull(state.uri.queryParameters['path']!), + ); }, ), ], @@ -468,5 +477,5 @@ class AppRoutes { // Open an external link (where path is relative to the OFF website) static String EXTERNAL(String path) => - '/${_InternalAppRoutes.EXTERNAL_PAGE}/$path'; + '/${_InternalAppRoutes.EXTERNAL_PAGE}?path=${Uri.encodeFull(path)}'; } diff --git a/packages/smooth_app/lib/pages/navigator/external_page.dart b/packages/smooth_app/lib/pages/navigator/external_page.dart index ed725da3de4..1cab8d78b93 100644 --- a/packages/smooth_app/lib/pages/navigator/external_page.dart +++ b/packages/smooth_app/lib/pages/navigator/external_page.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_custom_tabs/flutter_custom_tabs.dart' as tabs; +import 'package:go_router/go_router.dart'; import 'package:http/http.dart' as http; import 'package:openfoodfacts/openfoodfacts.dart'; import 'package:path/path.dart' as path; @@ -9,6 +10,7 @@ import 'package:smooth_app/helpers/launch_url_helper.dart'; import 'package:smooth_app/pages/navigator/app_navigator.dart'; import 'package:smooth_app/query/product_query.dart'; import 'package:smooth_app/services/smooth_services.dart'; +import 'package:url_launcher/url_launcher.dart'; /// This screen is only used for deep links! /// @@ -62,6 +64,7 @@ class _ExternalPageState extends State { try { if (Platform.isAndroid) { + /// Custom tabs WidgetsFlutterBinding.ensureInitialized(); await tabs.launchUrl( Uri.parse(url), @@ -70,13 +73,22 @@ class _ExternalPageState extends State { ), ); } else { - await LaunchUrlHelper.launchURL(url); + /// The default browser + await LaunchUrlHelper.launchURL( + url, + mode: LaunchMode.externalApplication, + ); } } catch (e) { Logs.e('Unable to open an external link', ex: e); } finally { if (mounted) { - AppNavigator.of(context).pop(); + final bool success = AppNavigator.of(context).pop(); + if (!success) { + /// This page was called with the go() without an history + /// (mainly for an external deep link) + GoRouter.of(context).go('/'); + } } } });