Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7b9470f
Add limit to image_picker_platform_interface
pdenert Feb 25, 2024
83ad657
Add limit in getMultiImage and getMedia for android and ios
pdenert Feb 25, 2024
38d6d79
Update image picker test mocks
pdenert Feb 25, 2024
05d3953
Format dart files
pdenert Feb 25, 2024
a974ac9
Do clang-format
pdenert Feb 25, 2024
56cffc0
Update pigeon and fix ios tests
pdenert Feb 25, 2024
2e8ebe1
Update pigeon in image_picker_android
pdenert Feb 25, 2024
36083e4
Update pubspec versions and changelog
pdenert Feb 26, 2024
8f8c169
Add tests
pdenert Feb 27, 2024
2dee0d1
Update changelogs
pdenert Feb 28, 2024
bf7f104
Remove limit argument, except from MultiImagePickerOptions
pdenert Feb 28, 2024
684ff3b
Add validation to MediaOptions and MultiImagePickerOptions
pdenert Feb 29, 2024
950a43f
Update image picker test mocks
pdenert Feb 29, 2024
99750d9
Remove changes from web, linux, macos and windows
pdenert Feb 29, 2024
26fd491
Remove limit from pickMultiImage in iOS package
pdenert Feb 29, 2024
70fce1f
Cleanup limit in image_picker_android
pdenert Feb 29, 2024
c7c2b02
Change limit verification param
pdenert Feb 29, 2024
4e7ed37
Update changelog
pdenert Mar 1, 2024
89e6aeb
Change limit validation to lower than 2
pdenert Mar 1, 2024
ba2ed83
Update ios CHANGELOG.md
pdenert Mar 4, 2024
861438a
Update android changelog
pdenert Mar 4, 2024
920baa9
Update image_picker changelog
pdenert Mar 4, 2024
f917977
Fix ImagePickerPluginTests
pdenert Mar 4, 2024
90dfa07
Add limit test to iOS
pdenert Mar 4, 2024
b6308c2
Remove dependency overrides from untouched packages
pdenert Mar 4, 2024
b792137
Format packages
pdenert Mar 5, 2024
b3036ff
Fix android test
pdenert Mar 5, 2024
17d2b6e
Check sdk version
pdenert Mar 5, 2024
7b59aaa
Check only is extension version is available
pdenert Mar 5, 2024
71147c3
Verify is getPickImagesMaxLimit available
pdenert Mar 5, 2024
029b1de
Update image_picker changelog
pdenert Mar 6, 2024
0dc50cd
Remove limit from getMultiImage overrides in iOS and Android
pdenert Mar 6, 2024
d6d6757
Throw error when allowMultiple is false and limit is not null in Medi…
pdenert Mar 13, 2024
81d5115
Add getLimitFromOption method
pdenert Mar 15, 2024
eb7c210
Update android native tests
pdenert Mar 16, 2024
06c8c81
Fix ImagePickerDelegateTests
pdenert Mar 17, 2024
618bf3d
Add android native tests for limit in pickImages
pdenert Mar 17, 2024
85d17ab
Validate media options for allowMultiple and limit
pdenert Mar 18, 2024
a89fe2e
Remove platform interface changes
pdenert Apr 9, 2024
c5e2280
Remove dependency override and update versions
pdenert Apr 9, 2024
39b1df5
Donwgrade versions in example package
pdenert Apr 9, 2024
3e4865c
Bump dart and flutter versions
pdenert Apr 9, 2024
8f8d38a
Remove dependency_overrides from examples
pdenert Apr 9, 2024
7d5a6b1
Update changelog
pdenert Apr 12, 2024
3f7062e
Update example flutter and dart sdk versions
pdenert Apr 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/image_picker/image_picker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 1.1.0

* Adds limit parameter to `MediaOptions` and `MultiImagePickerOptions` which limits
the number of media that can be selected.
* Currently supported only on iOS and Android.
* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.

## 1.0.8

* Updates minimum supported SDK version to Flutter 3.13/Dart 3.1.
Expand Down
31 changes: 22 additions & 9 deletions packages/image_picker/image_picker/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class _MyHomePageState extends State<MyHomePage> {
final TextEditingController maxWidthController = TextEditingController();
final TextEditingController maxHeightController = TextEditingController();
final TextEditingController qualityController = TextEditingController();
final TextEditingController limitController = TextEditingController();

Future<void> _playVideo(XFile? file) async {
if (file != null && mounted) {
Expand Down Expand Up @@ -96,19 +97,21 @@ class _MyHomePageState extends State<MyHomePage> {
source: source, maxDuration: const Duration(seconds: 10));
await _playVideo(file);
} else if (isMultiImage) {
await _displayPickImageDialog(context,
(double? maxWidth, double? maxHeight, int? quality) async {
await _displayPickImageDialog(context, true, (double? maxWidth,
double? maxHeight, int? quality, int? limit) async {
try {
final List<XFile> pickedFileList = isMedia
? await _picker.pickMultipleMedia(
maxWidth: maxWidth,
maxHeight: maxHeight,
imageQuality: quality,
limit: limit,
)
: await _picker.pickMultiImage(
maxWidth: maxWidth,
maxHeight: maxHeight,
imageQuality: quality,
limit: limit,
);
setState(() {
_mediaFileList = pickedFileList;
Expand All @@ -120,8 +123,8 @@ class _MyHomePageState extends State<MyHomePage> {
}
});
} else if (isMedia) {
await _displayPickImageDialog(context,
(double? maxWidth, double? maxHeight, int? quality) async {
await _displayPickImageDialog(context, false, (double? maxWidth,
double? maxHeight, int? quality, int? limit) async {
try {
final List<XFile> pickedFileList = <XFile>[];
final XFile? media = await _picker.pickMedia(
Expand All @@ -142,8 +145,8 @@ class _MyHomePageState extends State<MyHomePage> {
}
});
} else {
await _displayPickImageDialog(context,
(double? maxWidth, double? maxHeight, int? quality) async {
await _displayPickImageDialog(context, false, (double? maxWidth,
double? maxHeight, int? quality, int? limit) async {
try {
final XFile? pickedFile = await _picker.pickImage(
source: source,
Expand Down Expand Up @@ -454,7 +457,7 @@ class _MyHomePageState extends State<MyHomePage> {
}

Future<void> _displayPickImageDialog(
BuildContext context, OnPickImageCallback onPick) async {
BuildContext context, bool isMulti, OnPickImageCallback onPick) async {
return showDialog(
context: context,
builder: (BuildContext context) {
Expand Down Expand Up @@ -483,6 +486,13 @@ class _MyHomePageState extends State<MyHomePage> {
decoration: const InputDecoration(
hintText: 'Enter quality if desired'),
),
if (isMulti)
TextField(
controller: limitController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
hintText: 'Enter limit if desired'),
),
],
),
actions: <Widget>[
Expand All @@ -504,7 +514,10 @@ class _MyHomePageState extends State<MyHomePage> {
final int? quality = qualityController.text.isNotEmpty
? int.parse(qualityController.text)
: null;
onPick(width, height, quality);
final int? limit = limitController.text.isNotEmpty
? int.parse(limitController.text)
: null;
onPick(width, height, quality, limit);
Navigator.of(context).pop();
}),
],
Expand All @@ -514,7 +527,7 @@ class _MyHomePageState extends State<MyHomePage> {
}

typedef OnPickImageCallback = void Function(
double? maxWidth, double? maxHeight, int? quality);
double? maxWidth, double? maxHeight, int? quality, int? limit);

class AspectRatioVideo extends StatefulWidget {
const AspectRatioVideo(this.controller, {super.key});
Expand Down
6 changes: 3 additions & 3 deletions packages/image_picker/image_picker/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ description: Demonstrates how to use the image_picker plugin.
publish_to: none

environment:
sdk: ^3.1.0
flutter: ">=3.13.0"
sdk: ^3.3.0
flutter: ">=3.19.0"

dependencies:
flutter:
Expand All @@ -17,7 +17,7 @@ dependencies:
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
image_picker_platform_interface: ^2.8.0
image_picker_platform_interface: ^2.10.0
mime: ^1.0.4
video_player: ^2.7.0

Expand Down
10 changes: 7 additions & 3 deletions packages/image_picker/image_picker/lib/image_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class ImagePicker {
double? maxWidth,
double? maxHeight,
int? imageQuality,
int? limit,
bool requestFullMetadata = true,
}) {
final ImageOptions imageOptions = ImageOptions.createAndValidate(
Expand All @@ -138,8 +139,9 @@ class ImagePicker {
);

return platform.getMultiImageWithOptions(
options: MultiImagePickerOptions(
options: MultiImagePickerOptions.createAndValidate(
imageOptions: imageOptions,
limit: limit,
),
);
}
Expand Down Expand Up @@ -186,7 +188,7 @@ class ImagePicker {
bool requestFullMetadata = true,
}) async {
final List<XFile> listMedia = await platform.getMedia(
options: MediaOptions(
options: MediaOptions.createAndValidate(
imageOptions: ImageOptions.createAndValidate(
maxHeight: maxHeight,
maxWidth: maxWidth,
Expand Down Expand Up @@ -239,17 +241,19 @@ class ImagePicker {
double? maxWidth,
double? maxHeight,
int? imageQuality,
int? limit,
bool requestFullMetadata = true,
}) {
return platform.getMedia(
options: MediaOptions(
options: MediaOptions.createAndValidate(
allowMultiple: true,
imageOptions: ImageOptions.createAndValidate(
maxHeight: maxHeight,
maxWidth: maxWidth,
imageQuality: imageQuality,
requestFullMetadata: requestFullMetadata,
),
limit: limit,
),
);
}
Expand Down
10 changes: 5 additions & 5 deletions packages/image_picker/image_picker/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ description: Flutter plugin for selecting images from the Android and iOS image
library, and taking new pictures with the camera.
repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
version: 1.0.8
version: 1.1.0

environment:
sdk: ^3.1.0
flutter: ">=3.13.0"
sdk: ^3.3.0
flutter: ">=3.19.0"

flutter:
plugin:
Expand All @@ -30,10 +30,10 @@ dependencies:
sdk: flutter
image_picker_android: ^0.8.7
image_picker_for_web: ">=2.2.0 <4.0.0"
image_picker_ios: ^0.8.9+1
image_picker_ios: ^0.8.8
image_picker_linux: ^0.2.1
image_picker_macos: ^0.2.1
image_picker_platform_interface: ^2.8.0
image_picker_platform_interface: ^2.10.0
image_picker_windows: ^0.2.1

dev_dependencies:
Expand Down
112 changes: 109 additions & 3 deletions packages/image_picker/image_picker/test/image_picker_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,16 @@ void main() {
imageQuality: 70,
);
await picker.pickMultiImage(
maxWidth: 10.0, maxHeight: 20.0, imageQuality: 70);
maxWidth: 10.0,
maxHeight: 20.0,
imageQuality: 70,
);
await picker.pickMultiImage(
maxWidth: 10.0,
maxHeight: 20.0,
imageQuality: 70,
limit: 5,
);

verifyInOrder(<Object>[
mockPlatform.getMultiImageWithOptions(
Expand Down Expand Up @@ -529,6 +538,29 @@ void main() {
named: 'options',
),
),
mockPlatform.getMultiImageWithOptions(
options: argThat(
isInstanceOf<MultiImagePickerOptions>()
.having(
(MultiImagePickerOptions options) =>
options.imageOptions.maxWidth,
'maxWidth',
equals(10.0))
.having(
(MultiImagePickerOptions options) =>
options.imageOptions.maxWidth,
'maxHeight',
equals(10.0))
.having(
(MultiImagePickerOptions options) =>
options.imageOptions.imageQuality,
'imageQuality',
equals(70))
.having((MultiImagePickerOptions options) => options.limit,
'limit', equals(5)),
named: 'options',
),
),
]);
});

Expand All @@ -545,6 +577,24 @@ void main() {
);
});

test('does not accept a limit argument lower than 2', () {
final ImagePicker picker = ImagePicker();
expect(
() => picker.pickMultiImage(limit: -1),
throwsArgumentError,
);

expect(
() => picker.pickMultiImage(limit: 0),
throwsArgumentError,
);

expect(
() => picker.pickMultiImage(limit: 1),
throwsArgumentError,
);
});

test('handles an empty image file response gracefully', () async {
final ImagePicker picker = ImagePicker();

Expand Down Expand Up @@ -620,7 +670,15 @@ void main() {
imageQuality: 70,
);
await picker.pickMedia(
maxWidth: 10.0, maxHeight: 20.0, imageQuality: 70);
maxWidth: 10.0,
maxHeight: 20.0,
imageQuality: 70,
);
await picker.pickMedia(
maxWidth: 10.0,
maxHeight: 20.0,
imageQuality: 70,
);

verifyInOrder(<Object>[
mockPlatform.getMedia(
Expand Down Expand Up @@ -793,7 +851,16 @@ void main() {
imageQuality: 70,
);
await picker.pickMultipleMedia(
maxWidth: 10.0, maxHeight: 20.0, imageQuality: 70);
maxWidth: 10.0,
maxHeight: 20.0,
imageQuality: 70,
);
await picker.pickMultipleMedia(
maxWidth: 10.0,
maxHeight: 20.0,
imageQuality: 70,
limit: 5,
);

verifyInOrder(<Object>[
mockPlatform.getMedia(
Expand Down Expand Up @@ -885,6 +952,27 @@ void main() {
named: 'options',
),
),
mockPlatform.getMedia(
options: argThat(
isInstanceOf<MediaOptions>()
.having(
(MediaOptions options) => options.imageOptions.maxWidth,
'maxWidth',
equals(10.0))
.having(
(MediaOptions options) => options.imageOptions.maxWidth,
'maxHeight',
equals(10.0))
.having(
(MediaOptions options) =>
options.imageOptions.imageQuality,
'imageQuality',
equals(70))
.having((MediaOptions options) => options.limit, 'limit',
equals(5)),
named: 'options',
),
),
]);
});

Expand All @@ -901,6 +989,24 @@ void main() {
);
});

test('does not accept a limit argument lower than 2', () {
final ImagePicker picker = ImagePicker();
expect(
() => picker.pickMultipleMedia(limit: -1),
throwsArgumentError,
);

expect(
() => picker.pickMultipleMedia(limit: 0),
throwsArgumentError,
);

expect(
() => picker.pickMultipleMedia(limit: 1),
throwsArgumentError,
);
});

test('handles an empty image file response gracefully', () async {
final ImagePicker picker = ImagePicker();

Expand Down
4 changes: 4 additions & 0 deletions packages/image_picker/image_picker_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.8.10

* Adds limit parameter to `MediaOptions` and `MultiImagePickerOptions` that sets a limit to how many media or image items can be selected.

## 0.8.9+6

* Updates minSdkVersion to 19.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.flutter.plugins.imagepicker">

<application>
Expand All @@ -11,5 +12,15 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/flutter_image_picker_file_paths" />
</provider>
<!-- Trigger Google Play services to install the backported photo picker module. -->
<service android:name="com.google.android.gms.metadata.ModuleDependencies"
android:enabled="false"
android:exported="false"
tools:ignore="MissingClass">
<intent-filter>
<action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
</intent-filter>
<meta-data android:name="photopicker_activity:0:required" android:value="" />
</service>
</application>
</manifest>
Loading