91 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:flutter/material.dart';
 | |
| import 'package:flutter_contacts/flutter_contacts.dart';
 | |
| import 'package:permission_handler/permission_handler.dart';
 | |
| import 'package:marco/helpers/widgets/my_snackbar.dart';
 | |
| import 'package:marco/helpers/services/app_logger.dart';
 | |
| 
 | |
| class ContactPickerHelper {
 | |
|   static Future<String?> pickIndianPhoneNumber(BuildContext context) async {
 | |
|     final status = await Permission.contacts.request();
 | |
| 
 | |
|     if (!status.isGranted) {
 | |
|       if (status.isPermanentlyDenied) {
 | |
|         await openAppSettings();
 | |
|       }
 | |
| 
 | |
|       showAppSnackbar(
 | |
|         title: "Permission Required",
 | |
|         message:
 | |
|             "Please allow Contacts permission from settings to pick a contact.",
 | |
|         type: SnackbarType.warning,
 | |
|       );
 | |
|       return null;
 | |
|     }
 | |
| 
 | |
|     try {
 | |
|       final picked = await FlutterContacts.openExternalPick();
 | |
|       if (picked == null) return null;
 | |
| 
 | |
|       final contact =
 | |
|           await FlutterContacts.getContact(picked.id, withProperties: true);
 | |
|       if (contact == null || contact.phones.isEmpty) {
 | |
|         showAppSnackbar(
 | |
|           title: "No Phone Number",
 | |
|           message: "Selected contact has no phone number.",
 | |
|           type: SnackbarType.warning,
 | |
|         );
 | |
|         return null;
 | |
|       }
 | |
| 
 | |
|       final indiaPhones = contact.phones.where((p) {
 | |
|         final normalized = p.number.replaceAll(RegExp(r'[^0-9+]'), '');
 | |
|         return normalized.startsWith('+91') || RegExp(r'^\d{10}$').hasMatch(normalized);
 | |
|       }).toList();
 | |
| 
 | |
|       if (indiaPhones.isEmpty) {
 | |
|         showAppSnackbar(
 | |
|           title: "No Indian Number",
 | |
|           message: "Selected contact has no Indian (+91) phone number.",
 | |
|           type: SnackbarType.warning,
 | |
|         );
 | |
|         return null;
 | |
|       }
 | |
| 
 | |
|       if (indiaPhones.length == 1) {
 | |
|         return _normalizeNumber(indiaPhones.first.number);
 | |
|       }
 | |
| 
 | |
|       return await showDialog<String>(
 | |
|         context: context,
 | |
|         builder: (ctx) => AlertDialog(
 | |
|           title: const Text("Choose a number"),
 | |
|           content: Column(
 | |
|             mainAxisSize: MainAxisSize.min,
 | |
|             children: indiaPhones
 | |
|                 .map((p) => ListTile(
 | |
|                       title: Text(p.number),
 | |
|                       onTap: () => Navigator.of(ctx).pop(_normalizeNumber(p.number)),
 | |
|                     ))
 | |
|                 .toList(),
 | |
|           ),
 | |
|         ),
 | |
|       );
 | |
|     } catch (e, st) {
 | |
|       logSafe("Error picking contact", level: LogLevel.error, error: e, stackTrace: st);
 | |
|       showAppSnackbar(
 | |
|         title: "Error",
 | |
|         message: "Failed to fetch contact.",
 | |
|         type: SnackbarType.error,
 | |
|       );
 | |
|       return null;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   static String _normalizeNumber(String raw) {
 | |
|     final normalized = raw.replaceAll(RegExp(r'[^0-9]'), '');
 | |
|     return normalized.length > 10
 | |
|         ? normalized.substring(normalized.length - 10)
 | |
|         : normalized;
 | |
|   }
 | |
| }
 | 
