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.

292 lines
11KB

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