112 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			3.2 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 {
 | |
|   /// Launches the phone dialer with the provided phone number
 | |
|   static Future<void> launchPhone(String phoneNumber) async {
 | |
|     logSafe('Attempting to launch phone: $phoneNumber',  );
 | |
| 
 | |
|     final Uri url = Uri(scheme: 'tel', path: phoneNumber);
 | |
|     await _tryLaunch(url, 'Could not launch phone');
 | |
|   }
 | |
| 
 | |
|   /// Launches the email app with the provided email address
 | |
|   static Future<void> launchEmail(String email) async {
 | |
|     logSafe('Attempting to launch email: $email',  );
 | |
| 
 | |
|     final Uri url = Uri(scheme: 'mailto', path: email);
 | |
|     await _tryLaunch(url, 'Could not launch email');
 | |
|   }
 | |
| 
 | |
|   /// Launches WhatsApp with the provided phone number
 | |
|   static Future<void> launchWhatsApp(String phoneNumber) async {
 | |
|     logSafe('Attempting to launch WhatsApp with: $phoneNumber',  );
 | |
| 
 | |
|     String normalized = phoneNumber.replaceAll(RegExp(r'\D'), '');
 | |
|     if (!normalized.startsWith('91')) {
 | |
|       normalized = '91$normalized';
 | |
|     }
 | |
| 
 | |
|     logSafe('Normalized WhatsApp number: $normalized',  );
 | |
| 
 | |
|     if (normalized.length < 12) {
 | |
|       logSafe('Invalid WhatsApp number: $normalized',  );
 | |
|       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');
 | |
|   }
 | |
| 
 | |
|   /// Copies text to clipboard with feedback
 | |
|   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,
 | |
|          
 | |
|       );
 | |
|       showAppSnackbar(
 | |
|         title: 'Error',
 | |
|         message: 'Failed to copy $typeLabel',
 | |
|         type: SnackbarType.error,
 | |
|       );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Internal function to launch a URL and show error if failed
 | |
|   static Future<void> _tryLaunch(Uri url, String errorMsg) async {
 | |
|     try {
 | |
|       logSafe('Trying to launch URL: ${url.toString()}');
 | |
| 
 | |
|       final bool launched = await launchUrl(
 | |
|         url,
 | |
|         mode: LaunchMode.externalApplication,
 | |
|       );
 | |
| 
 | |
|       if (launched) {
 | |
|         logSafe('URL launched successfully: ${url.toString()}');
 | |
|       } else {
 | |
|         logSafe(
 | |
|           'launchUrl 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,
 | |
|       );
 | |
|     }
 | |
|   }
 | |
| }
 | 
