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.

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