|
1 |
| -import 'package:flutter/foundation.dart'; |
2 | 1 | import 'package:flutter/gestures.dart';
|
3 | 2 | import 'package:flutter/material.dart';
|
4 |
| -import 'package:flutter/services.dart'; |
5 | 3 | import 'package:html/dom.dart' as dom;
|
6 | 4 | import 'package:intl/intl.dart';
|
7 | 5 | import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
|
8 | 6 |
|
9 | 7 | import '../api/core.dart';
|
10 | 8 | import '../api/model/model.dart';
|
11 | 9 | import '../model/avatar_url.dart';
|
12 |
| -import '../model/binding.dart'; |
13 | 10 | import '../model/content.dart';
|
14 |
| -import '../model/internal_link.dart'; |
15 | 11 | import 'code_block.dart';
|
16 |
| -import 'dialog.dart'; |
17 | 12 | import 'icons.dart';
|
| 13 | +import 'launch_url.dart'; |
18 | 14 | import 'lightbox.dart';
|
19 |
| -import 'message_list.dart'; |
20 | 15 | import 'store.dart';
|
21 | 16 | import 'text.dart';
|
22 | 17 |
|
@@ -507,7 +502,7 @@ class _BlockInlineContainerState extends State<_BlockInlineContainer> {
|
507 | 502 |
|
508 | 503 | void _prepareRecognizers() {
|
509 | 504 | _recognizers.addEntries(widget.links.map((node) => MapEntry(node,
|
510 |
| - TapGestureRecognizer()..onTap = () => _launchUrl(context, node.url)))); |
| 505 | + TapGestureRecognizer()..onTap = () => launchUrlWithRealm(context, node.url)))); |
511 | 506 | }
|
512 | 507 |
|
513 | 508 | void _disposeRecognizers() {
|
@@ -873,52 +868,6 @@ class GlobalTime extends StatelessWidget {
|
873 | 868 | }
|
874 | 869 | }
|
875 | 870 |
|
876 |
| -void _launchUrl(BuildContext context, String urlString) async { |
877 |
| - Future<void> showError(BuildContext context, String? message) { |
878 |
| - return showErrorDialog(context: context, |
879 |
| - title: 'Unable to open link', |
880 |
| - message: [ |
881 |
| - 'Link could not be opened: $urlString', |
882 |
| - if (message != null) message, |
883 |
| - ].join("\n\n")); |
884 |
| - } |
885 |
| - |
886 |
| - final store = PerAccountStoreWidget.of(context); |
887 |
| - final url = store.tryResolveUrl(urlString); |
888 |
| - if (url == null) { // TODO(log) |
889 |
| - await showError(context, null); |
890 |
| - return; |
891 |
| - } |
892 |
| - |
893 |
| - final internalNarrow = parseInternalLink(url, store); |
894 |
| - if (internalNarrow != null) { |
895 |
| - Navigator.push(context, |
896 |
| - MessageListPage.buildRoute(context: context, |
897 |
| - narrow: internalNarrow)); |
898 |
| - return; |
899 |
| - } |
900 |
| - |
901 |
| - bool launched = false; |
902 |
| - String? errorMessage; |
903 |
| - try { |
904 |
| - launched = await ZulipBinding.instance.launchUrl(url, |
905 |
| - mode: switch (defaultTargetPlatform) { |
906 |
| - // On iOS we prefer LaunchMode.externalApplication because (for |
907 |
| - // HTTP URLs) LaunchMode.platformDefault uses SFSafariViewController, |
908 |
| - // which gives an awkward UX as described here: |
909 |
| - // https://chat.zulip.org/#narrow/stream/48-mobile/topic/in-app.20browser/near/1169118 |
910 |
| - TargetPlatform.iOS => UrlLaunchMode.externalApplication, |
911 |
| - _ => UrlLaunchMode.platformDefault, |
912 |
| - }); |
913 |
| - } on PlatformException catch (e) { |
914 |
| - errorMessage = e.message; |
915 |
| - } |
916 |
| - if (!launched) { // TODO(log) |
917 |
| - if (!context.mounted) return; |
918 |
| - await showError(context, errorMessage); |
919 |
| - } |
920 |
| -} |
921 |
| - |
922 | 871 | /// Like [Image.network], but includes [authHeader] if [src] is on-realm.
|
923 | 872 | ///
|
924 | 873 | /// Use this to present image content in the ambient realm: avatars, images in
|
|
0 commit comments