|
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 |
|
@@ -525,7 +520,7 @@ class _BlockInlineContainerState extends State<_BlockInlineContainer> {
|
525 | 520 |
|
526 | 521 | void _prepareRecognizers() {
|
527 | 522 | _recognizers.addEntries(widget.links.map((node) => MapEntry(node,
|
528 |
| - TapGestureRecognizer()..onTap = () => _launchUrl(context, node.url)))); |
| 523 | + TapGestureRecognizer()..onTap = () => launchUrlWithRealm(context, node.url)))); |
529 | 524 | }
|
530 | 525 |
|
531 | 526 | void _disposeRecognizers() {
|
@@ -891,52 +886,6 @@ class GlobalTime extends StatelessWidget {
|
891 | 886 | }
|
892 | 887 | }
|
893 | 888 |
|
894 |
| -void _launchUrl(BuildContext context, String urlString) async { |
895 |
| - Future<void> showError(BuildContext context, String? message) { |
896 |
| - return showErrorDialog(context: context, |
897 |
| - title: 'Unable to open link', |
898 |
| - message: [ |
899 |
| - 'Link could not be opened: $urlString', |
900 |
| - if (message != null) message, |
901 |
| - ].join("\n\n")); |
902 |
| - } |
903 |
| - |
904 |
| - final store = PerAccountStoreWidget.of(context); |
905 |
| - final url = store.tryResolveUrl(urlString); |
906 |
| - if (url == null) { // TODO(log) |
907 |
| - await showError(context, null); |
908 |
| - return; |
909 |
| - } |
910 |
| - |
911 |
| - final internalNarrow = parseInternalLink(url, store); |
912 |
| - if (internalNarrow != null) { |
913 |
| - Navigator.push(context, |
914 |
| - MessageListPage.buildRoute(context: context, |
915 |
| - narrow: internalNarrow)); |
916 |
| - return; |
917 |
| - } |
918 |
| - |
919 |
| - bool launched = false; |
920 |
| - String? errorMessage; |
921 |
| - try { |
922 |
| - launched = await ZulipBinding.instance.launchUrl(url, |
923 |
| - mode: switch (defaultTargetPlatform) { |
924 |
| - // On iOS we prefer LaunchMode.externalApplication because (for |
925 |
| - // HTTP URLs) LaunchMode.platformDefault uses SFSafariViewController, |
926 |
| - // which gives an awkward UX as described here: |
927 |
| - // https://chat.zulip.org/#narrow/stream/48-mobile/topic/in-app.20browser/near/1169118 |
928 |
| - TargetPlatform.iOS => UrlLaunchMode.externalApplication, |
929 |
| - _ => UrlLaunchMode.platformDefault, |
930 |
| - }); |
931 |
| - } on PlatformException catch (e) { |
932 |
| - errorMessage = e.message; |
933 |
| - } |
934 |
| - if (!launched) { // TODO(log) |
935 |
| - if (!context.mounted) return; |
936 |
| - await showError(context, errorMessage); |
937 |
| - } |
938 |
| -} |
939 |
| - |
940 | 889 | /// Like [Image.network], but includes [authHeader] if [src] is on-realm.
|
941 | 890 | ///
|
942 | 891 | /// Use this to present image content in the ambient realm: avatars, images in
|
|
0 commit comments