From c4c1a61e9d6fc7bfdf2cd6cc4cee9c107867c496 Mon Sep 17 00:00:00 2001 From: rajveermalviya Date: Wed, 20 Mar 2024 17:34:04 +0530 Subject: [PATCH] content: Open links externally on iOS On iOS we prefer LaunchMode.externalApplication because (for HTTP URLs) LaunchMode.platformDefault uses SFSafariViewController, which gives an awkward UX as described here: https://chat.zulip.org/#narrow/stream/48-mobile/topic/in-app.20browser/near/1169118 Fixes: #280 --- lib/widgets/content.dart | 11 ++++++++++- test/widgets/content_test.dart | 6 +++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/widgets/content.dart b/lib/widgets/content.dart index 24794464b4..c023d6d7be 100644 --- a/lib/widgets/content.dart +++ b/lib/widgets/content.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -895,7 +896,15 @@ void _launchUrl(BuildContext context, String urlString) async { bool launched = false; String? errorMessage; try { - launched = await ZulipBinding.instance.launchUrl(url); + launched = await ZulipBinding.instance.launchUrl(url, + mode: switch (defaultTargetPlatform) { + // On iOS we prefer LaunchMode.externalApplication because (for + // HTTP URLs) LaunchMode.platformDefault uses SFSafariViewController, + // which gives an awkward UX as described here: + // https://chat.zulip.org/#narrow/stream/48-mobile/topic/in-app.20browser/near/1169118 + TargetPlatform.iOS => UrlLaunchMode.externalApplication, + _ => UrlLaunchMode.platformDefault, + }); } on PlatformException catch (e) { errorMessage = e.message; } diff --git a/test/widgets/content_test.dart b/test/widgets/content_test.dart index 5976171eec..00a7a1cfba 100644 --- a/test/widgets/content_test.dart +++ b/test/widgets/content_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:checks/checks.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/zulip_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -318,8 +319,11 @@ void main() { '

hello

'); await tapText(tester, find.text('hello')); + + final expectedLaunchMode = defaultTargetPlatform == TargetPlatform.iOS ? + LaunchMode.externalApplication : LaunchMode.platformDefault; check(testBinding.takeLaunchUrlCalls()) - .single.equals((url: Uri.parse('https://example/'), mode: LaunchMode.platformDefault)); + .single.equals((url: Uri.parse('https://example/'), mode: expectedLaunchMode)); }, variant: const TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS})); testWidgets('multiple links in paragraph', (tester) async {