import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:image_picker/image_picker.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import '../../../new_views/common_widgets/app_dashed_button.dart'; import 'multi_image_picker_item.dart'; // class MultiFilesPicker extends StatefulWidget { // final String label; // final bool error; // final List files; // final List attachment; // // final bool enabled, onlyImages; // double? buttonHeight; // Widget? buttonIcon; // Color? buttonColor; // final Function(List)? onChange; // final bool showAsGrid; // // MultiFilesPicker( // {Key? key, // this.files = const [], // this.attachment = const [], // required this.label, // this.error = false, // this.buttonHeight, // this.buttonIcon, // this.enabled = true, // this.onlyImages = false, // this.onChange, // this.showAsGrid = false, // this.buttonColor}) // : super(key: key); // // @override // State createState() => _MultiFilesPickerState(); // } // // class _MultiFilesPickerState extends State { // @override // Widget build(BuildContext context) { // return Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // if (widget.enabled) ...[ // AppDashedButton( // title: widget.label, // height: widget.buttonHeight, // buttonColor: widget.buttonColor, // icon: widget.buttonIcon, // onPressed: (widget.enabled == false) // ? () {} // : widget.showAsGrid // ? showFileSourceSheet // : onFilePicker), // 16.height, // ], // if (widget.files.isNotEmpty) // Wrap( // spacing: 8.toScreenWidth, // children: List.generate( // widget.files!.length, // (index) { // File image = widget.files![index]; // return MultiFilesPickerItem( // file: image, // enabled: widget.enabled, // onRemoveTap: (image) { // if (!widget.enabled) { // return; // } // widget.files.remove(image); // if (widget.onChange != null) { // widget.onChange!(widget.files); // } // setState(() {}); // }, // ); // }, // ), // ), // ], // ); // } // // fromFilePicker() async { // FilePickerResult? result = await FilePicker.platform.pickFiles( // type: FileType.custom, // allowMultiple: true, // allowedExtensions: widget.onlyImages ? ['jpg', 'jpeg', 'png'] : ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xlsx', 'pptx'], // ); // if (result != null) { // for (var path in result.paths) { // widget.files.add(File(path!)); // if (widget.onChange != null) { // widget.onChange!(widget.files); // } // } // setState(() {}); // } // } // // void showFileSourceSheet() async { // if (widget.files.length >= 5) { // Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5); // return; // } // // ImageSource? source = (await showModalBottomSheet( // context: context, // shape: const RoundedRectangleBorder( // borderRadius: BorderRadius.vertical( // top: Radius.circular(20), // ), // ), // clipBehavior: Clip.antiAliasWithSaveLayer, // builder: (BuildContext context) => Column( // mainAxisSize: MainAxisSize.min, // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // "Attach File".heading4(context), // 12.height, // GridView( // padding: const EdgeInsets.all(0), // shrinkWrap: true, // physics: const NeverScrollableScrollPhysics(), // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1, crossAxisSpacing: 12, mainAxisSpacing: 12), // children: [ // gridItem(Icons.camera_enhance_rounded, context.translation.pickFromCamera).onPress(() => Navigator.of(context).pop(ImageSource.camera)), // gridItem(Icons.image_rounded, context.translation.pickFromGallery).onPress(() => Navigator.of(context).pop(ImageSource.gallery)), // gridItem(Icons.file_present_rounded, context.translation.pickFromFiles).onPress(() async { // await fromFilePicker(); // Navigator.pop(context); // }), // ], // ), // 12.height, // ], // ).paddingAll(21), // )) as ImageSource?; // if (source == null) return; // final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 70, maxWidth: 800, maxHeight: 800); // // if (pickedFile != null) { // File fileImage = File(pickedFile.path); // widget.files.add(fileImage); // if (widget.onChange != null) { // widget.onChange!(widget.files); // } // setState(() {}); // } // } // // Widget gridItem(IconData iconData, String title) { // return Container( // padding: const EdgeInsets.all(12), // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.circular(12), // border: Border.all(color: const Color(0xffF1F1F1), width: 1), // ), // child: Column( // crossAxisAlignment: CrossAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // Icon(iconData, color: const Color(0xff7D859A), size: 36), // Text( // title, // style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), // ), // ], // ), // ); // } // // onFilePicker() async { // if (widget.files.length >= 5) { // Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5); // return; // } // ImageSource? source = await showModalBottomSheet( // context: context, // builder: (BuildContext context) { // Widget listCard({required String icon, required String label, required VoidCallback onTap}) { // return GestureDetector( // onTap: onTap, // child: Container( // constraints: BoxConstraints(minWidth: 111.toScreenWidth, minHeight: 111.toScreenHeight), // padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth, vertical: 12.toScreenHeight), // decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), border: Border.all(width: 1, color: AppColor.white70)), // child: Column( // mainAxisSize: MainAxisSize.min, // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // icon.toSvgAsset(), // 24.height, // label.bodyText2(context).custom(color: AppColor.black20), // ], // ), // ), // ); // } // // return Container( // padding: const EdgeInsets.all(16.0), // child: Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // listCard( // icon: 'camera_icon', // label: '${context.translation.open}\n${context.translation.camera}', // onTap: () { // Navigator.of(context).pop(ImageSource.camera); // }, // ), // listCard( // icon: 'gallery_icon', // label: '${context.translation.open}\n${context.translation.gallery}', // onTap: () { // Navigator.of(context).pop(ImageSource.gallery); // }, // ), // listCard( // icon: 'file_icon', // label: '${context.translation.open}\n${context.translation.files}', // onTap: () async { // await fromFilePicker(); // Navigator.pop(context); // }, // ), // ], // ), // ); // }, // ); // // ImageSource source = await showDialog( // // context: context, // // builder: (dialogContext) => CupertinoAlertDialog( // // actions: [ // // TextButton( // // child: Text(context.translation.pickFromCamera), // // onPressed: () { // // Navigator.of(dialogContext).pop(ImageSource.camera); // // }, // // ), // // TextButton( // // child: Text(context.translation.pickFromGallery), // // onPressed: () { // // Navigator.of(dialogContext).pop(ImageSource.gallery); // // }, // // ), // // TextButton( // // child: Text(context.translation.pickFromFiles), // // onPressed: () async { // // await fromFilePicker(); // // Navigator.pop(context); // // }, // // ), // // ], // // ), // // ); // if (source == null) return; // // final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 70, maxWidth: 800, maxHeight: 800); // // if (pickedFile != null) { // File fileImage = File(pickedFile.path); // if (fileImage != null) { // widget.files.add(fileImage); // if (widget.onChange != null) { // widget.onChange!(widget.files); // } // setState(() {}); // } // } // // setState(() {}); // } // } class AttachmentModel { int id = 0; File? file; AttachmentModel(this.id, this.file); factory AttachmentModel.fromJson(Map json) { return AttachmentModel( json['id'] ?? 0, json['file'] != null ? File(json['file']) : null, ); } Map toJson() { return { 'id': id, 'file': file?.path, }; } } class AttachmentPicker extends StatefulWidget { final String label; final bool error; final List attachment; final bool enabled, onlyImages; double? buttonHeight; Widget? buttonIcon; Color? buttonColor; final Function(List)? onChange; final bool showAsGrid; AttachmentPicker( {Key? key, this.attachment = const [], required this.label, this.error = false, this.buttonHeight, this.buttonIcon, this.enabled = true, this.onlyImages = false, this.onChange, this.showAsGrid = false, this.buttonColor}) : super(key: key); @override State createState() => _AttachmentPickerState(); } class _AttachmentPickerState extends State { @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AppDashedButton( title: widget.label, height: widget.buttonHeight, buttonColor: widget.buttonColor, icon: widget.buttonIcon, onPressed: (widget.enabled == false) ? () {} : widget.showAsGrid ? showFileSourceSheet : onFilePicker), 16.height, if (widget.attachment.isNotEmpty) Wrap( spacing: 8.toScreenWidth, children: List.generate( widget.attachment.length, (index) { File image = File(widget.attachment[index].name!); return MultiFilesPickerItem( file: image, enabled: widget.enabled, onRemoveTap: (image) { if (!widget.enabled) { return; } widget.attachment.removeAt(index); if (widget.onChange != null) { widget.onChange!(widget.attachment); } setState(() {}); }, ); }, ), ), ], ); } fromFilePicker() async { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowMultiple: true, allowedExtensions: widget.onlyImages ? ['jpg', 'jpeg', 'png'] : ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xlsx', 'pptx'], ); if (result != null) { for (var path in result.paths) { widget.attachment.add(GenericAttachmentModel(id: 0, name: File(path!).path)); } if (widget.onChange != null) { widget.onChange!(widget.attachment); } setState(() {}); } } void showFileSourceSheet() async { // if (widget.attachment.length >= 5) { // Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5); // return; // } ImageSource source = (await showModalBottomSheet( context: context, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( top: Radius.circular(20), ), ), clipBehavior: Clip.antiAliasWithSaveLayer, builder: (BuildContext context) => Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ "Attach File".heading4(context), 12.height, GridView( padding: const EdgeInsets.all(0), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1, crossAxisSpacing: 12, mainAxisSpacing: 12), children: [ gridItem(Icons.camera_enhance_rounded, context.translation.pickFromCamera).onPress(() => Navigator.of(context).pop(ImageSource.camera)), gridItem(Icons.image_rounded, context.translation.pickFromGallery).onPress(() => Navigator.of(context).pop(ImageSource.gallery)), gridItem(Icons.file_present_rounded, context.translation.pickFromFiles).onPress(() async { await fromFilePicker(); Navigator.pop(context); }), ], ), 12.height, ], ).paddingAll(21), )) as ImageSource; final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 70, maxWidth: 800, maxHeight: 800); if (pickedFile != null) { File fileImage = File(pickedFile.path); widget.attachment.add(GenericAttachmentModel(id: 0, name: fileImage.path)); if (widget.onChange != null) { widget.onChange!(widget.attachment); } setState(() {}); } } Widget gridItem(IconData iconData, String title) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: const Color(0xffF1F1F1), width: 1), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Icon(iconData, color: const Color(0xff7D859A), size: 36), Text( title, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), ), ], ), ); } onFilePicker() async { //TODO removed on request by Backend as they don't have anyissue with large number of files // if (widget.attachment.length >= 5) { // Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5); // return; // } ImageSource? source = await showModalBottomSheet( context: context, builder: (BuildContext context) { Widget listCard({required String icon, required String label, required VoidCallback onTap}) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColor.background(context), // color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: const Color(0xffF1F1F1), width: 1), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ icon.toSvgAsset(color: AppColor.iconColor(context), width: 36, height: 36), // Icon(iconData, color: const Color(0xff7D859A), size: 36), Text( label, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), ), ], ), ).onPress(onTap); } return SafeArea( top: false, child: Container( width: double.infinity, color: AppColor.background(context), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ "Attach File".heading4(context), 12.height, GridView( padding: const EdgeInsets.all(0), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1, crossAxisSpacing: 12, mainAxisSpacing: 12), children: [ listCard( icon: 'camera_icon', label: '${context.translation.open}\n${context.translation.camera}', onTap: () { Navigator.of(context).pop(ImageSource.camera); }, ), listCard( icon: 'gallery_icon', label: '${context.translation.open}\n${context.translation.gallery}', onTap: () { Navigator.of(context).pop(ImageSource.gallery); }, ), listCard( icon: 'file_icon', label: '${context.translation.open}\n${context.translation.files}', onTap: () async { await fromFilePicker(); Navigator.pop(context); }, ), ], ), // Container( // padding: const EdgeInsets.all(16.0), // child: Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // listCard( // icon: 'camera_icon', // label: '${context.translation.open}\n${context.translation.camera}', // onTap: () { // Navigator.of(context).pop(ImageSource.camera); // }, // ), // listCard( // icon: 'gallery_icon', // label: '${context.translation.open}\n${context.translation.gallery}', // onTap: () { // Navigator.of(context).pop(ImageSource.gallery); // }, // ), // listCard( // icon: 'file_icon', // label: '${context.translation.open}\n${context.translation.files}', // onTap: () async { // await fromFilePicker(); // Navigator.pop(context); // }, // ), // ], // ), // ), ], ).paddingAll(16), ), ); }, ); // ImageSource source = await showDialog( // context: context, // builder: (dialogContext) => CupertinoAlertDialog( // actions: [ // TextButton( // child: Text(context.translation.pickFromCamera), // onPressed: () { // Navigator.of(dialogContext).pop(ImageSource.camera); // }, // ), // TextButton( // child: Text(context.translation.pickFromGallery), // onPressed: () { // Navigator.of(dialogContext).pop(ImageSource.gallery); // }, // ), // TextButton( // child: Text(context.translation.pickFromFiles), // onPressed: () async { // await fromFilePicker(); // Navigator.pop(context); // }, // ), // ], // ), // ); if (source == null) return; final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 70, maxWidth: 800, maxHeight: 800); if (pickedFile != null) { File fileImage = File(pickedFile.path); widget.attachment.add(GenericAttachmentModel(id: 0, name: fileImage.path)); if (widget.onChange != null) { widget.onChange!(widget.attachment); } setState(() {}); } setState(() {}); } }