120 lines
3.1 KiB
Dart
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);
|
|
}
|
|
}
|