You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
11KB

  1. import 'dart:io';
  2. import 'package:cached_network_image/cached_network_image.dart';
  3. import 'package:farm_tpf/custom_model/Media.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/camera_helper.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/widget_show_video.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  7. import 'package:farm_tpf/presentation/screens/actions/util_action.dart';
  8. import 'package:farm_tpf/utils/const_color.dart';
  9. import 'package:farm_tpf/utils/const_common.dart';
  10. import 'package:farm_tpf/utils/const_string.dart';
  11. import 'package:file_picker/file_picker.dart';
  12. import 'package:flutter/cupertino.dart';
  13. import 'package:flutter/material.dart';
  14. import 'package:flutter_bloc/flutter_bloc.dart';
  15. import 'bloc/media_helper_bloc.dart';
  16. import 'hoz_list_view.dart';
  17. class WidgetMediaPicker extends StatefulWidget {
  18. final List<Media> currentItems;
  19. final Function(List<String> addNewFilePaths, List<String> deleteFilePaths)
  20. onChangeFiles;
  21. WidgetMediaPicker({this.currentItems, @required this.onChangeFiles});
  22. @override
  23. _WidgetMediaPickerState createState() => _WidgetMediaPickerState();
  24. }
  25. class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
  26. List<Media> currentItems = [];
  27. List<String> addNewFilePaths = new List<String>();
  28. List<String> deleteFilePaths = new List<String>();
  29. @override
  30. void initState() {
  31. super.initState();
  32. }
  33. @override
  34. Widget build(BuildContext context) {
  35. return BlocProvider<MediaHelperBloc>(
  36. create: (BuildContext contextA) =>
  37. MediaHelperBloc()..add(ChangeListMedia(items: currentItems)),
  38. child: BlocBuilder<MediaHelperBloc, MediaHelperState>(
  39. builder: (contextB, state) {
  40. if (state is MediaHelperFailure) {
  41. return Container();
  42. } else if (state is MediaHelperSuccess) {
  43. currentItems = widget.currentItems ?? [];
  44. return Container(
  45. padding: EdgeInsets.only(top: 8, bottom: 8),
  46. child: Column(
  47. children: <Widget>[
  48. SizedBox(
  49. width: double.infinity,
  50. height: 44,
  51. child: FlatButton(
  52. onPressed: () {
  53. showDialog(
  54. context: context,
  55. barrierDismissible: true,
  56. builder: (context) => Opacity(
  57. child: multipleChoice(contextB),
  58. opacity: 1,
  59. ));
  60. },
  61. color: COLOR_CONST.DEFAULT,
  62. shape: RoundedRectangleBorder(
  63. borderRadius: new BorderRadius.circular(7.0),
  64. ),
  65. child: Center(
  66. child: Row(
  67. mainAxisAlignment: MainAxisAlignment.center,
  68. children: <Widget>[
  69. Icon(Icons.image, color: Colors.white),
  70. SizedBox(
  71. width: 8.0,
  72. ),
  73. Text(
  74. button_add_media,
  75. style: TextStyle(
  76. fontWeight: FontWeight.bold,
  77. color: COLOR_CONST.WHITE),
  78. )
  79. ],
  80. ),
  81. )),
  82. ),
  83. SizedBox(
  84. height: 8.0,
  85. ),
  86. Container(
  87. child: _buildListPoster(),
  88. ),
  89. ],
  90. ));
  91. }
  92. return Container();
  93. }));
  94. }
  95. Widget multipleChoice(BuildContext context) {
  96. return CupertinoAlertDialog(
  97. title: Text(label_title_select_media),
  98. actions: <Widget>[
  99. CupertinoDialogAction(
  100. child: const Text(label_take_photo_or_video),
  101. onPressed: () {
  102. Navigator.pop(context, 'Discard');
  103. Navigator.of(context)
  104. .push(MaterialPageRoute(builder: (context) => CameraHelper()))
  105. .then((value) {
  106. if (value != null) {
  107. print("ok");
  108. print(value);
  109. String filePath = value[0];
  110. File f = File(filePath);
  111. f.length().then((lengthFileInBytes) {
  112. if (lengthFileInBytes > ConstCommon.kFileSize) {
  113. Utils.showSnackBarWarning(message: label_file_to_large);
  114. } else {
  115. bool isVideo = value[1];
  116. Media newMedia = Media()
  117. ..isVideo = isVideo
  118. ..isServerFile = false
  119. ..pathFile = filePath;
  120. currentItems.add(newMedia);
  121. addNewFilePaths.add(filePath);
  122. BlocProvider.of<MediaHelperBloc>(context)
  123. ..add(ChangeListMedia(items: currentItems));
  124. widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
  125. }
  126. });
  127. }
  128. });
  129. }),
  130. CupertinoDialogAction(
  131. child: const Text(label_select_image_from_library),
  132. onPressed: () async {
  133. Navigator.pop(context, 'Discard');
  134. FilePickerResult result =
  135. await FilePicker.platform.pickFiles(type: FileType.image);
  136. if (result != null) {
  137. UtilAction.compressImage(File(result.files.single.path))
  138. .then((compressFile) async {
  139. var lengthFileInBytes = await compressFile.length();
  140. if (lengthFileInBytes > ConstCommon.kFileSize) {
  141. Utils.showSnackBarWarning(message: label_file_to_large);
  142. } else {
  143. Media newMedia = Media()
  144. ..isVideo = false
  145. ..isServerFile = false
  146. ..pathFile = compressFile.path;
  147. currentItems.add(newMedia);
  148. addNewFilePaths.add(compressFile.path);
  149. BlocProvider.of<MediaHelperBloc>(context)
  150. ..add(ChangeListMedia(items: currentItems));
  151. widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
  152. }
  153. });
  154. }
  155. }),
  156. CupertinoDialogAction(
  157. child: const Text(label_select_video_from_library),
  158. onPressed: () async {
  159. Navigator.pop(context, 'Discard');
  160. FilePickerResult result =
  161. await FilePicker.platform.pickFiles(type: FileType.video);
  162. if (result != null) {
  163. String filePath = result.files.single.path;
  164. var lengthFileInBytes = result.files.single.size * 1000;
  165. if (lengthFileInBytes > ConstCommon.kFileSize) {
  166. Utils.showSnackBarWarning(message: label_file_to_large);
  167. } else {
  168. Media newMedia = Media()
  169. ..isVideo = true
  170. ..isServerFile = false
  171. ..pathFile = filePath;
  172. currentItems.add(newMedia);
  173. addNewFilePaths.add(filePath);
  174. BlocProvider.of<MediaHelperBloc>(context)
  175. ..add(ChangeListMedia(items: currentItems));
  176. widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
  177. }
  178. }
  179. }),
  180. CupertinoDialogAction(
  181. child: const Text(label_cancel),
  182. textStyle: TextStyle(fontWeight: FontWeight.bold),
  183. isDefaultAction: true,
  184. onPressed: () {
  185. Navigator.pop(context, 'Cancel');
  186. }),
  187. ],
  188. );
  189. }
  190. _buildListPoster() {
  191. return BlocBuilder<MediaHelperBloc, MediaHelperState>(
  192. builder: (context, state) {
  193. if (state is MediaHelperSuccess) {
  194. return WrapContentHozListView(
  195. itemBuilder: (context, index) {
  196. var item = currentItems[index];
  197. return _WidgetItemMedia(
  198. item: item,
  199. deleteImage: (item) {
  200. if (item.isServerFile) {
  201. var url =
  202. item.pathFile.replaceAll(ConstCommon.baseImageUrl, '');
  203. deleteFilePaths.add(url);
  204. }
  205. currentItems.remove(item);
  206. widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
  207. BlocProvider.of<MediaHelperBloc>(context)
  208. .add(ChangeListMedia(items: currentItems));
  209. });
  210. },
  211. separatorBuilder: (context, index) {
  212. return SizedBox(width: 4);
  213. },
  214. list: currentItems,
  215. );
  216. }
  217. return Container();
  218. });
  219. }
  220. }
  221. class _WidgetItemMedia extends StatelessWidget {
  222. ItemMediaCallback deleteImage;
  223. final Media item;
  224. _WidgetItemMedia({@required this.item, @required this.deleteImage});
  225. BuildContext _context;
  226. @override
  227. Widget build(BuildContext context) {
  228. _context = context;
  229. return GestureDetector(
  230. onTap: () {
  231. print("Show preview image or video");
  232. },
  233. child: Stack(
  234. alignment: Alignment.bottomCenter,
  235. overflow: Overflow.visible,
  236. children: <Widget>[
  237. Positioned(
  238. child: item.isVideo
  239. ? VideoWidget(
  240. pathFile: item.pathFile,
  241. isServerFile: item.isServerFile,
  242. play: false,
  243. )
  244. : Container(
  245. width: 100,
  246. height: 100,
  247. decoration: BoxDecoration(
  248. color: Colors.white,
  249. border: Border.all(color: Colors.grey),
  250. borderRadius:
  251. BorderRadius.all(Radius.circular(8.0))),
  252. child: item.isServerFile
  253. ? CachedNetworkImage(
  254. placeholder: (context, url) =>
  255. Icon(Icons.crop_original),
  256. imageUrl: item.pathFile)
  257. : Image.file(File(item.pathFile),
  258. width: 100, height: 100),
  259. )),
  260. Positioned(
  261. top: -14,
  262. right: -14,
  263. child: IconButton(
  264. icon: Icon(
  265. Icons.cancel,
  266. color: Colors.redAccent,
  267. size: 24,
  268. ),
  269. onPressed: () {
  270. print("On tap delete media");
  271. deleteImage(item);
  272. }),
  273. )
  274. ],
  275. ));
  276. }
  277. }
  278. typedef ItemMediaCallback = void Function(Media item);