Skip to content

Commit 71ec0cc

Browse files
committed
content: Attempt to open external app for links on Android
This is a lot better than the default, though still not ideal. Comments describe a couple of upstream bugs that we should file or comment on.
1 parent c365525 commit 71ec0cc

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

lib/widgets/content.dart

+20-1
Original file line numberDiff line numberDiff line change
@@ -673,13 +673,32 @@ void _launchUrl(BuildContext context, String urlString) async {
673673
url = store.account.realmUrl.resolve(urlString);
674674
} on FormatException { // TODO(log)
675675
await showError(context, null);
676+
if (!context.mounted) return; // TODO(dart): redundant for sake of lint
676677
return;
677678
}
678679

679680
bool launched = false;
680681
String? errorMessage;
681682
try {
682-
launched = await ZulipBinding.instance.launchUrl(url);
683+
launched = await ZulipBinding.instance.launchUrl(url,
684+
mode: switch (Theme.of(context).platform) {
685+
// TODO(upstream) The url_launcher default on Android is a weird UX:
686+
// opens a webview in-app, but on a blank black background.
687+
// The status bar is hidden:
688+
// https://github.com/flutter/flutter/issues/120883
689+
// but also there's no app bar, no location bar, no share button;
690+
// no browser chrome at all.
691+
// Probably what we really want is a "Chrome custom tab":
692+
// https://github.com/flutter/flutter/issues/18589
693+
// TODO(upstream) With url_launcher's LaunchMode.externalApplication
694+
// on Android, we still don't get the normal Android UX for
695+
// opening a URL in a browser, where the system gives the user
696+
// a bit of UI to choose which browser to use:
697+
// https://github.com/zulip/zulip-flutter/issues/74#issuecomment-1514040730
698+
TargetPlatform.android => LaunchMode.externalApplication,
699+
_ => LaunchMode.platformDefault,
700+
},
701+
);
683702
} on PlatformException catch (e) {
684703
errorMessage = e.message;
685704
}

test/widgets/content_test.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void main() {
1919
TestZulipBinding.ensureInitialized();
2020

2121
group('LinkNode interactions', () {
22-
const expectedModeAndroid = LaunchMode.platformDefault;
22+
const expectedModeAndroid = LaunchMode.externalApplication;
2323

2424
// The Flutter test font uses square glyphs, so width equals height:
2525
// https://github.com/flutter/flutter/wiki/Flutter-Test-Fonts
@@ -43,7 +43,8 @@ void main() {
4343
'<p><a href="https://example/">hello</a></p>');
4444

4545
await tester.tap(find.text('hello'));
46-
const expectedMode = LaunchMode.platformDefault;
46+
final expectedMode = defaultTargetPlatform == TargetPlatform.android ?
47+
LaunchMode.externalApplication : LaunchMode.platformDefault;
4748
check(TestZulipBinding.instance.takeLaunchUrlCalls())
4849
.single.equals((url: Uri.parse('https://example/'), mode: expectedMode));
4950
}, variant: const TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS}));

0 commit comments

Comments
 (0)