diff --git a/.flutter-plugins b/.flutter-plugins index b01711a..a39a755 100644 --- a/.flutter-plugins +++ b/.flutter-plugins @@ -1,22 +1,23 @@ # This is a generated file; do not edit or check into version control. -flutter_plugin_android_lifecycle=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-2.0.7/ -flutter_sound=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/flutter_sound-9.2.13/ -flutter_sound_web=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/flutter_sound_web-9.2.13/ -image_picker=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.8.6/ -image_picker_android=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/image_picker_android-0.8.5+3/ -image_picker_for_web=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/image_picker_for_web-2.1.10/ -image_picker_ios=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/image_picker_ios-0.8.6+1/ -path_provider=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/ -path_provider_android=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.20/ -path_provider_ios=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/ -path_provider_linux=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/ -path_provider_macos=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/ -path_provider_windows=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/ -permission_handler=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/permission_handler-10.2.0/ -permission_handler_android=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/permission_handler_android-10.2.0/ -permission_handler_apple=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/permission_handler_apple-9.0.7/ -permission_handler_windows=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/permission_handler_windows-0.1.2/ -video_player=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/video_player-2.4.7/ -video_player_android=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/video_player_android-2.3.9/ -video_player_avfoundation=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/video_player_avfoundation-2.3.7/ -video_player_web=/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/video_player_web-2.0.12/ +file_picker=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\file_picker-5.2.4\\ +flutter_plugin_android_lifecycle=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\flutter_plugin_android_lifecycle-2.0.7\\ +flutter_sound=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\flutter_sound-9.2.13\\ +flutter_sound_web=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\flutter_sound_web-9.2.13\\ +image_picker=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\image_picker-0.8.6\\ +image_picker_android=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\image_picker_android-0.8.5+4\\ +image_picker_for_web=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\image_picker_for_web-2.1.10\\ +image_picker_ios=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\image_picker_ios-0.8.6+2\\ +path_provider=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider-2.0.11\\ +path_provider_android=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider_android-2.0.22\\ +path_provider_ios=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider_ios-2.0.11\\ +path_provider_linux=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider_linux-2.1.7\\ +path_provider_macos=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider_macos-2.0.6\\ +path_provider_windows=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider_windows-2.1.3\\ +permission_handler=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\permission_handler-10.2.0\\ +permission_handler_android=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\permission_handler_android-10.2.0\\ +permission_handler_apple=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\permission_handler_apple-9.0.7\\ +permission_handler_windows=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\permission_handler_windows-0.1.2\\ +video_player=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\video_player-2.4.10\\ +video_player_android=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\video_player_android-2.3.10\\ +video_player_avfoundation=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\video_player_avfoundation-2.3.8\\ +video_player_web=C:\\src\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\video_player_web-2.0.13\\ diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 960c88b..9b3bf42 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_sound","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/flutter_sound-9.2.13/","native_build":true,"dependencies":[]},{"name":"image_picker_ios","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/image_picker_ios-0.8.6+1/","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/","native_build":true,"dependencies":[]},{"name":"permission_handler_apple","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/permission_handler_apple-9.0.7/","native_build":true,"dependencies":[]},{"name":"video_player_avfoundation","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/video_player_avfoundation-2.3.7/","native_build":true,"dependencies":[]}],"android":[{"name":"flutter_plugin_android_lifecycle","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-2.0.7/","native_build":true,"dependencies":[]},{"name":"flutter_sound","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/flutter_sound-9.2.13/","native_build":true,"dependencies":[]},{"name":"image_picker_android","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/image_picker_android-0.8.5+3/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider_android","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.20/","native_build":true,"dependencies":[]},{"name":"permission_handler_android","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/permission_handler_android-10.2.0/","native_build":true,"dependencies":[]},{"name":"video_player_android","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/video_player_android-2.3.9/","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/","native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/","native_build":false,"dependencies":[]},{"name":"permission_handler_windows","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/permission_handler_windows-0.1.2/","native_build":true,"dependencies":[]}],"web":[{"name":"flutter_sound_web","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/flutter_sound_web-9.2.13/","dependencies":[]},{"name":"image_picker_for_web","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/image_picker_for_web-2.1.10/","dependencies":[]},{"name":"video_player_web","path":"/Users/nielsgorter/.pub-cache/hosted/pub.dartlang.org/video_player_web-2.0.12/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_sound","dependencies":["path_provider","flutter_sound_web"]},{"name":"flutter_sound_web","dependencies":[]},{"name":"image_picker","dependencies":["image_picker_android","image_picker_for_web","image_picker_ios"]},{"name":"image_picker_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"image_picker_for_web","dependencies":[]},{"name":"image_picker_ios","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":["permission_handler_android","permission_handler_apple","permission_handler_windows"]},{"name":"permission_handler_android","dependencies":[]},{"name":"permission_handler_apple","dependencies":[]},{"name":"permission_handler_windows","dependencies":[]},{"name":"video_player","dependencies":["video_player_android","video_player_avfoundation","video_player_web"]},{"name":"video_player_android","dependencies":[]},{"name":"video_player_avfoundation","dependencies":[]},{"name":"video_player_web","dependencies":[]}],"date_created":"2022-10-25 14:19:39.438192","version":"3.3.4"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"file_picker","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\file_picker-5.2.4\\\\","native_build":true,"dependencies":[]},{"name":"flutter_sound","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_sound-9.2.13\\\\","native_build":true,"dependencies":[]},{"name":"image_picker_ios","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\image_picker_ios-0.8.6+2\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_ios-2.0.11\\\\","native_build":true,"dependencies":[]},{"name":"permission_handler_apple","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler_apple-9.0.7\\\\","native_build":true,"dependencies":[]},{"name":"video_player_avfoundation","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\video_player_avfoundation-2.3.8\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"file_picker","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\file_picker-5.2.4\\\\","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"flutter_plugin_android_lifecycle","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_plugin_android_lifecycle-2.0.7\\\\","native_build":true,"dependencies":[]},{"name":"flutter_sound","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_sound-9.2.13\\\\","native_build":true,"dependencies":[]},{"name":"image_picker_android","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\image_picker_android-0.8.5+4\\\\","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider_android","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_android-2.0.22\\\\","native_build":true,"dependencies":[]},{"name":"permission_handler_android","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler_android-10.2.0\\\\","native_build":true,"dependencies":[]},{"name":"video_player_android","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\video_player_android-2.3.10\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_macos-2.0.6\\\\","native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_linux-2.1.7\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_windows-2.1.3\\\\","native_build":false,"dependencies":[]},{"name":"permission_handler_windows","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler_windows-0.1.2\\\\","native_build":true,"dependencies":[]}],"web":[{"name":"file_picker","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\file_picker-5.2.4\\\\","dependencies":[]},{"name":"flutter_sound_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_sound_web-9.2.13\\\\","dependencies":[]},{"name":"image_picker_for_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\image_picker_for_web-2.1.10\\\\","dependencies":[]},{"name":"video_player_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\video_player_web-2.0.13\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"file_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_sound","dependencies":["path_provider","flutter_sound_web"]},{"name":"flutter_sound_web","dependencies":[]},{"name":"image_picker","dependencies":["image_picker_android","image_picker_for_web","image_picker_ios"]},{"name":"image_picker_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"image_picker_for_web","dependencies":[]},{"name":"image_picker_ios","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":["permission_handler_android","permission_handler_apple","permission_handler_windows"]},{"name":"permission_handler_android","dependencies":[]},{"name":"permission_handler_apple","dependencies":[]},{"name":"permission_handler_windows","dependencies":[]},{"name":"video_player","dependencies":["video_player_android","video_player_avfoundation","video_player_web"]},{"name":"video_player_android","dependencies":[]},{"name":"video_player_avfoundation","dependencies":[]},{"name":"video_player_web","dependencies":[]}],"date_created":"2023-01-03 09:08:54.917527","version":"3.3.10"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 23b3828..6a5e431 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,25 @@ -## 0.0.1 +## 0.2.0 +- Added option to select a file +- Added file_picker package for file picking possibility +- Inputs now have widgets so any widget can be used in the media picker now. +- Translated the example to English -- Initial port +## 0.1.1 -## 0.0.2 - -- Updated flutter_form version - -## 0.0.3 - -- Fixed bug where onTap was not working when header is set +- Updated flutter_form version to 2.0.1 ## 0.1.0 - Ability to set styling for the audio input. -## 0.1.1 +## 0.0.3 -- Updated flutter_form version to 2.0.1 +- Fixed bug where onTap was not working when header is set + +## 0.0.2 + +- Updated flutter_form version + +## 0.0.1 + +- Initial port diff --git a/MediaPickerGifNew.gif b/MediaPickerGifNew.gif new file mode 100644 index 0000000..c839edc Binary files /dev/null and b/MediaPickerGifNew.gif differ diff --git a/example/lib/main.dart b/example/lib/main.dart index d83d1f8..88ab789 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -17,11 +17,11 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return ProviderScope( child: MaterialApp( - title: 'Flutter Demo', + title: 'Media Picker Example', theme: ThemeData( primarySwatch: Colors.blue, ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), + home: const MyHomePage(title: 'Media Picker Example'), ), ); } @@ -45,13 +45,13 @@ class _MyHomePageState extends State { ), body: Center( child: ElevatedButton( - child: const Text('Media Picker'), + child: const Text('Media Picker Text Options'), onPressed: () { showModalBottomSheet( backgroundColor: Colors.transparent, context: context, builder: (context) { - return MediaPickerPage( + return MediaPickerExample( callback: () { Navigator.pop(context); }, diff --git a/example/lib/media_picker.dart b/example/lib/media_picker.dart index 8940d6f..df02605 100644 --- a/example/lib/media_picker.dart +++ b/example/lib/media_picker.dart @@ -8,15 +8,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_media_picker/flutter_media_picker.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -class MediaPickerPage extends ConsumerStatefulWidget { - const MediaPickerPage({required this.callback, Key? key}) : super(key: key); +class MediaPickerExample extends ConsumerStatefulWidget { + const MediaPickerExample({required this.callback, Key? key}) + : super(key: key); final Function callback; @override - ConsumerState createState() => _MediaPickerState(); + ConsumerState createState() => + _MediaPickerExampleState(); } -class _MediaPickerState extends ConsumerState { +class _MediaPickerExampleState extends ConsumerState { @override Widget build(BuildContext context) { var mediaService = ref.read(mediaPickerServiceProvider); @@ -49,7 +51,7 @@ class _MediaPickerState extends ConsumerState { height: 14, ), const Text( - 'Maken', + 'Create/Pick', style: TextStyle( fontWeight: FontWeight.w900, fontSize: 20, @@ -61,9 +63,14 @@ class _MediaPickerState extends ConsumerState { MediaPicker( mediaPickerInputs: [ MediaPickerInputPhoto( + label: 'Make photo', + // widget: const IconButtonWithText( + // icon: Icons.photo, + // iconText: "Make photo", + // ), pickFile: mediaService.pickImageFile, checkPageSettings: { - 'title': 'Foto delen', + 'title': 'Share photo', 'width': 125.0, 'height': 200.0, }, @@ -72,10 +79,15 @@ class _MediaPickerState extends ConsumerState { }, ), MediaPickerInputVideo( + label: 'Make video', + // widget: const IconButtonWithText( + // icon: Icons.video_camera_front, + // iconText: "Make video", + // ), pickFile: mediaService.pickVideoFile, videoPlayerFactory: MediaPickerVideoPlayerFactory(), checkPageSettings: { - 'title': 'Video delen', + 'title': 'Share video', 'width': 122.5, 'height': 200.0, }, @@ -85,14 +97,48 @@ class _MediaPickerState extends ConsumerState { ), if (!kIsWeb) MediaPickerInputAudio( - checkPageSettings: {'title': 'Audio delen'}, + label: 'Record audio', + // widget: const IconButtonWithText( + // icon: Icons.record_voice_over, + // iconText: "Record audio", + // ), + checkPageSettings: {'title': 'Share audio'}, onComplete: (MediaResult result) { Navigator.pop(context); }, audioService: audioService, ), MediaPickerInputText( - checkPageSettings: {'title': 'Tekst delen'}, + label: 'Write text', + // widget: const IconButtonWithText( + // icon: Icons.text_fields, + // iconText: "Write text", + // ), + checkPageSettings: {'title': 'Share text'}, + onComplete: (MediaResult result) { + Navigator.pop(context); + }, + ), + MediaPickerInputFile( + label: 'Select file', + // widget: const IconButtonWithText( + // icon: Icons.file_copy, + // iconText: "Select file", + // ), + pickFile: mediaService.pickFile, + fileExtensions: [ + 'pdf', + 'doc', + 'png', + 'jpg', + 'docx', + 'bmp', + 'gif', + 'txt', + ], + checkPageSettings: { + 'title': 'Share file', + }, onComplete: (MediaResult result) { Navigator.pop(context); }, diff --git a/example/lib/media_picker_check.dart b/example/lib/media_picker_check.dart index b7fd87d..f366a57 100644 --- a/example/lib/media_picker_check.dart +++ b/example/lib/media_picker_check.dart @@ -70,7 +70,7 @@ class _MediaCheckPageState extends State { widget.cancel(); formController.autoNextStep(); }, - child: const Text("Delen"), + child: const Text('Share'), ), ), ), @@ -140,7 +140,7 @@ class _MediaCheckPageState extends State { ), Expanded( child: FlutterFormInputMultiLine( - hint: "Voeg omschrijving toe...", + hint: 'Add description...', maxCharacters: 300, controller: descriptionController), ), @@ -149,7 +149,7 @@ class _MediaCheckPageState extends State { ), FlutterFormInputSwitch( label: const Text( - 'Deel op je tijdlijn', + 'Share on time line', style: TextStyle( fontWeight: FontWeight.w500, fontSize: 18, @@ -162,7 +162,7 @@ class _MediaCheckPageState extends State { ), FlutterFormInputSwitch( label: const Text( - 'Bewaar in de kluis', + 'Save in vault', style: TextStyle( fontWeight: FontWeight.w500, fontSize: 18, diff --git a/example/lib/widgets/icon_button_with_text.dart b/example/lib/widgets/icon_button_with_text.dart new file mode 100644 index 0000000..5fb6097 --- /dev/null +++ b/example/lib/widgets/icon_button_with_text.dart @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2022 Iconica +// +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:flutter/material.dart'; + +class IconButtonWithText extends StatelessWidget { + const IconButtonWithText({ + super.key, + this.iconSize = 40, + this.iconText = 'Button', + this.iconTextSize = 16, + this.icon = Icons.file_copy, + }); + + final double iconSize; + final String iconText; + final double iconTextSize; + final IconData icon; + + @override + Widget build(BuildContext context) { + return FittedBox( + fit: BoxFit.fitHeight, + child: Column( + children: [ + Icon( + icon, + size: iconSize, + ), + Text( + iconText, + style: TextStyle(fontSize: iconTextSize), + textAlign: TextAlign.center, + ), + ], + ), + ); + } +} diff --git a/example/pubspec.lock b/example/pubspec.lock index 60c212d..a249f75 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -85,6 +85,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.4" + file_picker: + dependency: transitive + description: + name: file_picker + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.4" flutter: dependency: "direct main" description: flutter diff --git a/lib/src/abstracts/media_picker_input.dart b/lib/src/abstracts/media_picker_input.dart index 66097b8..294df75 100644 --- a/lib/src/abstracts/media_picker_input.dart +++ b/lib/src/abstracts/media_picker_input.dart @@ -6,26 +6,24 @@ import 'package:flutter/material.dart'; import 'package:flutter_media_picker/src/media_result.dart'; /// Abstract class for inputs used by [MediaPicker]. -/// -/// The [label] is used as the title in the header. -/// -/// [onPressed] is called when the user has chosen the input to use. -/// -/// [displayResult] is used when the checkpage parameter is set for the [MediaPicker]. -/// The widget will be given as [displayResult] within the checkpage parameter. -/// -/// [checkPageSettings] are some settings that can be set when needed so they can be used in the checkPage. -/// -/// [onComplete] will be called when the user has selected/made the media. -/// If checkpage is set this method will be called when the [onComplete] is called in the checkPage. abstract class MediaPickerInput { - String label = "Media Picker input"; + /// The [label] is used as the title for the object in the media picker and no [widget] has been given. + String label = 'Media Picker input'; + /// The [widget] is the object that is used to show in the media picker where the user can click on. + Widget? widget; + + /// [onPressed] is called when the user has chosen the input to use. Future onPressed(BuildContext context); + /// [displayResult] is used when the checkpage parameter is set for the [MediaPicker]. + /// The widget will be given as [displayResult] within the checkpage parameter. Future displayResult(MediaResult result); + /// [checkPageSettings] are some settings that can be set when needed so they can be used in the checkPage. Map? checkPageSettings; + /// [onComplete] will be called when the user has selected/made the media. + /// If checkpage is set this method will be called when the [onComplete] is called in the checkPage. void Function(MediaResult result)? onComplete; } diff --git a/lib/src/abstracts/media_picker_service.dart b/lib/src/abstracts/media_picker_service.dart index ecfbd39..dda347d 100644 --- a/lib/src/abstracts/media_picker_service.dart +++ b/lib/src/abstracts/media_picker_service.dart @@ -4,10 +4,15 @@ import 'dart:typed_data'; +import 'package:file_picker/file_picker.dart'; + abstract class MediaPickerService { /// Returns [Uint8List] based on given [ImageSource]. Future pickImageFile(); /// Returns [Uint8List] based on given [VideoSource]. Future pickVideoFile(); + + /// Returns [FilePickerResult] based on given [File]. + Future pickFile(List fileExtensions); } diff --git a/lib/src/inputs/input_audio.dart b/lib/src/inputs/input_audio.dart index d8e6449..ec1151d 100644 --- a/lib/src/inputs/input_audio.dart +++ b/lib/src/inputs/input_audio.dart @@ -12,10 +12,11 @@ import 'package:intl/intl.dart'; /// Input for audio used by [MediaPicker]. /// -/// This feature is only usable for nativa applications. +/// This feature is only usable for native applications. class MediaPickerInputAudio implements MediaPickerInput { MediaPickerInputAudio({ - this.label = "Audio", + this.label = 'Audio', + this.widget, this.checkPageSettings, this.onComplete, required this.audioService, @@ -29,6 +30,9 @@ class MediaPickerInputAudio implements MediaPickerInput { @override String label; + @override + Widget? widget; + @override Future onPressed(BuildContext context) async { MediaResult audio = MediaResult(); @@ -42,7 +46,7 @@ class MediaPickerInputAudio implements MediaPickerInput { if (content.fileValue != null) { audio = content; } else { - throw Exception("No recording returned"); + throw Exception('No recording returned'); } }, inputStyling: inputStyling ?? AudioInputStyling(), diff --git a/lib/src/inputs/input_file.dart b/lib/src/inputs/input_file.dart new file mode 100644 index 0000000..a918f6d --- /dev/null +++ b/lib/src/inputs/input_file.dart @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2022 Iconica +// +// SPDX-License-Identifier: BSD-3-Clause + +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; + +import 'package:path/path.dart' as path; + +import '../../flutter_media_picker.dart'; + +/// Input for file used by [MediaPicker]. +class MediaPickerInputFile implements MediaPickerInput { + MediaPickerInputFile({ + this.label = 'File', + this.widget, + this.fileExtensions = const ['pdf', 'jpg', 'png'], + this.checkPageSettings, + this.onComplete, + this.pickFile, + }); + + final Future Function(List)? pickFile; + final List fileExtensions; + + @override + String label; + + @override + Widget? widget; + + @override + Future onPressed(BuildContext context) async { + var file = await pickFile?.call(fileExtensions); + + if (file != null && file.files.first.bytes != null) { + return MediaResult( + fileValue: file.files.first.bytes, + fileType: path.extension(file.files.first.name), + fileName: file.files.first.name, + ); + } + return MediaResult(); + } + + @override + Future displayResult(MediaResult result) async { + if (result.fileValue != null) { + switch (result.fileType) { + case '.png': + case '.jpg': + case '.jpeg': + case '.webp': + case '.bmp': + case '.gif': + return Image.memory( + result.fileValue!, + height: 250, + ); + case '.pdf': + case '.doc': + case '.docx': + return Text(result.fileName!); + case '.txt': + return Column(mainAxisSize: MainAxisSize.min, children: [ + Text(result.fileName!), + const SizedBox( + height: 20, + ), + Center( + child: Text(String.fromCharCodes(result.fileValue!)), + ) + ]); + default: + } + } + + return Container(); + } + + @override + Map? checkPageSettings; + + @override + void Function(MediaResult value)? onComplete; +} diff --git a/lib/src/inputs/input_photo.dart b/lib/src/inputs/input_photo.dart index b61168f..0720670 100644 --- a/lib/src/inputs/input_photo.dart +++ b/lib/src/inputs/input_photo.dart @@ -12,7 +12,8 @@ import 'package:flutter_media_picker/src/media_result.dart'; /// Input for photo used by [MediaPicker]. class MediaPickerInputPhoto implements MediaPickerInput { MediaPickerInputPhoto({ - this.label = "Foto", + this.label = 'Photo', + this.widget, this.checkPageSettings, this.onComplete, this.pickFile, @@ -23,6 +24,9 @@ class MediaPickerInputPhoto implements MediaPickerInput { @override String label; + @override + Widget? widget; + @override Future onPressed(BuildContext context) async { var image = await pickFile?.call(); diff --git a/lib/src/inputs/input_text.dart b/lib/src/inputs/input_text.dart index 2dacd91..9a8d7ae 100644 --- a/lib/src/inputs/input_text.dart +++ b/lib/src/inputs/input_text.dart @@ -11,7 +11,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; /// Input for text used by [MediaPicker]. class MediaPickerInputText implements MediaPickerInput { MediaPickerInputText({ - this.label = "Tekst", + this.label = 'Text', + this.widget, this.checkPageSettings, this.onComplete, }); @@ -19,6 +20,9 @@ class MediaPickerInputText implements MediaPickerInput { @override String label; + @override + Widget? widget; + @override Future onPressed(BuildContext context) async { return MediaResult(); diff --git a/lib/src/inputs/input_video.dart b/lib/src/inputs/input_video.dart index 3f16c17..d9ee12b 100644 --- a/lib/src/inputs/input_video.dart +++ b/lib/src/inputs/input_video.dart @@ -10,7 +10,8 @@ import 'package:flutter_media_picker/flutter_media_picker.dart'; /// Input for video used by [MediaPicker]. class MediaPickerInputVideo implements MediaPickerInput { MediaPickerInputVideo({ - this.label = "Video", + this.label = 'Video', + this.widget, this.checkPageSettings, this.onComplete, this.pickFile, @@ -20,6 +21,9 @@ class MediaPickerInputVideo implements MediaPickerInput { final Future Function()? pickFile; final VideoPlayerFactory videoPlayerFactory; + @override + Widget? widget; + @override String label; diff --git a/lib/src/inputs/inputs.dart b/lib/src/inputs/inputs.dart index 40fa916..9a15183 100644 --- a/lib/src/inputs/inputs.dart +++ b/lib/src/inputs/inputs.dart @@ -6,3 +6,4 @@ export 'input_audio.dart'; export 'input_photo.dart'; export 'input_text.dart'; export 'input_video.dart'; +export 'input_file.dart'; diff --git a/lib/src/media_picker.dart b/lib/src/media_picker.dart index 99253d4..2e303f3 100644 --- a/lib/src/media_picker.dart +++ b/lib/src/media_picker.dart @@ -100,18 +100,23 @@ import '../flutter_media_picker.dart'; /// ], /// ); ///``` + class MediaPicker extends ConsumerWidget { const MediaPicker({ this.mediaPickerInputs, - this.header, + this.inputsDirection = Axis.horizontal, this.onComplete, this.mediaCheckPage, + this.horizontalSpacing = 0, + this.verticalSpacing = 0, Key? key, }) : super(key: key); final List? mediaPickerInputs; - final Widget Function(String label, Function onPressed)? header; final void Function(MediaResult result)? onComplete; + final Axis inputsDirection; + final double horizontalSpacing; + final double verticalSpacing; final Widget Function( Widget displayResult, Map? inputSettings, @@ -134,42 +139,46 @@ class MediaPicker extends ConsumerWidget { inputs = mediaPickerInputs!; } - return Column( + return Wrap( + alignment: WrapAlignment.center, + direction: inputsDirection, + spacing: horizontalSpacing, + runSpacing: verticalSpacing, children: [ for (final input in inputs) ...[ - const SizedBox(height: 2.5), - header?.call(input.label, (BuildContext ct) async { - await onPressedMediaType(ct, input); - }) ?? - GestureDetector( - onTap: () async { - await onPressedMediaType(context, input); - }, - child: Container( - height: 55, - width: MediaQuery.of(context).size.width * 0.9, - decoration: const BoxDecoration( - border: Border( - bottom: BorderSide( - color: Color(0xFF979797), - width: 1, + GestureDetector( + onTap: () async { + await onPressedMediaType(context, input); + }, + child: Wrap( + children: [ + input.widget ?? + Container( + height: 55, + width: MediaQuery.of(context).size.width * 0.9, + decoration: const BoxDecoration( + border: Border( + bottom: BorderSide( + color: Color(0xFF979797), + width: 1, + ), + ), + ), + child: Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + input.label, + style: Theme.of(context).textTheme.headline6, + ), + ), ), ), - ), - child: Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: const EdgeInsets.only(left: 15), - child: Text( - input.label, - style: Theme.of(context).textTheme.headline6, - ), - ), - ), - ), - ), - const SizedBox(height: 2.5), - ], + ], + ), + ), + ] ], ); } @@ -187,6 +196,7 @@ class MediaPicker extends ConsumerWidget { MediaResult result = MediaResult( fileValue: content.fileValue, textValue: content.textValue, + fileType: content.fileType, checkPageResults: results, ); diff --git a/lib/src/media_result.dart b/lib/src/media_result.dart index 9e430e5..7a1da26 100644 --- a/lib/src/media_result.dart +++ b/lib/src/media_result.dart @@ -10,6 +10,8 @@ class MediaResult { this.textValue, this.fileValue, this.checkPageResults, + this.fileType, + this.fileName, }); /// For textfield returns actual text, @@ -21,4 +23,10 @@ class MediaResult { /// Returns the values from the checkPageResults if checkpage is set. final Map? checkPageResults; + + /// Returns the filetype when a file is selected with the FilePicker. + final String? fileType; + + /// Returns the file name when a file is selected with the FilePicker. + final String? fileName; } diff --git a/lib/src/service/media_picker_service.dart b/lib/src/service/media_picker_service.dart index a0d7e1d..3a98ff5 100644 --- a/lib/src/service/media_picker_service.dart +++ b/lib/src/service/media_picker_service.dart @@ -4,6 +4,7 @@ import 'dart:typed_data'; +import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_media_picker/src/abstracts/media_picker_service.dart'; import 'package:image_picker/image_picker.dart'; @@ -47,4 +48,19 @@ class MediaPickerFileService implements MediaPickerService { await controller.setLooping(true); await controller.play(); } + + @override + Future pickFile(List extensions) async { + var file = await FilePicker.platform.pickFiles( + withData: true, + type: FileType.custom, + allowedExtensions: extensions, + ); + + if (file != null) { + return file; + } + + return Future.value(null); + } } diff --git a/pubspec.yaml b/pubspec.yaml index 7ef046c..4a0ae74 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,9 @@ dependencies: flutter: sdk: flutter + path: any image_picker: any + file_picker: any video_player: any path_provider: any hooks_riverpod: any