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.

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