| import 'package:file_picker/file_picker.dart'; | import 'package:file_picker/file_picker.dart'; | ||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
| import 'package:get/get.dart'; | import 'package:get/get.dart'; | ||||
| import 'package:thumbnails/thumbnails.dart'; | |||||
| import 'package:video_player/video_player.dart'; | import 'package:video_player/video_player.dart'; | ||||
| import 'package:path_provider/path_provider.dart'; | import 'package:path_provider/path_provider.dart'; | ||||
| 'Đang mở camera ....', | 'Đang mở camera ....', | ||||
| style: TextStyle( | style: TextStyle( | ||||
| color: Colors.white, | color: Colors.white, | ||||
| fontSize: 20.0, | |||||
| fontSize: 18.0, | |||||
| fontWeight: FontWeight.w900, | fontWeight: FontWeight.w900, | ||||
| ), | ), | ||||
| ); | ); | ||||
| mainAxisAlignment: MainAxisAlignment.spaceEvenly, | mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||||
| mainAxisSize: MainAxisSize.max, | mainAxisSize: MainAxisSize.max, | ||||
| children: <Widget>[ | children: <Widget>[ | ||||
| IconButton( | |||||
| icon: Icon(Icons.video_library), | |||||
| onPressed: () async { | |||||
| FilePickerResult result = await FilePicker.platform | |||||
| .pickFiles(type: FileType.video, allowMultiple: true); | |||||
| if (result != null) { | |||||
| result.files.forEach((element) { | |||||
| print("----" + result.files.single.path); | |||||
| }); | |||||
| } | |||||
| }), | |||||
| IconButton( | |||||
| icon: Icon(Icons.image), | |||||
| onPressed: () async { | |||||
| FilePickerResult result = await FilePicker.platform | |||||
| .pickFiles(type: FileType.image, allowMultiple: true); | |||||
| if (result != null) { | |||||
| result.files.forEach((element) { | |||||
| print("----" + result.files.single.path); | |||||
| }); | |||||
| } | |||||
| }), | |||||
| IconButton( | IconButton( | ||||
| icon: Icon(Icons.arrow_back), | icon: Icon(Icons.arrow_back), | ||||
| onPressed: () { | onPressed: () { | ||||
| }), | }), | ||||
| _cameraTogglesRowWidget(), | _cameraTogglesRowWidget(), | ||||
| IconButton( | IconButton( | ||||
| icon: const Icon(Icons.camera_alt), | |||||
| icon: const Icon( | |||||
| Icons.camera_alt, | |||||
| size: 30, | |||||
| ), | |||||
| color: Colors.blue, | color: Colors.blue, | ||||
| onPressed: controller != null && | onPressed: controller != null && | ||||
| controller.value.isInitialized && | controller.value.isInitialized && | ||||
| : null, | : null, | ||||
| ), | ), | ||||
| IconButton( | IconButton( | ||||
| icon: const Icon(Icons.videocam), | |||||
| icon: const Icon(Icons.videocam, size: 35), | |||||
| color: Colors.blue, | color: Colors.blue, | ||||
| onPressed: controller != null && | onPressed: controller != null && | ||||
| controller.value.isInitialized && | controller.value.isInitialized && | ||||
| videoController?.dispose(); | videoController?.dispose(); | ||||
| videoController = null; | videoController = null; | ||||
| }); | }); | ||||
| if (filePath != null) print('Picture saved to $filePath'); | |||||
| if (filePath != null) { | |||||
| print('Picture saved to $filePath'); | |||||
| Get.back(result: filePath); | |||||
| } | |||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| void onVideoRecordButtonPressed() { | void onVideoRecordButtonPressed() { | ||||
| startVideoRecording().then((String filePath) { | startVideoRecording().then((String filePath) { | ||||
| if (mounted) setState(() {}); | if (mounted) setState(() {}); | ||||
| if (filePath != null) print('Saving video to $filePath'); | |||||
| if (filePath != null) { | |||||
| print('Saving video to $filePath'); | |||||
| } | |||||
| }); | }); | ||||
| } | } | ||||
| void onStopButtonPressed() { | void onStopButtonPressed() { | ||||
| stopVideoRecording().then((_) { | stopVideoRecording().then((_) { | ||||
| if (mounted) setState(() {}); | if (mounted) setState(() {}); | ||||
| print('Video recorded to: $videoPath'); | |||||
| { | |||||
| print('Video recorded to: $videoPath'); | |||||
| _getImage(videoPath); | |||||
| } | |||||
| }); | }); | ||||
| } | } | ||||
| _getImage(videoPathUrl) async { | |||||
| var appDocDir = await getApplicationDocumentsDirectory(); | |||||
| final folderPath = appDocDir.path; | |||||
| String thumb = await Thumbnails.getThumbnail( | |||||
| thumbnailFolder: folderPath, | |||||
| videoFile: videoPathUrl, | |||||
| imageType: | |||||
| ThumbFormat.PNG, //this image will store in created folderpath | |||||
| quality: 30); | |||||
| print("--thumb--" + thumb); | |||||
| Get.back(result: thumb); | |||||
| } | |||||
| void onPauseButtonPressed() { | void onPauseButtonPressed() { | ||||
| pauseVideoRecording().then((_) { | pauseVideoRecording().then((_) { | ||||
| if (mounted) setState(() {}); | if (mounted) setState(() {}); |
| 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); |
| import 'package:farm_tpf/data/repository/repository.dart'; | import 'package:farm_tpf/data/repository/repository.dart'; | ||||
| import 'package:farm_tpf/models/index.dart'; | import 'package:farm_tpf/models/index.dart'; | ||||
| import 'package:farm_tpf/presentation/custom_widgets/widget_media_helper.dart'; | import 'package:farm_tpf/presentation/custom_widgets/widget_media_helper.dart'; | ||||
| import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart'; | |||||
| import 'package:farm_tpf/presentation/screens/actions/nursery/bloc/expansion_list_bloc.dart'; | import 'package:farm_tpf/presentation/screens/actions/nursery/bloc/expansion_list_bloc.dart'; | ||||
| import 'package:farm_tpf/presentation/screens/resources/sc_resource_helper.dart'; | import 'package:farm_tpf/presentation/screens/resources/sc_resource_helper.dart'; | ||||
| import 'package:farm_tpf/utils/bloc/bloc/status_add_form_bloc.dart'; | import 'package:farm_tpf/utils/bloc/bloc/status_add_form_bloc.dart'; | ||||
| SizedBox( | SizedBox( | ||||
| height: 8.0, | height: 8.0, | ||||
| ), | ), | ||||
| WidgetMediaHelper(onChangeFiles: (filePaths) { | |||||
| WidgetMediaPicker(onChangeFiles: (filePaths) { | |||||
| Get.find<ChangeFileController>() | Get.find<ChangeFileController>() | ||||
| .addAllFile(filePaths); | .addAllFile(filePaths); | ||||
| // setState(() { | // setState(() { |
| import 'package:farm_tpf/data/repository/authentication_repository.dart'; | import 'package:farm_tpf/data/repository/authentication_repository.dart'; | ||||
| import 'package:farm_tpf/presentation/custom_widgets/camera_helper.dart'; | import 'package:farm_tpf/presentation/custom_widgets/camera_helper.dart'; | ||||
| import 'package:farm_tpf/presentation/screens/actions/nursery/sc_edit_action_nursery.dart'; | |||||
| import 'package:farm_tpf/presentation/screens/login/bloc/login_bloc.dart'; | import 'package:farm_tpf/presentation/screens/login/bloc/login_bloc.dart'; | ||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
| IconButton( | IconButton( | ||||
| icon: Icon(Icons.cake), | icon: Icon(Icons.cake), | ||||
| onPressed: () { | onPressed: () { | ||||
| Get.to(CameraHelper()); | |||||
| Get.to(EditActionNurseryScreen()); | |||||
| }) | }) | ||||
| ], | ], | ||||
| ), | ), |
| const String label_title_select_media = "Chọn hoạt động"; | const String label_title_select_media = "Chọn hoạt động"; | ||||
| const String button_add_media = "Thêm ảnh hoặc video"; | const String button_add_media = "Thêm ảnh hoặc video"; | ||||
| const String label_select_image_from_library = "Chọn ảnh từ thư viện"; | |||||
| const String label_select_image_from_library = "Chọn ảnh"; | |||||
| const String label_take_photo = "Chụp ảnh"; | const String label_take_photo = "Chụp ảnh"; | ||||
| const String label_select_video_from_library = "Chọn video từ thư viện"; | |||||
| const String label_select_video_from_library = "Chọn video"; | |||||
| const String label_record_video = "Quay video"; | const String label_record_video = "Quay video"; | ||||
| const String label_take_photo_or_video = "Chụp ảnh hoặc quay video"; | |||||
| const String label_cancel = "Huỷ"; | const String label_cancel = "Huỷ"; | ||||
| const String label_list_empty = "Dữ liệu rỗng"; | const String label_list_empty = "Dữ liệu rỗng"; |
| url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
| source: hosted | source: hosted | ||||
| version: "0.2.17" | version: "0.2.17" | ||||
| thumbnails: | |||||
| dependency: "direct main" | |||||
| description: | |||||
| name: thumbnails | |||||
| url: "https://pub.dartlang.org" | |||||
| source: hosted | |||||
| version: "1.0.1" | |||||
| timing: | timing: | ||||
| dependency: transitive | dependency: transitive | ||||
| description: | description: |
| camera: ^0.5.8+5 | camera: ^0.5.8+5 | ||||
| path_provider: ^1.6.14 | path_provider: ^1.6.14 | ||||
| file_picker: ^2.0.0 | file_picker: ^2.0.0 | ||||
| thumbnails: ^1.0.1 | |||||
| dev_dependencies: | dev_dependencies: | ||||
| flutter_test: | flutter_test: |