import 'dart:developer'; import 'package:flutter_linkify/flutter_linkify.dart'; import 'package:url_launcher/url_launcher.dart'; /// Single entry point for opening links that come from outside the app (chat /// messages, ticker content, emergency notices). class UrlOpener { /// Schemes we hand to the platform. Message content is user supplied, so /// anything that could address another app directly stays out. static const _allowedSchemes = {'http', 'https', 'mailto', 'tel'}; static Future onOpen(LinkableElement link) => openUrl(link.url); static Future openUrl(String url) async { final uri = Uri.tryParse(url); if (uri == null || !_allowedSchemes.contains(uri.scheme.toLowerCase())) { return; } // externalApplication first: it hands the link to the app that owns it // (YouTube, Maps, the mail client) instead of iOS' in-app Safari sheet, // which throws a PlatformException whenever its load fails. for (final mode in const [ LaunchMode.externalApplication, LaunchMode.platformDefault, ]) { try { if (await launchUrl(uri, mode: mode)) return; } catch (e) { log('launching $uri as $mode failed: $e'); } } } }