|
- import 'dart:io';
- import 'dart:async';
-
- import 'package:farm_tpf/custom_model/Media.dart';
- import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
- import 'package:farm_tpf/presentation/custom_widgets/hoz_list_view.dart';
- import 'package:farm_tpf/presentation/custom_widgets/shimmer_image.dart';
- import 'package:farm_tpf/utils/const_color.dart';
- import 'package:farm_tpf/utils/const_string.dart';
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/foundation.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_bloc/flutter_bloc.dart';
- import 'package:get/get.dart';
- import 'package:get/state_manager.dart';
- import 'package:image_picker/image_picker.dart';
- import 'package:video_player/video_player.dart';
-
- class WidgetMediaHelper extends StatefulWidget {
- final Function(List<String> filePaths) onChangeFiles;
- WidgetMediaHelper({@required this.onChangeFiles});
- @override
- _WidgetMediaHelperState createState() => _WidgetMediaHelperState();
- }
-
- class _WidgetMediaHelperState extends State<WidgetMediaHelper> {
- final globalScaffoldKey = GlobalKey<ScaffoldState>();
- PickedFile _imageFile;
- dynamic _pickImageError;
- bool isVideo = false;
- VideoPlayerController _controller;
- VideoPlayerController _toBeDisposed;
- String _retrieveDataError;
-
- final ImagePicker _picker = ImagePicker();
- List<Media> currentItems = [];
- List<String> files = new List<String>();
- var changeImageController = Get.put(ChangeImageController());
- double imageWidth = 90;
- double imageHeight = 90;
-
- @override
- void initState() {
- super.initState();
- changeImageController.initValue();
- }
-
- @override
- Widget build(BuildContext context) {
- return BlocProvider<MediaHelperBloc>(
- create: (BuildContext contextA) =>
- MediaHelperBloc()..add(ChangeListMedia(items: currentItems)),
- child: BlocBuilder<MediaHelperBloc, MediaHelperState>(
- builder: (contextB, state) {
- if (state is MediaHelperFailure) {
- return Container();
- } else if (state is MediaHelperSuccess) {
- return Container(
- padding: EdgeInsets.all(8),
- child: Column(
- children: <Widget>[
- SizedBox(
- width: double.infinity,
- height: 44,
- child: FlatButton(
- onPressed: () {
- showDialog(
- context: context,
- barrierDismissible: true,
- builder: (context) => Opacity(
- child: multipleChoice(contextB),
- opacity: 1,
- ));
- },
- color: COLOR_CONST.DEFAULT,
- shape: RoundedRectangleBorder(
- borderRadius: new BorderRadius.circular(7.0),
- ),
- child: Center(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Icon(Icons.image, color: Colors.white),
- SizedBox(
- width: 8.0,
- ),
- Text(
- button_add_media,
- style: TextStyle(
- fontWeight: FontWeight.bold,
- color: COLOR_CONST.WHITE),
- )
- ],
- ),
- )),
- ),
- SizedBox(
- height: 4.0,
- ),
- Container(
- height: 150,
- child: _buildListPoster(),
- ),
- defaultTargetPlatform == TargetPlatform.android
- ? FutureBuilder<void>(
- future: retrieveLostData(context),
- builder: (BuildContext context,
- AsyncSnapshot<void> snapshot) {
- switch (snapshot.connectionState) {
- case ConnectionState.none:
- case ConnectionState.waiting:
- return const Text(
- 'You have not yet picked an image.',
- textAlign: TextAlign.center,
- );
- case ConnectionState.done:
- return isVideo
- ? _previewVideo()
- : _previewImage();
- default:
- if (snapshot.hasError) {
- return Text(
- 'Pick image/video error: ${snapshot.error}}',
- textAlign: TextAlign.center,
- );
- } else {
- return const Text(
- 'You have not yet picked an image.',
- textAlign: TextAlign.center,
- );
- }
- }
- },
- )
- : (isVideo ? _previewVideo() : _previewImage()),
- ],
- ));
- }
- return Container();
- }));
- }
-
- _buildListPoster() {
- return BlocBuilder<MediaHelperBloc, MediaHelperState>(
- builder: (context, state) {
- if (state is MediaHelperSuccess) {
- return WrapContentHozListView(
- itemBuilder: (context, index) {
- var item = state.items[index];
- return _WidgetItemMedia(
- item: item,
- deleteImage: (item) {
- files.remove(item.pathFile);
- currentItems.remove(item);
- widget.onChangeFiles(files);
- BlocProvider.of<MediaHelperBloc>(context)
- .add(ChangeListMedia(items: currentItems));
- });
- },
- separatorBuilder: (context, index) {
- return SizedBox(width: 14);
- },
- list: state.items,
- );
- }
- return Container();
- });
- }
-
- Widget multipleChoice(BuildContext context) {
- return CupertinoAlertDialog(
- title: Text(label_title_select_media),
- actions: <Widget>[
- CupertinoDialogAction(
- child: const Text(label_select_image_from_library),
- onPressed: () {
- Navigator.pop(context, 'Discard');
- isVideo = false;
- _onImageButtonPressed(ImageSource.gallery, context: context);
- }),
- CupertinoDialogAction(
- child: const Text(label_take_photo),
- onPressed: () {
- Navigator.pop(context, 'Discard');
- isVideo = false;
- _onImageButtonPressed(ImageSource.camera, context: context);
- }),
- CupertinoDialogAction(
- child: const Text(label_select_video_from_library),
- onPressed: () {
- Navigator.pop(context, 'Discard');
- isVideo = true;
- _onImageButtonPressed(ImageSource.gallery);
- }),
- CupertinoDialogAction(
- child: const Text(label_record_video),
- onPressed: () {
- Navigator.pop(context, 'Discard');
- isVideo = true;
- _onImageButtonPressed(ImageSource.camera);
- }),
- CupertinoDialogAction(
- child: const Text(label_cancel),
- textStyle: TextStyle(fontWeight: FontWeight.bold),
- isDefaultAction: true,
- onPressed: () {
- Navigator.pop(context, 'Cancel');
- }),
- ],
- );
- }
-
- Widget _actionButton() {
- return BlocListener<MediaHelperBloc, MediaHelperState>(
- listener: (context, state) {
- SizedBox(
- width: double.infinity,
- height: 44,
- child: FlatButton(
- onPressed: () {
- showDialog(
- context: context,
- barrierDismissible: true,
- builder: (context) => Opacity(
- child: Text(""),
- opacity: 1,
- ));
- },
- color: COLOR_CONST.DEFAULT,
- shape: RoundedRectangleBorder(
- borderRadius: new BorderRadius.circular(7.0),
- ),
- child: Center(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Icon(Icons.image, color: Colors.white),
- SizedBox(
- width: 8.0,
- ),
- Text(
- button_add_media,
- style: TextStyle(
- fontWeight: FontWeight.bold, color: COLOR_CONST.WHITE),
- )
- ],
- ),
- )),
- );
- });
- }
-
- Future<void> _playVideo(PickedFile file) async {
- if (file != null && mounted) {
- await _disposeVideoController();
- File f = File(file.path);
- _controller = VideoPlayerController.file(File(file.path));
- await _controller.setVolume(1.0);
- await _controller.initialize();
- await _controller.setLooping(false);
- await _controller.play();
- }
- }
-
- _onImageButtonPressed(ImageSource source, {BuildContext context}) async {
- if (_controller != null) {
- await _controller.setVolume(0.0);
- }
- if (isVideo) {
- // final video = await FilePicker.getFile(type: FileType.video);
- final PickedFile pickedFile = await _picker.getVideo(source: source);
- Get.find<ChangeImageController>().updateFile(pickedFile);
- Media newMedia = Media()
- ..isVideo = false
- ..isServerFile = false
- ..pathFile = pickedFile.path;
- currentItems.add(newMedia);
- print(pickedFile.path);
- files.add(pickedFile.path);
- _playVideo(pickedFile);
- // BlocProvider.of<MediaHelperBloc>(context)
- // ..add(ChangeListMedia(items: currentItems));
- // widget.onChangeFiles(files);
- } else {
- await _displayPickImageDialog(context,
- (double maxWidth, double maxHeight, int quality) async {
- try {
- final pickedFile = await _picker.getImage(
- source: source,
- maxWidth: imageWidth,
- maxHeight: imageHeight,
- imageQuality: quality,
- );
-
- Get.find<ChangeImageController>().updateFile(pickedFile);
- Media newMedia = Media()
- ..isVideo = false
- ..isServerFile = false
- ..pathFile = pickedFile.path;
- currentItems.add(newMedia);
- files.add(pickedFile.path);
- BlocProvider.of<MediaHelperBloc>(context)
- ..add(ChangeListMedia(items: currentItems));
- widget.onChangeFiles(files);
- } catch (e) {
- Get.find<ChangeImageController>().updateFileError(e);
- }
- });
- }
- ;
- }
-
- @override
- void deactivate() {
- if (_controller != null) {
- _controller.setVolume(0.0);
- _controller.pause();
- }
- super.deactivate();
- }
-
- @override
- void dispose() {
- _disposeVideoController();
- super.dispose();
- }
-
- Future<void> _disposeVideoController() async {
- if (_toBeDisposed != null) {
- await _toBeDisposed.dispose();
- }
- _toBeDisposed = _controller;
- _controller = null;
- }
-
- Widget _previewVideo() {
- final Text retrieveError = _getRetrieveErrorWidget();
- if (retrieveError != null) {
- return retrieveError;
- }
- if (_controller == null) {
- return const Text(
- 'You have not yet picked a video',
- textAlign: TextAlign.center,
- );
- }
- return Padding(
- padding: const EdgeInsets.all(10.0),
- child: AspectRatioVideo(_controller),
- );
- }
-
- Widget _previewImage() {
- return Builder(builder: (context) {
- final Text retrieveError = _getRetrieveErrorWidget();
- if (retrieveError != null) {
- return retrieveError;
- }
- if (_imageFile != null) {
- var imageResult =
- Image.file(File(_imageFile.path), width: imageWidth, height: 100);
- Media newMedia = Media()
- ..isVideo = false
- ..isServerFile = false
- ..pathFile = _imageFile.path;
- currentItems.add(newMedia);
- BlocProvider.of<MediaHelperBloc>(context)
- .add(ChangeListMedia(items: currentItems));
- //widget.onChangeFiles(files);
- return Container(
- child: Text("ok"),
- );
- } else if (_pickImageError != null) {
- return Text(
- 'Pick image error: $_pickImageError',
- textAlign: TextAlign.center,
- );
- } else {
- return const Text(
- 'You have not yet picked an image.',
- textAlign: TextAlign.center,
- );
- }
- });
- }
-
- Future<void> retrieveLostData(
- BuildContext context,
- ) async {
- final LostData response = await _picker.getLostData();
- if (response.isEmpty) {
- return;
- }
- if (response.file != null) {
- if (response.type == RetrieveType.video) {
- isVideo = true;
- await _playVideo(response.file);
- } else {
- isVideo = false;
- setState(() {
- _imageFile = response.file;
- });
- }
- } else {
- _retrieveDataError = response.exception.code;
- }
- }
-
- Text _getRetrieveErrorWidget() {
- if (_retrieveDataError != null) {
- final Text result = Text(_retrieveDataError);
- _retrieveDataError = null;
- return result;
- }
- return null;
- }
-
- Future<void> _displayPickImageDialog(
- BuildContext context, OnPickImageCallback onPick) async {
- onPick(null, null, null);
- }
- }
-
- typedef void OnPickImageCallback(
- double maxWidth, double maxHeight, int quality);
-
- class AspectRatioVideo extends StatefulWidget {
- AspectRatioVideo(this.controller);
-
- final VideoPlayerController controller;
-
- @override
- AspectRatioVideoState createState() => AspectRatioVideoState();
- }
-
- class AspectRatioVideoState extends State<AspectRatioVideo> {
- VideoPlayerController get controller => widget.controller;
- bool initialized = false;
-
- void _onVideoControllerUpdate() {
- if (!mounted) {
- return;
- }
- if (initialized != controller.value.initialized) {
- initialized = controller.value.initialized;
- setState(() {});
- }
- }
-
- @override
- void initState() {
- super.initState();
- controller.addListener(_onVideoControllerUpdate);
- }
-
- @override
- void dispose() {
- controller.removeListener(_onVideoControllerUpdate);
- super.dispose();
- }
-
- @override
- Widget build(BuildContext context) {
- if (initialized) {
- return Container(
- width: 100,
- height: 100,
- child: AspectRatio(
- aspectRatio: controller.value?.aspectRatio,
- child: VideoPlayer(controller),
- ),
- );
- } else {
- return Container();
- }
- }
- }
-
- class _WidgetItemMedia extends StatelessWidget {
- ItemMediaCallback deleteImage;
- final Media item;
-
- _WidgetItemMedia({@required this.item, @required this.deleteImage});
-
- BuildContext _context;
-
- @override
- Widget build(BuildContext context) {
- _context = context;
- return GestureDetector(
- onTap: () {
- print("Show preview image or video");
- },
- child: Stack(
- alignment: Alignment.bottomCenter,
- overflow: Overflow.visible,
- children: <Widget>[
- Positioned(
- child: ClipRRect(
- borderRadius: BorderRadius.circular(8),
- child: item.isServerFile
- ? ShimmerImage(
- item.pathFile,
- width: 93,
- height: 124,
- fit: BoxFit.cover,
- )
- : Image.file(File(item.pathFile), width: 100, height: 100),
- )),
- Positioned(
- top: -5,
- right: -5,
- child: IconButton(
- icon: Icon(
- Icons.cancel,
- color: Colors.redAccent,
- ),
- onPressed: () {
- print("On tap delete media");
- deleteImage(item);
- }),
- )
- ],
- ));
- }
- }
-
- typedef ItemMediaCallback = void Function(Media item);
-
- class ItemMediaVM {
- String photo;
- bool isVideo;
- Image image;
-
- ItemMediaVM(this.photo, this.isVideo, this.image);
- }
-
- class ChangeImageController extends GetxController {
- PickedFile _imageFile;
- dynamic _pickImageError;
- void initValue() {
- update();
- }
-
- void updateFile(PickedFile imageFile) {
- _imageFile = imageFile;
- update();
- }
-
- void updateFileError(dynamic pickImageError) {
- _pickImageError = pickImageError;
- update();
- }
- }
|