Skip to content

[image_picker] Adopt readme excerpts #3507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions packages/image_picker/image_picker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.8.7+1

* Updates README to use code excerpts.

## 0.8.7

* Adds `usePhotoPickerAndroid` options.
Expand Down
43 changes: 21 additions & 22 deletions packages/image_picker/image_picker/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Image Picker plugin for Flutter
<?code-excerpt path-base="excerpts/packages/image_picker_example"?>

[![pub package](https://img.shields.io/pub/v/image_picker.svg)](https://pub.dev/packages/image_picker)

Expand Down Expand Up @@ -42,22 +43,20 @@ If you require your picked image to be stored permanently, it is your responsibi

### Example

<?code-excerpt "readme_excerpts.dart (Pick)"?>
``` dart
import 'package:image_picker/image_picker.dart';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this from the excerpt since I don't think there's much value in showing the standard import for using a package; we are mostly only doing this for unusual cases (like including platform implementation packages).


...
final ImagePicker _picker = ImagePicker();
// Pick an image
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
// Capture a photo
final XFile? photo = await _picker.pickImage(source: ImageSource.camera);
// Pick a video
final XFile? image = await _picker.pickVideo(source: ImageSource.gallery);
// Capture a video
final XFile? video = await _picker.pickVideo(source: ImageSource.camera);
// Pick multiple images
final List<XFile>? images = await _picker.pickMultiImage();
...
final ImagePicker picker = ImagePicker();
// Pick an image.
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
// Capture a photo.
final XFile? photo = await picker.pickImage(source: ImageSource.camera);
// Pick a video.
final XFile? galleryVideo =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable names changed because there were variable redeclarations that didn't compile.

await picker.pickVideo(source: ImageSource.gallery);
// Capture a video.
final XFile? cameraVideo = await picker.pickVideo(source: ImageSource.camera);
// Pick multiple images.
final List<XFile> images = await picker.pickMultiImage();
```

### Handling MainActivity destruction on Android
Expand All @@ -71,17 +70,17 @@ low on memory. When the intent finishes executing, Android will restart the
application. Since the data is never returned to the original call use the
`ImagePicker.retrieveLostData()` method to retrieve the lost data. For example:

<?code-excerpt "readme_excerpts.dart (LostData)"?>
```dart
Future<void> getLostData() async {
final LostDataResponse response =
await picker.retrieveLostData();
final ImagePicker picker = ImagePicker();
final LostDataResponse response = await picker.retrieveLostData();
if (response.isEmpty) {
return;
}
if (response.files != null) {
for (final XFile file in response.files) {
_handleFile(file);
}
final List<XFile>? files = response.files;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was added to avoid having to !; the code as written wasn't null-safe since it was doing a property lookup (which can't infer safety from earlier null checks).

if (files != null) {
_handleLostFiles(files);
} else {
_handleError(response.exception);
}
Expand All @@ -95,7 +94,7 @@ complete example of handling this flow.

### Android Photo Picker

This package has optional [Android Photo Picker](https://developer.android.com/training/data-storage/shared/photopicker) functionality.
This package has optional [Android Photo Picker](https://developer.android.com/training/data-storage/shared/photopicker) functionality.
[Learn how to use it](https://pub.dev/packages/image_picker_android).

## Migrating to 0.8.2+
Expand Down
15 changes: 15 additions & 0 deletions packages/image_picker/image_picker/example/build.excerpt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
targets:
$default:
sources:
include:
- lib/**
# Some default includes that aren't really used here but will prevent
# false-negative warnings:
- $package$
- lib/$lib$
exclude:
- '**/.*/**'
- '**/build/**'
builders:
code_excerpter|code_excerpter:
enabled: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';

/// Example function for README demonstration of various pick* calls.
Future<List<XFile?>> readmePickExample() async {
// #docregion Pick
final ImagePicker picker = ImagePicker();
// Pick an image.
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
// Capture a photo.
final XFile? photo = await picker.pickImage(source: ImageSource.camera);
// Pick a video.
final XFile? galleryVideo =
await picker.pickVideo(source: ImageSource.gallery);
// Capture a video.
final XFile? cameraVideo = await picker.pickVideo(source: ImageSource.camera);
// Pick multiple images.
final List<XFile> images = await picker.pickMultiImage();
// #enddocregion Pick

// Return everything for the sanity check test.
return <XFile?>[
image,
photo,
galleryVideo,
cameraVideo,
if (images.isEmpty) null else images.first
];
}

/// Example function for README demonstration of getting lost data.
// #docregion LostData
Future<void> getLostData() async {
final ImagePicker picker = ImagePicker();
final LostDataResponse response = await picker.retrieveLostData();
if (response.isEmpty) {
return;
}
final List<XFile>? files = response.files;
if (files != null) {
_handleLostFiles(files);
} else {
_handleError(response.exception);
}
}
// #enddocregion LostData

// Stubs for the getLostData function.
void _handleLostFiles(List<XFile> file) {}
void _handleError(PlatformException? exception) {}
2 changes: 2 additions & 0 deletions packages/image_picker/image_picker/example/pubspec.yaml
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ 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.6.1
video_player: ^2.1.4

dev_dependencies:
build_runner: ^2.1.10
espresso: ^0.2.0
flutter_driver:
sdk: flutter
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter_test/flutter_test.dart';
import 'package:image_picker_example/readme_excerpts.dart';
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';

void main() {
TestWidgetsFlutterBinding.ensureInitialized();

setUpAll(() async {
ImagePickerPlatform.instance = FakeImagePicker();
});

test('sanity check readmePickExample', () async {
// Ensure that the snippet code runs successfully.
final List<XFile?> results = await readmePickExample();
// It should demonstrate a variety of calls.
expect(results.length, greaterThan(4));
// And the calls should all be different. This works since each fake call
// returns a different result.
expect(results.map((XFile? file) => file?.path).toSet().length,
results.length);
});

test('sanity check getLostData', () async {
// Ensure that the snippet code runs successfully.
await getLostData();
});
}

class FakeImagePicker extends ImagePickerPlatform {
@override
Future<XFile?> getImageFromSource(
{required ImageSource source,
ImagePickerOptions options = const ImagePickerOptions()}) async {
return XFile(source == ImageSource.camera ? 'cameraImage' : 'galleryImage');
}

@override
Future<LostDataResponse> getLostData() async {
return LostDataResponse.empty();
}

@override
Future<List<XFile>> getMultiImageWithOptions(
{MultiImagePickerOptions options =
const MultiImagePickerOptions()}) async {
return <XFile>[XFile('multiImage')];
}

@override
Future<XFile?> getVideo(
{required ImageSource source,
CameraDevice preferredCameraDevice = CameraDevice.rear,
Duration? maxDuration}) async {
return XFile(source == ImageSource.camera ? 'cameraVideo' : 'galleryVideo');
}
}
2 changes: 1 addition & 1 deletion packages/image_picker/image_picker/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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: 0.8.7
version: 0.8.7+1

environment:
sdk: ">=2.17.0 <4.0.0"
Expand Down
1 change: 0 additions & 1 deletion script/configs/temp_exclude_excerpt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
- google_maps_flutter/google_maps_flutter
- google_sign_in/google_sign_in
- google_sign_in_web
- image_picker/image_picker
- image_picker_for_web
- in_app_purchase/in_app_purchase
- ios_platform_images
Expand Down