- Implemented ContactProfileResponse and related models for handling contact details. - Created ContactTagResponse and ContactTag models for managing contact tags. - Added DirectoryCommentResponse and DirectoryComment models for comment management. - Developed DirectoryFilterBottomSheet for filtering contacts. - Introduced OrganizationListModel for organization data handling. - Updated routes to include DirectoryMainScreen. - Enhanced DashboardScreen to navigate to the new directory page. - Created ContactDetailScreen for displaying detailed contact information. - Developed DirectoryMainScreen for managing and displaying contacts. - Added dependencies for font_awesome_flutter and flutter_html in pubspec.yaml.
99 lines
3.0 KiB
Dart
99 lines
3.0 KiB
Dart
import 'package:flutter/services.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
|
import 'package:marco/helpers/services/app_logger.dart';
|
|
|
|
class LauncherUtils {
|
|
static Future<void> launchPhone(String phoneNumber) async {
|
|
logSafe('Attempting to launch phone: $phoneNumber', sensitive: true);
|
|
|
|
final Uri url = Uri(scheme: 'tel', path: phoneNumber);
|
|
await _tryLaunch(url, 'Could not launch phone');
|
|
}
|
|
|
|
static Future<void> launchEmail(String email) async {
|
|
logSafe('Attempting to launch email: $email', sensitive: true);
|
|
|
|
final Uri url = Uri(scheme: 'mailto', path: email);
|
|
await _tryLaunch(url, 'Could not launch email');
|
|
}
|
|
|
|
static Future<void> launchWhatsApp(String phoneNumber) async {
|
|
logSafe('Attempting to launch WhatsApp with: $phoneNumber',
|
|
sensitive: true);
|
|
|
|
String normalized = phoneNumber.replaceAll(RegExp(r'\D'), '');
|
|
if (!normalized.startsWith('91')) {
|
|
normalized = '91$normalized';
|
|
}
|
|
|
|
logSafe('Normalized WhatsApp number: $normalized', sensitive: true);
|
|
|
|
if (normalized.length < 12) {
|
|
logSafe('Invalid WhatsApp number: $normalized', sensitive: true);
|
|
showAppSnackbar(
|
|
title: 'Error',
|
|
message: 'Invalid phone number for WhatsApp',
|
|
type: SnackbarType.error,
|
|
);
|
|
return;
|
|
}
|
|
|
|
final Uri url = Uri.parse('https://wa.me/$normalized');
|
|
await _tryLaunch(url, 'Could not open WhatsApp');
|
|
}
|
|
|
|
static Future<void> copyToClipboard(String text,
|
|
{required String typeLabel}) async {
|
|
try {
|
|
logSafe('Copying "$typeLabel" to clipboard');
|
|
|
|
HapticFeedback.lightImpact();
|
|
await Clipboard.setData(ClipboardData(text: text));
|
|
showAppSnackbar(
|
|
title: 'Copied',
|
|
message: '$typeLabel copied to clipboard',
|
|
type: SnackbarType.success,
|
|
);
|
|
} catch (e, st) {
|
|
logSafe('Failed to copy $typeLabel to clipboard: $e',
|
|
stackTrace: st, level: LogLevel.error, sensitive: true);
|
|
|
|
showAppSnackbar(
|
|
title: 'Error',
|
|
message: 'Failed to copy $typeLabel',
|
|
type: SnackbarType.error,
|
|
);
|
|
}
|
|
}
|
|
|
|
static Future<void> _tryLaunch(Uri url, String errorMsg) async {
|
|
try {
|
|
logSafe('Trying to launch URL: ${url.toString()}');
|
|
|
|
if (await canLaunchUrl(url)) {
|
|
await launchUrl(url, mode: LaunchMode.externalApplication);
|
|
logSafe('URL launched successfully: ${url.toString()}');
|
|
} else {
|
|
logSafe(
|
|
'Launch failed - canLaunchUrl returned false: ${url.toString()}',
|
|
level: LogLevel.warning);
|
|
showAppSnackbar(
|
|
title: 'Error',
|
|
message: errorMsg,
|
|
type: SnackbarType.error,
|
|
);
|
|
}
|
|
} catch (e, st) {
|
|
logSafe('Exception during launch of ${url.toString()}: $e',
|
|
stackTrace: st, level: LogLevel.error);
|
|
|
|
showAppSnackbar(
|
|
title: 'Error',
|
|
message: '$errorMsg: $e',
|
|
type: SnackbarType.error,
|
|
);
|
|
}
|
|
}
|
|
}
|