|
|
|
@@ -0,0 +1,259 @@ |
|
|
|
import 'dart:io'; |
|
|
|
|
|
|
|
import 'package:farm_tpf/custom_model/Media.dart'; |
|
|
|
import 'package:farm_tpf/presentation/custom_widgets/camera_helper.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:file_picker/file_picker.dart'; |
|
|
|
import 'package:flutter/cupertino.dart'; |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart'; |
|
|
|
import 'package:get/route_manager.dart'; |
|
|
|
import 'package:path_provider/path_provider.dart'; |
|
|
|
import 'package:thumbnails/thumbnails.dart'; |
|
|
|
import 'package:video_player/video_player.dart'; |
|
|
|
|
|
|
|
import 'bloc/media_helper_bloc.dart'; |
|
|
|
import 'hoz_list_view.dart'; |
|
|
|
|
|
|
|
class WidgetMediaPicker extends StatefulWidget { |
|
|
|
final Function(List<String> filePaths) onChangeFiles; |
|
|
|
WidgetMediaPicker({@required this.onChangeFiles}); |
|
|
|
@override |
|
|
|
_WidgetMediaPickerState createState() => _WidgetMediaPickerState(); |
|
|
|
} |
|
|
|
|
|
|
|
class _WidgetMediaPickerState extends State<WidgetMediaPicker> { |
|
|
|
List<Media> currentItems = []; |
|
|
|
List<String> files = new List<String>(); |
|
|
|
|
|
|
|
@override |
|
|
|
void initState() { |
|
|
|
super.initState(); |
|
|
|
} |
|
|
|
|
|
|
|
@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(), |
|
|
|
), |
|
|
|
], |
|
|
|
)); |
|
|
|
} |
|
|
|
return Container(); |
|
|
|
})); |
|
|
|
} |
|
|
|
|
|
|
|
Widget multipleChoice(BuildContext context) { |
|
|
|
return CupertinoAlertDialog( |
|
|
|
title: Text(label_title_select_media), |
|
|
|
actions: <Widget>[ |
|
|
|
CupertinoDialogAction( |
|
|
|
child: const Text(label_take_photo_or_video), |
|
|
|
onPressed: () { |
|
|
|
Navigator.pop(context, 'Discard'); |
|
|
|
Navigator.of(context) |
|
|
|
.push(MaterialPageRoute(builder: (context) => CameraHelper())) |
|
|
|
.then((value) { |
|
|
|
if (value != null) { |
|
|
|
print("ok"); |
|
|
|
print(value); |
|
|
|
String filePath = value; |
|
|
|
Media newMedia = Media() |
|
|
|
..isVideo = false |
|
|
|
..isServerFile = false |
|
|
|
..pathFile = filePath; |
|
|
|
currentItems.add(newMedia); |
|
|
|
files.add(filePath); |
|
|
|
BlocProvider.of<MediaHelperBloc>(context) |
|
|
|
..add(ChangeListMedia(items: currentItems)); |
|
|
|
widget.onChangeFiles(files); |
|
|
|
} |
|
|
|
}); |
|
|
|
}), |
|
|
|
CupertinoDialogAction( |
|
|
|
child: const Text(label_select_image_from_library), |
|
|
|
onPressed: () async { |
|
|
|
Navigator.pop(context, 'Discard'); |
|
|
|
FilePickerResult result = |
|
|
|
await FilePicker.platform.pickFiles(type: FileType.image); |
|
|
|
|
|
|
|
if (result != null) { |
|
|
|
String filePath = result.files.single.path; |
|
|
|
Media newMedia = Media() |
|
|
|
..isVideo = false |
|
|
|
..isServerFile = false |
|
|
|
..pathFile = filePath; |
|
|
|
currentItems.add(newMedia); |
|
|
|
files.add(filePath); |
|
|
|
BlocProvider.of<MediaHelperBloc>(context) |
|
|
|
..add(ChangeListMedia(items: currentItems)); |
|
|
|
widget.onChangeFiles(files); |
|
|
|
} |
|
|
|
}), |
|
|
|
CupertinoDialogAction( |
|
|
|
child: const Text(label_select_video_from_library), |
|
|
|
onPressed: () async { |
|
|
|
Navigator.pop(context, 'Discard'); |
|
|
|
FilePickerResult result = |
|
|
|
await FilePicker.platform.pickFiles(type: FileType.video); |
|
|
|
|
|
|
|
if (result != null) { |
|
|
|
//Get thumb video |
|
|
|
var appDocDir = await getApplicationDocumentsDirectory(); |
|
|
|
final folderPath = appDocDir.path; |
|
|
|
String filePath = await Thumbnails.getThumbnail( |
|
|
|
thumbnailFolder: folderPath, |
|
|
|
videoFile: result.files.single.path, |
|
|
|
imageType: ThumbFormat |
|
|
|
.PNG, //this image will store in created folderpath |
|
|
|
quality: 30); |
|
|
|
|
|
|
|
Media newMedia = Media() |
|
|
|
..isVideo = false |
|
|
|
..isServerFile = false |
|
|
|
..pathFile = filePath; |
|
|
|
currentItems.add(newMedia); |
|
|
|
files.add(filePath); |
|
|
|
BlocProvider.of<MediaHelperBloc>(context) |
|
|
|
..add(ChangeListMedia(items: currentItems)); |
|
|
|
widget.onChangeFiles(files); |
|
|
|
} |
|
|
|
}), |
|
|
|
CupertinoDialogAction( |
|
|
|
child: const Text(label_cancel), |
|
|
|
textStyle: TextStyle(fontWeight: FontWeight.bold), |
|
|
|
isDefaultAction: true, |
|
|
|
onPressed: () { |
|
|
|
Navigator.pop(context, 'Cancel'); |
|
|
|
}), |
|
|
|
], |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
_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(); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
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; |
|
|
|
VideoPlayerController _controller = |
|
|
|
VideoPlayerController.file(File(item.pathFile)); |
|
|
|
_controller.play(); |
|
|
|
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: 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); |