mirror of
https://github.com/Iconica-Development/flutter_media_picker.git
synced 2025-05-19 00:43:45 +02:00
Merge pull request #4 from Iconica-Development/feature/add-file-picker
Added file picker and option to change widget
This commit is contained in:
commit
4ba167aacb
21 changed files with 345 additions and 103 deletions
|
@ -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\\
|
||||
|
|
File diff suppressed because one or more lines are too long
28
CHANGELOG.md
28
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
|
||||
|
|
BIN
MediaPickerGifNew.gif
Normal file
BIN
MediaPickerGifNew.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 4 MiB |
|
@ -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<MyHomePage> {
|
|||
),
|
||||
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);
|
||||
},
|
||||
|
|
|
@ -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<ConsumerStatefulWidget> createState() => _MediaPickerState();
|
||||
ConsumerState<ConsumerStatefulWidget> createState() =>
|
||||
_MediaPickerExampleState();
|
||||
}
|
||||
|
||||
class _MediaPickerState extends ConsumerState<MediaPickerPage> {
|
||||
class _MediaPickerExampleState extends ConsumerState<MediaPickerExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var mediaService = ref.read<MediaPickerService>(mediaPickerServiceProvider);
|
||||
|
@ -49,7 +51,7 @@ class _MediaPickerState extends ConsumerState<MediaPickerPage> {
|
|||
height: 14,
|
||||
),
|
||||
const Text(
|
||||
'Maken',
|
||||
'Create/Pick',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w900,
|
||||
fontSize: 20,
|
||||
|
@ -61,9 +63,14 @@ class _MediaPickerState extends ConsumerState<MediaPickerPage> {
|
|||
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<MediaPickerPage> {
|
|||
},
|
||||
),
|
||||
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<MediaPickerPage> {
|
|||
),
|
||||
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);
|
||||
},
|
||||
|
|
|
@ -70,7 +70,7 @@ class _MediaCheckPageState extends State<MediaCheckPage> {
|
|||
widget.cancel();
|
||||
formController.autoNextStep();
|
||||
},
|
||||
child: const Text("Delen"),
|
||||
child: const Text('Share'),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -140,7 +140,7 @@ class _MediaCheckPageState extends State<MediaCheckPage> {
|
|||
),
|
||||
Expanded(
|
||||
child: FlutterFormInputMultiLine(
|
||||
hint: "Voeg omschrijving toe...",
|
||||
hint: 'Add description...',
|
||||
maxCharacters: 300,
|
||||
controller: descriptionController),
|
||||
),
|
||||
|
@ -149,7 +149,7 @@ class _MediaCheckPageState extends State<MediaCheckPage> {
|
|||
),
|
||||
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<MediaCheckPage> {
|
|||
),
|
||||
FlutterFormInputSwitch(
|
||||
label: const Text(
|
||||
'Bewaar in de kluis',
|
||||
'Save in vault',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 18,
|
||||
|
|
40
example/lib/widgets/icon_button_with_text.dart
Normal file
40
example/lib/widgets/icon_button_with_text.dart
Normal file
|
@ -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,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<MediaResult> 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<Widget> displayResult(MediaResult result);
|
||||
|
||||
/// [checkPageSettings] are some settings that can be set when needed so they can be used in the checkPage.
|
||||
Map<String, dynamic>? 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;
|
||||
}
|
||||
|
|
|
@ -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<Uint8List?> pickImageFile();
|
||||
|
||||
/// Returns [Uint8List] based on given [VideoSource].
|
||||
Future<Uint8List?> pickVideoFile();
|
||||
|
||||
/// Returns [FilePickerResult] based on given [File].
|
||||
Future<FilePickerResult?> pickFile(List<String> fileExtensions);
|
||||
}
|
||||
|
|
|
@ -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<MediaResult> 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(),
|
||||
|
|
86
lib/src/inputs/input_file.dart
Normal file
86
lib/src/inputs/input_file.dart
Normal file
|
@ -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<FilePickerResult?> Function(List<String>)? pickFile;
|
||||
final List<String> fileExtensions;
|
||||
|
||||
@override
|
||||
String label;
|
||||
|
||||
@override
|
||||
Widget? widget;
|
||||
|
||||
@override
|
||||
Future<MediaResult> 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<Widget> 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<String, dynamic>? checkPageSettings;
|
||||
|
||||
@override
|
||||
void Function(MediaResult value)? onComplete;
|
||||
}
|
|
@ -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<MediaResult> onPressed(BuildContext context) async {
|
||||
var image = await pickFile?.call();
|
||||
|
|
|
@ -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<MediaResult> onPressed(BuildContext context) async {
|
||||
return MediaResult();
|
||||
|
|
|
@ -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<Uint8List?> Function()? pickFile;
|
||||
final VideoPlayerFactory videoPlayerFactory;
|
||||
|
||||
@override
|
||||
Widget? widget;
|
||||
|
||||
@override
|
||||
String label;
|
||||
|
||||
|
|
|
@ -6,3 +6,4 @@ export 'input_audio.dart';
|
|||
export 'input_photo.dart';
|
||||
export 'input_text.dart';
|
||||
export 'input_video.dart';
|
||||
export 'input_file.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<MediaPickerInput>? 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<String, dynamic>? inputSettings,
|
||||
|
@ -134,18 +139,21 @@ 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(
|
||||
child: Wrap(
|
||||
children: [
|
||||
input.widget ??
|
||||
Container(
|
||||
height: 55,
|
||||
width: MediaQuery.of(context).size.width * 0.9,
|
||||
decoration: const BoxDecoration(
|
||||
|
@ -167,9 +175,10 @@ class MediaPicker extends ConsumerWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
);
|
||||
|
||||
|
|
|
@ -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<String, dynamic>? 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;
|
||||
}
|
||||
|
|
|
@ -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<FilePickerResult?> pickFile(List<String> extensions) async {
|
||||
var file = await FilePicker.platform.pickFiles(
|
||||
withData: true,
|
||||
type: FileType.custom,
|
||||
allowedExtensions: extensions,
|
||||
);
|
||||
|
||||
if (file != null) {
|
||||
return file;
|
||||
}
|
||||
|
||||
return Future.value(null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue