Main coves client
at main 111 lines 3.6 kB view raw
1import 'package:flutter/material.dart'; 2import 'package:image_picker/image_picker.dart'; 3 4import '../constants/app_colors.dart'; 5 6/// A modal bottom sheet for selecting an image source (gallery or camera). 7/// 8/// Usage: 9/// ```dart 10/// final source = await ImageSourcePicker.show(context); 11/// if (source != null) { 12/// // Pick image using the selected source 13/// } 14/// ``` 15abstract final class ImageSourcePicker { 16 /// Shows the image source picker modal and returns the selected source. 17 /// 18 /// Returns [ImageSource.gallery], [ImageSource.camera], or null if cancelled. 19 static Future<ImageSource?> show(BuildContext context) { 20 return showModalBottomSheet<ImageSource>( 21 context: context, 22 backgroundColor: AppColors.backgroundSecondary, 23 shape: const RoundedRectangleBorder( 24 borderRadius: BorderRadius.vertical(top: Radius.circular(16)), 25 ), 26 builder: (context) => const _ImageSourcePickerSheet(), 27 ); 28 } 29} 30 31class _ImageSourcePickerSheet extends StatelessWidget { 32 const _ImageSourcePickerSheet(); 33 34 @override 35 Widget build(BuildContext context) { 36 return SafeArea( 37 child: Padding( 38 padding: const EdgeInsets.symmetric(vertical: 16), 39 child: Column( 40 mainAxisSize: MainAxisSize.min, 41 children: [ 42 Container( 43 width: 40, 44 height: 4, 45 margin: const EdgeInsets.only(bottom: 16), 46 decoration: BoxDecoration( 47 color: AppColors.border, 48 borderRadius: BorderRadius.circular(2), 49 ), 50 ), 51 const Text( 52 'Select Image Source', 53 style: TextStyle( 54 color: Colors.white, 55 fontSize: 18, 56 fontWeight: FontWeight.w600, 57 ), 58 ), 59 const SizedBox(height: 16), 60 ListTile( 61 leading: Container( 62 padding: const EdgeInsets.all(10), 63 decoration: BoxDecoration( 64 color: AppColors.primary.withValues(alpha: 0.1), 65 borderRadius: BorderRadius.circular(8), 66 ), 67 child: const Icon( 68 Icons.photo_library, 69 color: AppColors.primary, 70 ), 71 ), 72 title: const Text( 73 'Choose from Gallery', 74 style: TextStyle(color: Colors.white), 75 ), 76 subtitle: const Text( 77 'Select an existing photo', 78 style: TextStyle(color: AppColors.textSecondary, fontSize: 12), 79 ), 80 onTap: () => Navigator.pop(context, ImageSource.gallery), 81 ), 82 ListTile( 83 leading: Container( 84 padding: const EdgeInsets.all(10), 85 decoration: BoxDecoration( 86 color: AppColors.teal.withValues(alpha: 0.1), 87 borderRadius: BorderRadius.circular(8), 88 ), 89 child: const Icon( 90 Icons.camera_alt, 91 color: AppColors.teal, 92 ), 93 ), 94 title: const Text( 95 'Take a Photo', 96 style: TextStyle(color: Colors.white), 97 ), 98 subtitle: const Text( 99 'Use camera to capture', 100 style: TextStyle(color: AppColors.textSecondary, fontSize: 12), 101 ), 102 onTap: () => Navigator.pop(context, ImageSource.camera), 103 ), 104 105 const SizedBox(height: 8), 106 ], 107 ), 108 ), 109 ); 110 } 111}