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_color.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 'package:get/get.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 = new List(); List deleteFilePaths = new List(); @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.only(top: 8, bottom: 8), child: Column( children: [ SizedBox( width: double.infinity, height: 44, child: FlatButton( onPressed: () { showDialog( context: context, barrierDismissible: true, builder: (context) => Opacity( child: multipleChoice(contextB), opacity: 1, )); }, color: AppColors.DEFAULT, shape: RoundedRectangleBorder( borderRadius: new BorderRadius.circular(7.0), ), child: Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.image, color: Colors.white), SizedBox( width: 8.0, ), Text( button_add_media, style: TextStyle( fontWeight: FontWeight.bold, color: AppColors.WHITE), ) ], ), )), ), SizedBox( height: 8.0, ), Container( child: _buildListPoster(), ), ], )); } return Container(); })); } Widget multipleChoice(BuildContext context) { return CupertinoAlertDialog( title: Text(label_title_select_media), actions: [ CupertinoDialogAction( child: const Text(label_take_photo_or_video), 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(label_select_image_from_library), onPressed: () async { Navigator.pop(context, 'Discard'); FilePickerResult result = await FilePicker.platform .pickFiles(type: FileType.image, allowMultiple: true); if (result != null) { var listFuture = List>(); 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 GridView.count( physics: NeverScrollableScrollPhysics(), shrinkWrap: true, crossAxisCount: 4, children: currentItems.map( (item) { return _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)); }); }, ).toList()); } return Container(); }); } } class _WidgetItemMedia extends StatelessWidget { ItemMediaCallback deleteImage; final Media item; _WidgetItemMedia({@required this.item, @required this.deleteImage}); BuildContext _context; // screenSize/rowGridview - iconSize - (rowGridview-1)*marginContainer // Get.width/4 - 24 - 3*4 double positionIconDelete = -(Get.width / 4 - 36); @override Widget build(BuildContext context) { _context = context; return GestureDetector( onTap: () { print("Show preview image or video"); }, child: Stack( alignment: Alignment.topRight, overflow: Overflow.visible, children: [ Positioned.fill( child: item.isVideo ? 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: positionIconDelete, right: positionIconDelete, child: IconButton( icon: Icon( Icons.cancel, color: Colors.redAccent, size: 24, ), onPressed: () { print("On tap delete media"); deleteImage(item); }), ) ], )); } } typedef ItemMediaCallback = void Function(Media item);