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.

260 lines
9.2KB

  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/shimmer_image.dart';
  5. import 'package:farm_tpf/utils/const_color.dart';
  6. import 'package:farm_tpf/utils/const_string.dart';
  7. import 'package:file_picker/file_picker.dart';
  8. import 'package:flutter/cupertino.dart';
  9. import 'package:flutter/material.dart';
  10. import 'package:flutter_bloc/flutter_bloc.dart';
  11. import 'package:get/route_manager.dart';
  12. import 'package:path_provider/path_provider.dart';
  13. import 'package:thumbnails/thumbnails.dart';
  14. import 'package:video_player/video_player.dart';
  15. import 'bloc/media_helper_bloc.dart';
  16. import 'hoz_list_view.dart';
  17. class WidgetMediaPicker extends StatefulWidget {
  18. final Function(List<String> filePaths) onChangeFiles;
  19. WidgetMediaPicker({@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. 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: 4.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;
  107. Media newMedia = Media()
  108. ..isVideo = false
  109. ..isServerFile = false
  110. ..pathFile = filePath;
  111. currentItems.add(newMedia);
  112. files.add(filePath);
  113. BlocProvider.of<MediaHelperBloc>(context)
  114. ..add(ChangeListMedia(items: currentItems));
  115. widget.onChangeFiles(files);
  116. }
  117. });
  118. }),
  119. CupertinoDialogAction(
  120. child: const Text(label_select_image_from_library),
  121. onPressed: () async {
  122. Navigator.pop(context, 'Discard');
  123. FilePickerResult result =
  124. await FilePicker.platform.pickFiles(type: FileType.image);
  125. if (result != null) {
  126. String filePath = result.files.single.path;
  127. Media newMedia = Media()
  128. ..isVideo = false
  129. ..isServerFile = false
  130. ..pathFile = filePath;
  131. currentItems.add(newMedia);
  132. files.add(filePath);
  133. BlocProvider.of<MediaHelperBloc>(context)
  134. ..add(ChangeListMedia(items: currentItems));
  135. widget.onChangeFiles(files);
  136. }
  137. }),
  138. CupertinoDialogAction(
  139. child: const Text(label_select_video_from_library),
  140. onPressed: () async {
  141. Navigator.pop(context, 'Discard');
  142. FilePickerResult result =
  143. await FilePicker.platform.pickFiles(type: FileType.video);
  144. if (result != null) {
  145. //Get thumb video
  146. var appDocDir = await getApplicationDocumentsDirectory();
  147. final folderPath = appDocDir.path;
  148. String filePath = await Thumbnails.getThumbnail(
  149. thumbnailFolder: folderPath,
  150. videoFile: result.files.single.path,
  151. imageType: ThumbFormat
  152. .PNG, //this image will store in created folderpath
  153. quality: 30);
  154. Media newMedia = Media()
  155. ..isVideo = false
  156. ..isServerFile = false
  157. ..pathFile = filePath;
  158. currentItems.add(newMedia);
  159. files.add(filePath);
  160. BlocProvider.of<MediaHelperBloc>(context)
  161. ..add(ChangeListMedia(items: currentItems));
  162. widget.onChangeFiles(files);
  163. }
  164. }),
  165. CupertinoDialogAction(
  166. child: const Text(label_cancel),
  167. textStyle: TextStyle(fontWeight: FontWeight.bold),
  168. isDefaultAction: true,
  169. onPressed: () {
  170. Navigator.pop(context, 'Cancel');
  171. }),
  172. ],
  173. );
  174. }
  175. _buildListPoster() {
  176. return BlocBuilder<MediaHelperBloc, MediaHelperState>(
  177. builder: (context, state) {
  178. if (state is MediaHelperSuccess) {
  179. return WrapContentHozListView(
  180. itemBuilder: (context, index) {
  181. var item = state.items[index];
  182. return _WidgetItemMedia(
  183. item: item,
  184. deleteImage: (item) {
  185. files.remove(item.pathFile);
  186. currentItems.remove(item);
  187. widget.onChangeFiles(files);
  188. BlocProvider.of<MediaHelperBloc>(context)
  189. .add(ChangeListMedia(items: currentItems));
  190. });
  191. },
  192. separatorBuilder: (context, index) {
  193. return SizedBox(width: 14);
  194. },
  195. list: state.items,
  196. );
  197. }
  198. return Container();
  199. });
  200. }
  201. }
  202. class _WidgetItemMedia extends StatelessWidget {
  203. ItemMediaCallback deleteImage;
  204. final Media item;
  205. _WidgetItemMedia({@required this.item, @required this.deleteImage});
  206. BuildContext _context;
  207. @override
  208. Widget build(BuildContext context) {
  209. _context = context;
  210. VideoPlayerController _controller =
  211. VideoPlayerController.file(File(item.pathFile));
  212. _controller.play();
  213. return GestureDetector(
  214. onTap: () {
  215. print("Show preview image or video");
  216. },
  217. child: Stack(
  218. alignment: Alignment.bottomCenter,
  219. overflow: Overflow.visible,
  220. children: <Widget>[
  221. Positioned(
  222. child: ClipRRect(
  223. borderRadius: BorderRadius.circular(8),
  224. child: Image.file(File(item.pathFile), width: 100, height: 100),
  225. )),
  226. Positioned(
  227. top: -5,
  228. right: -5,
  229. child: IconButton(
  230. icon: Icon(
  231. Icons.cancel,
  232. color: Colors.redAccent,
  233. ),
  234. onPressed: () {
  235. print("On tap delete media");
  236. deleteImage(item);
  237. }),
  238. )
  239. ],
  240. ));
  241. }
  242. }
  243. typedef ItemMediaCallback = void Function(Media item);