diff --git a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md index efcef0146cdc..7b4ffeb275a5 100644 --- a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md +++ b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.0.0 + +**breaking changes**: +- pickImage now returns XFile instead of PickedFile +- pickVideo now returns XFile instead of PickedFile +- changed LostData file parameter type to XFile +- removed PickedFile class and its tests + ## 1.1.5 * Update Flutter SDK constraint. diff --git a/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart b/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart index 6e7641324805..e1f4e98beaeb 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart @@ -1,2 +1,3 @@ export 'package:image_picker_platform_interface/src/platform_interface/image_picker_platform.dart'; export 'package:image_picker_platform_interface/src/types/types.dart'; +export 'package:cross_file/cross_file.dart'; diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart b/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart index 71704b63ced4..05205ecb66db 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart @@ -7,6 +7,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:image_picker_platform_interface/src/types/lost_data.dart'; import 'package:meta/meta.dart' show required, visibleForTesting; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; @@ -20,7 +21,7 @@ class MethodChannelImagePicker extends ImagePickerPlatform { MethodChannel get channel => _channel; @override - Future pickImage({ + Future pickImage({ @required ImageSource source, double maxWidth, double maxHeight, @@ -34,7 +35,7 @@ class MethodChannelImagePicker extends ImagePickerPlatform { imageQuality: imageQuality, preferredCameraDevice: preferredCameraDevice, ); - return path != null ? PickedFile(path) : null; + return path != null ? XFile(path) : null; } @override @@ -72,7 +73,7 @@ class MethodChannelImagePicker extends ImagePickerPlatform { } @override - Future pickVideo({ + Future pickVideo({ @required ImageSource source, CameraDevice preferredCameraDevice = CameraDevice.rear, Duration maxDuration, @@ -82,7 +83,7 @@ class MethodChannelImagePicker extends ImagePickerPlatform { maxDuration: maxDuration, preferredCameraDevice: preferredCameraDevice, ); - return path != null ? PickedFile(path) : null; + return path != null ? XFile(path) : null; } @override @@ -132,7 +133,7 @@ class MethodChannelImagePicker extends ImagePickerPlatform { final String path = result['path']; return LostData( - file: path != null ? PickedFile(path) : null, + file: path != null ? XFile(path) : null, exception: exception, type: retrieveType, ); diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart b/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart index cbd604187714..31d1ce0c6b00 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart @@ -4,6 +4,8 @@ import 'dart:async'; +import 'package:cross_file/cross_file.dart'; +import 'package:image_picker_platform_interface/src/types/lost_data.dart'; import 'package:meta/meta.dart' show required; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -115,7 +117,7 @@ abstract class ImagePickerPlatform extends PlatformInterface { // Next version of the API. - /// Returns a [PickedFile] with the image that was picked. + /// Returns a [XFile] with the image that was picked. /// /// The `source` argument controls where the image comes from. This can /// be either [ImageSource.camera] or [ImageSource.gallery]. @@ -141,7 +143,7 @@ abstract class ImagePickerPlatform extends PlatformInterface { /// /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data. - Future pickImage({ + Future pickImage({ @required ImageSource source, double maxWidth, double maxHeight, @@ -151,7 +153,7 @@ abstract class ImagePickerPlatform extends PlatformInterface { throw UnimplementedError('pickImage() has not been implemented.'); } - /// Returns a [PickedFile] containing the video that was picked. + /// Returns a [XFile] containing the video that was picked. /// /// The [source] argument controls where the video comes from. This can /// be either [ImageSource.camera] or [ImageSource.gallery]. @@ -165,7 +167,7 @@ abstract class ImagePickerPlatform extends PlatformInterface { /// /// In Android, the MainActivity can be destroyed for various fo reasons. If that happens, the result will be lost /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data. - Future pickVideo({ + Future pickVideo({ @required ImageSource source, CameraDevice preferredCameraDevice = CameraDevice.rear, Duration maxDuration, @@ -173,7 +175,7 @@ abstract class ImagePickerPlatform extends PlatformInterface { throw UnimplementedError('pickVideo() has not been implemented.'); } - /// Retrieve the lost [PickedFile] file when [pickImage] or [pickVideo] failed because the MainActivity is destroyed. (Android only) + /// Retrieve the lost [XFile] file when [pickImage] or [pickVideo] failed because the MainActivity is destroyed. (Android only) /// /// Image or video can be lost if the MainActivity is destroyed. And there is no guarantee that the MainActivity is always alive. /// Call this method to retrieve the lost data and process the data according to your APP's business logic. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/lost_data.dart similarity index 96% rename from packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart rename to packages/image_picker/image_picker_platform_interface/lib/src/types/lost_data.dart index b94e69de219e..0623c66502d9 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/lost_data.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:cross_file/cross_file.dart'; import 'package:flutter/services.dart'; import 'package:image_picker_platform_interface/src/types/types.dart'; @@ -31,7 +32,7 @@ class LostData { /// The file that was lost in a previous [pickImage] or [pickVideo] call due to MainActivity being destroyed. /// /// Can be null if [exception] exists. - final PickedFile file; + final XFile file; /// The exception of the last [pickImage] or [pickVideo]. /// diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart deleted file mode 100644 index 285294efcb3d..000000000000 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:meta/meta.dart'; - -/// The interface for a PickedFile. -/// -/// A PickedFile is a container that wraps the path of a selected -/// file by the user and (in some platforms, like web) the bytes -/// with the contents of the file. -/// -/// This class is a very limited subset of dart:io [File], so all -/// the methods should seem familiar. -@immutable -abstract class PickedFileBase { - /// Construct a PickedFile - PickedFileBase(String path); - - /// Get the path of the picked file. - /// - /// This should only be used as a backwards-compatibility clutch - /// for mobile apps, or cosmetic reasons only (to show the user - /// the path they've picked). - /// - /// Accessing the data contained in the picked file by its path - /// is platform-dependant (and won't work on web), so use the - /// byte getters in the PickedFile instance instead. - String get path { - throw UnimplementedError('.path has not been implemented.'); - } - - /// Synchronously read the entire file contents as a string using the given [Encoding]. - /// - /// By default, `encoding` is [utf8]. - /// - /// Throws Exception if the operation fails. - Future readAsString({Encoding encoding = utf8}) { - throw UnimplementedError('readAsString() has not been implemented.'); - } - - /// Synchronously read the entire file contents as a list of bytes. - /// - /// Throws Exception if the operation fails. - Future readAsBytes() { - throw UnimplementedError('readAsBytes() has not been implemented.'); - } - - /// Create a new independent [Stream] for the contents of this file. - /// - /// If `start` is present, the file will be read from byte-offset `start`. Otherwise from the beginning (index 0). - /// - /// If `end` is present, only up to byte-index `end` will be read. Otherwise, until end of file. - /// - /// In order to make sure that system resources are freed, the stream must be read to completion or the subscription on the stream must be cancelled. - Stream openRead([int start, int end]) { - throw UnimplementedError('openRead() has not been implemented.'); - } -} diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart deleted file mode 100644 index ee5145009dc7..000000000000 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:http/http.dart' as http show readBytes; - -import './base.dart'; - -/// A PickedFile that works on web. -/// -/// It wraps the bytes of a selected file. -class PickedFile extends PickedFileBase { - final String path; - final Uint8List _initBytes; - - /// Construct a PickedFile object from its ObjectUrl. - /// - /// Optionally, this can be initialized with `bytes` - /// so no http requests are performed to retrieve files later. - PickedFile(this.path, {Uint8List bytes}) - : _initBytes = bytes, - super(path); - - Future get _bytes async { - if (_initBytes != null) { - return Future.value(UnmodifiableUint8ListView(_initBytes)); - } - return http.readBytes(Uri.parse(path)); - } - - @override - Future readAsString({Encoding encoding = utf8}) async { - return encoding.decode(await _bytes); - } - - @override - Future readAsBytes() async { - return Future.value(await _bytes); - } - - @override - Stream openRead([int start, int end]) async* { - final bytes = await _bytes; - yield bytes.sublist(start ?? 0, end ?? bytes.length); - } -} diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart deleted file mode 100644 index dd64558bf044..000000000000 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; - -import './base.dart'; - -/// A PickedFile backed by a dart:io File. -class PickedFile extends PickedFileBase { - final File _file; - - /// Construct a PickedFile object backed by a dart:io File. - PickedFile(String path) - : _file = File(path), - super(path); - - @override - String get path { - return _file.path; - } - - @override - Future readAsString({Encoding encoding = utf8}) { - return _file.readAsString(encoding: encoding); - } - - @override - Future readAsBytes() { - return _file.readAsBytes(); - } - - @override - Stream openRead([int start, int end]) { - return _file - .openRead(start ?? 0, end) - .map((chunk) => Uint8List.fromList(chunk)); - } -} diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart deleted file mode 100644 index b2a614ccb304..000000000000 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart +++ /dev/null @@ -1,4 +0,0 @@ -export 'lost_data.dart'; -export 'unsupported.dart' - if (dart.library.html) 'html.dart' - if (dart.library.io) 'io.dart'; diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart deleted file mode 100644 index bc10a4890c8d..000000000000 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart +++ /dev/null @@ -1,14 +0,0 @@ -import './base.dart'; - -/// A PickedFile is a cross-platform, simplified File abstraction. -/// -/// It wraps the bytes of a selected file, and its (platform-dependant) path. -class PickedFile extends PickedFileBase { - /// Construct a PickedFile object, from its `bytes`. - /// - /// Optionally, you may pass a `path`. See caveats in [PickedFileBase.path]. - PickedFile(String path) : super(path) { - throw UnimplementedError( - 'PickedFile is not available in your current platform.'); - } -} diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart index 9c44fae1aa9d..b2a50b43855c 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart @@ -2,7 +2,7 @@ export 'camera_device.dart'; export 'image_source.dart'; export 'lost_data_response.dart'; export 'retrieve_type.dart'; -export 'picked_file/picked_file.dart'; +export 'lost_data.dart'; /// Denotes that an image is being picked. const String kTypeImage = 'image'; diff --git a/packages/image_picker/image_picker_platform_interface/pubspec.yaml b/packages/image_picker/image_picker_platform_interface/pubspec.yaml index 7943a2a3eccd..46f837ac8870 100644 --- a/packages/image_picker/image_picker_platform_interface/pubspec.yaml +++ b/packages/image_picker/image_picker_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the image_picker plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.1.5 +version: 2.0.0 dependencies: flutter: @@ -11,6 +11,7 @@ dependencies: meta: ^1.1.8 http: ^0.12.1 plugin_platform_interface: ^1.0.2 + cross_file: ^0.2.0 dev_dependencies: flutter_test: diff --git a/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart b/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart index e7abe37e4838..57f8d2529c4e 100644 --- a/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart @@ -7,6 +7,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:image_picker_platform_interface/src/method_channel/method_channel_image_picker.dart'; +import 'package:image_picker_platform_interface/src/types/lost_data.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart b/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart deleted file mode 100644 index 49d84ff88f88..000000000000 --- a/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@TestOn('chrome') // Uses web-only Flutter SDK - -import 'dart:convert'; -import 'dart:html' as html; -import 'dart:typed_data'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; - -final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = utf8.encode(expectedStringContents); -final html.File textFile = html.File([bytes], 'hello.txt'); -final String textFileUrl = html.Url.createObjectUrl(textFile); - -void main() { - group('Create with an objectUrl', () { - final pickedFile = PickedFile(textFileUrl); - - test('Can be read as a string', () async { - expect(await pickedFile.readAsString(), equals(expectedStringContents)); - }); - test('Can be read as bytes', () async { - expect(await pickedFile.readAsBytes(), equals(bytes)); - }); - - test('Can be read as a stream', () async { - expect(await pickedFile.openRead().first, equals(bytes)); - }); - - test('Stream can be sliced', () async { - expect( - await pickedFile.openRead(2, 5).first, equals(bytes.sublist(2, 5))); - }); - }); -} diff --git a/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart b/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart deleted file mode 100644 index 94ff759a2fb2..000000000000 --- a/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@TestOn('vm') // Uses dart:io - -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; - -final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = utf8.encode(expectedStringContents); -final File textFile = File('./assets/hello.txt'); -final String textFilePath = textFile.path; - -void main() { - group('Create with an objectUrl', () { - final pickedFile = PickedFile(textFilePath); - - test('Can be read as a string', () async { - expect(await pickedFile.readAsString(), equals(expectedStringContents)); - }); - test('Can be read as bytes', () async { - expect(await pickedFile.readAsBytes(), equals(bytes)); - }); - - test('Can be read as a stream', () async { - expect(await pickedFile.openRead().first, equals(bytes)); - }); - - test('Stream can be sliced', () async { - expect( - await pickedFile.openRead(2, 5).first, equals(bytes.sublist(2, 5))); - }); - }); -}