import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/models/view/alert_data.dart'; import 'package:didvan/providers/user.dart'; import 'package:didvan/services/media/media.dart'; import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/views/widgets/menu_item.dart'; import 'package:didvan/views/widgets/didvan/divider.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:provider/provider.dart'; import 'package:image_cropper/image_cropper.dart'; class ProfilePhoto extends StatefulWidget { const ProfilePhoto({Key? key}) : super(key: key); @override State createState() => _ProfilePhotoState(); } class _ProfilePhotoState extends State { @override Widget build(BuildContext context) { final userProvider = context.watch(); return GestureDetector( onTap: () => _openImagePickerSheet(), child: Center( child: Stack( children: [ if (userProvider.user.photo == null) Container( height: 96, width: 96, decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context).colorScheme.focused, ), child: Icon( DidvanIcons.profile_solid, size: 60, color: Theme.of(context).colorScheme.title, ), ), if (userProvider.user.photo != null) SkeletonImage( key: GlobalKey(debugLabel: userProvider.user.photo), imageUrl: userProvider.user.photo!, width: 96, height: 96, borderRadius: BorderRadius.circular(200), ), Positioned( bottom: 0, right: 0, child: Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( border: Border.all( color: Theme.of(context).colorScheme.cardBorder, ), color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(100), ), child: const Icon( DidvanIcons.camera_regular, ), ), ), ], ), ), ); } Future _openImagePickerSheet() async { FocusScope.of(context).unfocus(); await ActionSheetUtils.showBottomSheet( data: ActionSheetData( content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const DidvanText('بارگذاری تصویر از:'), const SizedBox(height: 16), Padding( padding: const EdgeInsets.only(right: 20), child: Column( children: [ MenuOption( title: 'دوربین', onTap: () => _setProfilePhoto(ImageSource.camera), icon: DidvanIcons.camera_regular, ), const DidvanDivider(), MenuOption( title: 'گالری', onTap: () => _setProfilePhoto(ImageSource.gallery), icon: DidvanIcons.gallery_file_regular, ), ], ), ), const DidvanDivider(), MenuOption( title: 'حذف تصویر', onTap: () => _setProfilePhoto(null), icon: DidvanIcons.trash_solid, color: Theme.of(context).colorScheme.secondary, ), ], ), hasConfirmButton: false, hasDismissButton: false, title: 'بارگذاری تصویر از:', ), ); } Future _setProfilePhoto(ImageSource? source) async { ActionSheetUtils.pop(); final state = context.read(); if (source == null) { final result = await state.deleteProfilePhoto(); ActionSheetUtils.showAlert( AlertData( message: result ? 'تصویر پروفایل حذف شد.' : 'حذف تصویر موفقیت آمیز نبود.', aLertType: result ? ALertType.success : ALertType.error, ), ); return; } final pickedFile = await MediaService.pickImage(source: source); dynamic file; if (pickedFile != null && !kIsWeb) { file = await ImageCropper().cropImage( sourcePath: pickedFile.path, aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1), androidUiSettings: const AndroidUiSettings(toolbarTitle: 'برش تصویر'), iosUiSettings: const IOSUiSettings( title: 'برش تصویر', doneButtonTitle: 'تایید', cancelButtonTitle: 'بازگشت', ), compressQuality: 30, ); if (file == null) return; } if (pickedFile == null) return; final uploadFile = kIsWeb ? pickedFile : file; final result = await state.setProfilePhoto(uploadFile); ActionSheetUtils.showAlert( AlertData( message: result ? 'تصویر پروفایل بارگذاری شد.' : 'بارگذاری تصویر موفقیت آمیز نبود.', aLertType: result ? ALertType.success : ALertType.error, ), ); } }