import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:farm_tpf/custom_model/Media.dart'; import 'package:farm_tpf/presentation/custom_widgets/camera_helper.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_show_video.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart'; import 'package:farm_tpf/presentation/screens/actions/util_action.dart'; import 'package:farm_tpf/utils/const_assets.dart'; import 'package:farm_tpf/utils/const_common.dart'; import 'package:farm_tpf/utils/const_string.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'bloc/media_helper_bloc.dart'; import 'hoz_list_view.dart'; class WidgetMediaPicker extends StatefulWidget { final List? currentItems; final Function(List addNewFilePaths, List deleteFilePaths) onChangeFiles; WidgetMediaPicker({this.currentItems, required this.onChangeFiles}); @override _WidgetMediaPickerState createState() => _WidgetMediaPickerState(); } class _WidgetMediaPickerState extends State { List currentItems = []; List addNewFilePaths = []; List deleteFilePaths = []; @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return BlocProvider( create: (BuildContext contextA) => MediaHelperBloc()..add(ChangeListMedia(items: currentItems)), child: BlocBuilder(builder: (contextB, state) { if (state is MediaHelperFailure) { return Container(); } else if (state is MediaHelperSuccess) { currentItems = widget.currentItems ?? []; return Container( padding: EdgeInsets.all(8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Hình ảnh/ Video', style: TextStyle(color: Colors.black54, fontSize: 16)), SizedBox( height: 8, ), Row( children: [ InkWell( child: Image.asset( AppAssets.icAddMedia, fit: BoxFit.contain, width: 114, height: 114, ), onTap: () { showDialog( context: context, barrierDismissible: true, builder: (context) => Opacity( child: multipleChoice(contextB), opacity: 1, )); }, ), SizedBox( width: 8.0, ), Expanded( child: _buildListPoster(), ), ], ), ], )); } return Container(); })); } Widget multipleChoice(BuildContext context) { return CupertinoAlertDialog( title: Text(label_title_select_media), actions: [ CupertinoDialogAction( child: const Text('Chụp ảnh'), onPressed: () { Navigator.pop(context, 'Discard'); Navigator.of(context).push(MaterialPageRoute(builder: (context) => CameraHelper())).then((value) { if (value != null) { print("ok"); print(value); String filePath = value[0]; File f = File(filePath); f.length().then((lengthFileInBytes) { if (lengthFileInBytes > ConstCommon.kFileSize) { Utils.showSnackBarWarning(message: label_file_to_large); } else { bool isVideo = value[1]; Media newMedia = Media() ..isVideo = isVideo ..isServerFile = false ..pathFile = filePath; currentItems.add(newMedia); addNewFilePaths.add(filePath); BlocProvider.of(context)..add(ChangeListMedia(items: currentItems)); widget.onChangeFiles(addNewFilePaths, deleteFilePaths); } }); } }); }), CupertinoDialogAction( child: const Text('Chọn ảnh'), onPressed: () async { Navigator.pop(context, 'Discard'); FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true); if (result != null) { var listFuture = >[]; result.files.forEach((element) { listFuture.add(UtilAction.compressImage(File(element.path ?? ''))); }); Future.wait(listFuture).then((values) { bool isExistedFileTooLarge = false; values.forEach((compressFile) { if (compressFile.lengthSync() > ConstCommon.kFileSize) { isExistedFileTooLarge = true; } else { Media newMedia = Media() ..isVideo = false ..isServerFile = false ..pathFile = compressFile.path; currentItems.add(newMedia); addNewFilePaths.add(compressFile.path); } }); if (isExistedFileTooLarge) { Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); } BlocProvider.of(context)..add(ChangeListMedia(items: currentItems)); widget.onChangeFiles(addNewFilePaths, deleteFilePaths); }); } }), // CupertinoDialogAction( // child: const Text(label_select_video_from_library), // onPressed: () async { // Navigator.pop(context, 'Discard'); // FilePickerResult result = await FilePicker.platform // .pickFiles(type: FileType.video, allowMultiple: true); // if (result != null) { // bool isExistedFileTooLarge = false; // result.files?.forEach((videoFile) { // if (videoFile.size * 1000 > ConstCommon.kFileSize) { // isExistedFileTooLarge = true; // } else { // Media newMedia = Media() // ..isVideo = true // ..isServerFile = false // ..pathFile = videoFile.path; // currentItems.add(newMedia); // addNewFilePaths.add(videoFile.path); // } // }); // if (isExistedFileTooLarge) { // Utils.showSnackBarWarning( // message: "Tập tin có kích thước lớn đã được loại bỏ."); // } // BlocProvider.of(context) // ..add(ChangeListMedia(items: currentItems)); // widget.onChangeFiles(addNewFilePaths, deleteFilePaths); // } // }), CupertinoDialogAction( child: const Text(label_cancel), textStyle: TextStyle(fontWeight: FontWeight.bold), isDefaultAction: true, onPressed: () { Navigator.pop(context, 'Cancel'); }), ], ); } _buildListPoster() { return BlocBuilder(builder: (context, state) { if (state is MediaHelperSuccess) { return WrapContentHozListView( list: currentItems, itemBuilder: (context, index) { var item = currentItems[index]; return Container( width: 120, height: 120, child: _WidgetItemMedia( item: item, deleteImage: (item) { if (item.isServerFile) { var url = item.pathFile?.replaceAll(ConstCommon.baseImageUrl, ''); deleteFilePaths.add(url ?? ''); } addNewFilePaths.remove(item.pathFile); currentItems.remove(item); widget.onChangeFiles(addNewFilePaths, deleteFilePaths); BlocProvider.of(context).add(ChangeListMedia(items: currentItems)); }), ); }); } return Container(); }); } } class _WidgetItemMedia extends StatelessWidget { ItemMediaCallback deleteImage; final Media item; _WidgetItemMedia({required this.item, required this.deleteImage}); @override Widget build(BuildContext context) { return GestureDetector( onTap: () { print("Show preview image or video"); }, child: Stack( alignment: Alignment.topRight, children: [ Positioned.fill( child: item.isVideo ?? false ? VideoWidget( pathFile: item.pathFile ?? '', isServerFile: item.isServerFile, play: false, ) : Container( margin: EdgeInsets.all(4.0), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.grey), borderRadius: BorderRadius.all( Radius.circular(8.0), ), ), child: item.isServerFile ? CachedNetworkImage( placeholder: (context, url) => Icon(Icons.crop_original), imageUrl: item.pathFile ?? '', ) : Image.file(File(item.pathFile ?? '')), )), Positioned.fill( top: -(120.0 - 36), right: -(120.0 - 36), child: IconButton( icon: Icon( Icons.delete, color: Colors.redAccent, size: 24, ), onPressed: () { print("On tap delete media"); deleteImage(item); })) ], )); } } typedef ItemMediaCallback = void Function(Media item);