chatapp3-flutter/lib/shared/tools/sc_url_launcher_utils.dart
2026-04-16 15:07:47 +08:00

120 lines
3.1 KiB
Dart

import 'package:url_launcher/url_launcher.dart';
class SCUrlLauncherUtils {
static const Set<String> _httpSchemes = {'http', 'https'};
static bool isHttpUrl(String url) {
final uri = Uri.tryParse(url);
if (uri == null) {
return false;
}
return _httpSchemes.contains(uri.scheme.toLowerCase());
}
static bool isCustomSchemeUrl(String url) {
final uri = Uri.tryParse(url);
if (uri == null || uri.scheme.isEmpty) {
return false;
}
return !_httpSchemes.contains(uri.scheme.toLowerCase());
}
static bool isWhatsAppUrl(String url) {
final uri = Uri.tryParse(url);
if (uri == null) {
return false;
}
final scheme = uri.scheme.toLowerCase();
final host = uri.host.toLowerCase();
return scheme == 'whatsapp' ||
host == 'wa.me' ||
host == 'api.whatsapp.com' ||
host == 'whatsapp.com' ||
host.endsWith('.whatsapp.com');
}
static bool shouldOpenExternally(String url) {
return isCustomSchemeUrl(url) || isWhatsAppUrl(url);
}
static Future<bool> launchExternal(String url) async {
final uri = Uri.tryParse(url);
if (uri == null || uri.scheme.isEmpty) {
return false;
}
final launchTargets = <Uri>[];
final normalizedUri = _normalizeWhatsAppUri(uri);
if (normalizedUri != null && normalizedUri.toString() != uri.toString()) {
launchTargets.add(normalizedUri);
}
launchTargets.add(uri);
for (final target in launchTargets) {
try {
final launched = await launchUrl(
target,
mode: LaunchMode.externalApplication,
);
if (launched) {
return true;
}
} catch (_) {}
}
return false;
}
static Uri? _normalizeWhatsAppUri(Uri uri) {
if (uri.scheme.toLowerCase() == 'whatsapp') {
return uri;
}
final scheme = uri.scheme.toLowerCase();
final host = uri.host.toLowerCase();
if (!_httpSchemes.contains(scheme)) {
return null;
}
if (host == 'wa.me') {
final pathSegments =
uri.pathSegments.where((segment) => segment.isNotEmpty).toList();
if (pathSegments.length != 1 ||
!_looksLikeWhatsAppPhone(pathSegments.first)) {
return null;
}
return Uri(
scheme: 'whatsapp',
host: 'send',
queryParameters: {
'phone': pathSegments.first,
if ((uri.queryParameters['text'] ?? '').isNotEmpty)
'text': uri.queryParameters['text']!,
},
);
}
if (host == 'api.whatsapp.com' && uri.path.toLowerCase() == '/send') {
final phone = uri.queryParameters['phone'] ?? '';
final text = uri.queryParameters['text'] ?? '';
if (phone.isEmpty && text.isEmpty) {
return null;
}
return Uri(
scheme: 'whatsapp',
host: 'send',
queryParameters: {
if (phone.isNotEmpty) 'phone': phone,
if (text.isNotEmpty) 'text': text,
},
);
}
return null;
}
static bool _looksLikeWhatsAppPhone(String value) {
return RegExp(r'^\d+$').hasMatch(value);
}
}