Skip to content

Commit 692c2f5

Browse files
committed
actions [nfc]: Move open-link logic here, from lib/widgets/content
We'll use when we add a "Learn more"-button param to showErrorDialog, coming up.
1 parent fe3538b commit 692c2f5

File tree

3 files changed

+37
-29
lines changed

3 files changed

+37
-29
lines changed

lib/widgets/actions.dart

+32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:async';
22

3+
import 'package:flutter/foundation.dart';
34
import 'package:flutter/material.dart';
45
import 'package:flutter/services.dart';
56

@@ -281,4 +282,35 @@ abstract final class PlatformActions {
281282
SnackBar(behavior: SnackBarBehavior.floating, content: successContent));
282283
}
283284
}
285+
286+
/// Opens a URL with [ZulipBinding.launchUrl], with an error dialog on failure.
287+
// TODO widget tests
288+
static Future<void> launchUrl(BuildContext context, Uri url) async {
289+
bool launched = false;
290+
String? errorMessage;
291+
try {
292+
launched = await ZulipBinding.instance.launchUrl(url,
293+
mode: switch (defaultTargetPlatform) {
294+
// On iOS we prefer LaunchMode.externalApplication because (for
295+
// HTTP URLs) LaunchMode.platformDefault uses SFSafariViewController,
296+
// which gives an awkward UX as described here:
297+
// https://chat.zulip.org/#narrow/stream/48-mobile/topic/in-app.20browser/near/1169118
298+
TargetPlatform.iOS => UrlLaunchMode.externalApplication,
299+
_ => UrlLaunchMode.platformDefault,
300+
});
301+
} on PlatformException catch (e) {
302+
errorMessage = e.message;
303+
}
304+
if (!launched) { // TODO(log)
305+
if (!context.mounted) return;
306+
307+
final zulipLocalizations = ZulipLocalizations.of(context);
308+
showErrorDialog(context: context,
309+
title: zulipLocalizations.errorCouldNotOpenLinkTitle,
310+
message: [
311+
zulipLocalizations.errorCouldNotOpenLink(url.toString()),
312+
if (errorMessage != null) errorMessage,
313+
].join("\n\n"));
314+
}
315+
}
284316
}

lib/widgets/content.dart

+2-29
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
import 'dart:async';
22

33
import 'package:flutter/cupertino.dart';
4-
import 'package:flutter/foundation.dart';
54
import 'package:flutter/gestures.dart';
65
import 'package:flutter/material.dart';
76
import 'package:flutter/rendering.dart';
8-
import 'package:flutter/services.dart';
97
import 'package:html/dom.dart' as dom;
108
import 'package:intl/intl.dart';
119

1210
import '../api/core.dart';
1311
import '../api/model/model.dart';
1412
import '../generated/l10n/zulip_localizations.dart';
1513
import '../model/avatar_url.dart';
16-
import '../model/binding.dart';
1714
import '../model/content.dart';
1815
import '../model/internal_link.dart';
16+
import 'actions.dart';
1917
import 'code_block.dart';
2018
import 'dialog.dart';
2119
import 'icons.dart';
@@ -1432,32 +1430,7 @@ void _launchUrl(BuildContext context, String urlString) async {
14321430
return;
14331431
}
14341432

1435-
bool launched = false;
1436-
String? errorMessage;
1437-
try {
1438-
launched = await ZulipBinding.instance.launchUrl(url,
1439-
mode: switch (defaultTargetPlatform) {
1440-
// On iOS we prefer LaunchMode.externalApplication because (for
1441-
// HTTP URLs) LaunchMode.platformDefault uses SFSafariViewController,
1442-
// which gives an awkward UX as described here:
1443-
// https://chat.zulip.org/#narrow/stream/48-mobile/topic/in-app.20browser/near/1169118
1444-
TargetPlatform.iOS => UrlLaunchMode.externalApplication,
1445-
_ => UrlLaunchMode.platformDefault,
1446-
});
1447-
} on PlatformException catch (e) {
1448-
errorMessage = e.message;
1449-
}
1450-
if (!launched) { // TODO(log)
1451-
if (!context.mounted) return;
1452-
1453-
final zulipLocalizations = ZulipLocalizations.of(context);
1454-
showErrorDialog(context: context,
1455-
title: zulipLocalizations.errorCouldNotOpenLinkTitle,
1456-
message: [
1457-
zulipLocalizations.errorCouldNotOpenLink(url.toString()),
1458-
if (errorMessage != null) errorMessage,
1459-
].join("\n\n"));
1460-
}
1433+
await PlatformActions.launchUrl(context, url);
14611434
}
14621435

14631436
/// Like [Image.network], but includes [authHeader] if [src] is on-realm.

lib/widgets/login.dart

+3
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ class _LoginPageState extends State<LoginPage> {
343343
// Could set [_inProgress]… but we'd need to unset it if the web-auth
344344
// attempt is aborted (by the user closing the browser, for example),
345345
// and I don't think we can reliably know when that happens.
346+
347+
// Not using [PlatformActions.launchUrl] because web auth needs special
348+
// error handling.
346349
await ZulipBinding.instance.launchUrl(url, mode: LaunchMode.inAppBrowserView);
347350
} catch (e) {
348351
assert(debugLog(e.toString()));

0 commit comments

Comments
 (0)