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