From f588942124a97485473417cb0311ee9de32404e3 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sun, 1 Dec 2024 11:48:35 +0300 Subject: [PATCH] feat: support saving images, improving docs, and adding tests (#9) * feat: support saving an image to the gallery, improve docs, add tests, and other improvements * chore(example): format AndroidManifest.xml using Android Studio * chore(docs): minor changes in doc comments of QuillNativeBridge * chore!: improve support for unit testing without workarounds (BREAKING CHANGE) * chore: update min versions of platform implementation packages in quill_native_bridge --- README.md | 22 +- quill_native_bridge/.pubignore | 12 + quill_native_bridge/CHANGELOG.md | 10 + quill_native_bridge/README.md | 267 ++++++++++- quill_native_bridge/example/README.md | 4 +- .../example/android/app/build.gradle | 6 +- .../android/app/src/debug/AndroidManifest.xml | 2 +- .../android/app/src/main/AndroidManifest.xml | 34 +- .../gradle/wrapper/gradle-wrapper.properties | 4 +- .../example/android/settings.gradle | 4 +- .../assets/flutter-casual-games-toolkit.webp | Bin 0 -> 29124 bytes .../example/assets/introducing-flutter.jpg | Bin 0 -> 59315 bytes .../example/assets/loading.gif | Bin 0 -> 79465 bytes ...est.dart => quill_native_bridge_test.dart} | 77 ++- .../example/ios/Runner/Info.plist | 12 + .../example/lib/album_name_input_dialog.dart | 75 +++ quill_native_bridge/example/lib/assets.dart | 3 + .../example/lib/cupertino.dart | 31 ++ quill_native_bridge/example/lib/main.dart | 440 +++++++++++------- .../example/lib/select_image_dialog.dart | 75 +++ .../flutter/generated_plugin_registrant.cc | 4 + .../linux/flutter/generated_plugins.cmake | 1 + .../macos/Runner/DebugProfile.entitlements | 5 + .../example/macos/Runner/Info.plist | 12 + .../example/macos/Runner/Release.entitlements | 5 + quill_native_bridge/example/pubspec.lock | 393 +++++++++++++++- quill_native_bridge/example/pubspec.yaml | 6 +- .../example/test/example_test.dart | 78 ++++ .../example/test/example_test.mocks.dart | 168 +++++++ .../example/test_driver/integration_test.dart | 3 + .../flutter/generated_plugin_registrant.cc | 3 + .../windows/flutter/generated_plugins.cmake | 1 + .../lib/quill_native_bridge.dart | 206 ++++++-- quill_native_bridge/pubspec.yaml | 23 +- ..._to_external_storage_permission_dialog.png | Bin 0 -> 17947 bytes .../ios_add_to_photos_permission_dialog.png | Bin 0 -> 45060 bytes ...ith_album_read_write_permission_dialog.png | Bin 0 -> 185264 bytes .../macos_add_to_photos_permission_dialog.png | Bin 0 -> 55249 bytes ...ith_album_read_write_permission_dialog.png | Bin 0 -> 68580 bytes .../readme_assets/macos_save_image_dialog.png | Bin 0 -> 53345 bytes .../test/quill_native_bridge_test.dart | 248 ++++++++++ .../test/quill_native_bridge_test.mocks.dart | 174 +++++++ quill_native_bridge_android/CHANGELOG.md | 12 + .../android/build.gradle | 14 +- .../QuillNativeBridgeImpl.kt | 42 ++ .../QuillNativeBridgePlugin.kt | 62 ++- .../clipboard/ClipboardReadImageHandler.kt | 24 +- .../clipboard/ClipboardWriteImageHandler.kt | 35 +- .../generated/GeneratedMessages.kt | 45 +- .../saveImage/SaveImageHandler.kt | 282 +++++++++++ .../util/ImageDecoderCompat.kt | 62 +++ .../util/PigeonExtension.kt | 25 + .../lib/quill_native_bridge_android.dart | 73 ++- .../lib/src/messages.g.dart | 69 ++- .../pigeons/messages.dart | 15 +- quill_native_bridge_android/pubspec.yaml | 8 +- .../quill_native_bridge_android_test.dart | 338 ++++++++++++++ ...uill_native_bridge_android_test.mocks.dart | 84 ++++ .../test/test_api.g.dart | 282 +++++++++++ quill_native_bridge_ios/CHANGELOG.md | 4 + .../quill_native_bridge_ios/Messages.g.swift | 37 ++ .../QuillNativeBridgeImpl.swift | 127 +++++ .../lib/quill_native_bridge_ios.dart | 32 +- .../lib/src/messages.g.dart | 63 +++ quill_native_bridge_ios/pigeons/messages.dart | 13 +- quill_native_bridge_ios/pubspec.yaml | 6 +- .../test/quill_native_bridge_ios_test.dart | 265 +++++++++++ .../quill_native_bridge_ios_test.mocks.dart | 90 ++++ quill_native_bridge_ios/test/test_api.g.dart | 298 ++++++++++++ quill_native_bridge_linux/CHANGELOG.md | 4 + .../lib/quill_native_bridge_linux.dart | 38 +- .../lib/src/environment_provider.dart | 21 + .../lib/src/image_saver.dart | 23 + quill_native_bridge_linux/pubspec.yaml | 10 +- .../test/environment_provider_test.dart | 40 ++ .../test/quill_native_bridge_linux_test.dart | 336 +++++++++++++ .../quill_native_bridge_linux_test.mocks.dart | 160 +++++++ quill_native_bridge_macos/CHANGELOG.md | 4 + .../lib/quill_native_bridge_macos.dart | 90 +++- .../lib/src/messages.g.dart | 121 +++++ .../Messages.g.swift | 71 +++ .../QuillNativeBridgeImpl.swift | 181 +++++++ .../pigeons/messages.dart | 22 +- quill_native_bridge_macos/pubspec.yaml | 6 +- .../test/quill_native_bridge_macos_test.dart | 386 +++++++++++++++ .../quill_native_bridge_macos_test.mocks.dart | 116 +++++ .../test/test_api.g.dart | 372 +++++++++++++++ .../CHANGELOG.md | 5 + ...uill_native_bridge_platform_interface.dart | 66 ++- .../lib/src/image_mime_utils.dart | 14 + .../lib/src/platform_feature.dart | 5 +- .../lib/src/types/image_save_options.dart | 55 +++ .../lib/src/types/image_save_result.dart | 32 ++ .../pubspec.yaml | 2 +- .../test/image_mime_utils_test.dart | 53 +++ ...ill_native_bridge_platform_interface.dart} | 82 ++++ quill_native_bridge_web/CHANGELOG.md | 4 + .../lib/quill_native_bridge_web.dart | 29 ++ quill_native_bridge_web/pubspec.yaml | 4 +- quill_native_bridge_windows/CHANGELOG.md | 4 + .../lib/quill_native_bridge_windows.dart | 48 ++ .../lib/src/environment_provider.dart | 21 + .../lib/src/image_saver.dart | 23 + quill_native_bridge_windows/pubspec.yaml | 8 +- .../test/environment_provider_test.dart | 40 ++ .../quill_native_bridge_windows_test.dart | 320 +++++++++++++ ...uill_native_bridge_windows_test.mocks.dart | 161 +++++++ 107 files changed, 7354 insertions(+), 438 deletions(-) create mode 100644 quill_native_bridge/.pubignore create mode 100644 quill_native_bridge/example/assets/flutter-casual-games-toolkit.webp create mode 100644 quill_native_bridge/example/assets/introducing-flutter.jpg create mode 100644 quill_native_bridge/example/assets/loading.gif rename quill_native_bridge/example/integration_test/{integration_test.dart => quill_native_bridge_test.dart} (65%) create mode 100644 quill_native_bridge/example/lib/album_name_input_dialog.dart create mode 100644 quill_native_bridge/example/lib/cupertino.dart create mode 100644 quill_native_bridge/example/lib/select_image_dialog.dart create mode 100644 quill_native_bridge/example/test/example_test.dart create mode 100644 quill_native_bridge/example/test/example_test.mocks.dart create mode 100644 quill_native_bridge/example/test_driver/integration_test.dart create mode 100644 quill_native_bridge/readme_assets/android_9_write_to_external_storage_permission_dialog.png create mode 100644 quill_native_bridge/readme_assets/ios_add_to_photos_permission_dialog.png create mode 100644 quill_native_bridge/readme_assets/ios_add_to_photos_with_album_read_write_permission_dialog.png create mode 100644 quill_native_bridge/readme_assets/macos_add_to_photos_permission_dialog.png create mode 100644 quill_native_bridge/readme_assets/macos_add_to_photos_with_album_read_write_permission_dialog.png create mode 100644 quill_native_bridge/readme_assets/macos_save_image_dialog.png create mode 100644 quill_native_bridge/test/quill_native_bridge_test.dart create mode 100644 quill_native_bridge/test/quill_native_bridge_test.mocks.dart create mode 100644 quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/saveImage/SaveImageHandler.kt create mode 100644 quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/util/ImageDecoderCompat.kt create mode 100644 quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/util/PigeonExtension.kt create mode 100644 quill_native_bridge_android/test/quill_native_bridge_android_test.dart create mode 100644 quill_native_bridge_android/test/quill_native_bridge_android_test.mocks.dart create mode 100644 quill_native_bridge_android/test/test_api.g.dart create mode 100644 quill_native_bridge_ios/test/quill_native_bridge_ios_test.dart create mode 100644 quill_native_bridge_ios/test/quill_native_bridge_ios_test.mocks.dart create mode 100644 quill_native_bridge_ios/test/test_api.g.dart create mode 100644 quill_native_bridge_linux/lib/src/environment_provider.dart create mode 100644 quill_native_bridge_linux/lib/src/image_saver.dart create mode 100644 quill_native_bridge_linux/test/environment_provider_test.dart create mode 100644 quill_native_bridge_linux/test/quill_native_bridge_linux_test.dart create mode 100644 quill_native_bridge_linux/test/quill_native_bridge_linux_test.mocks.dart create mode 100644 quill_native_bridge_macos/test/quill_native_bridge_macos_test.dart create mode 100644 quill_native_bridge_macos/test/quill_native_bridge_macos_test.mocks.dart create mode 100644 quill_native_bridge_macos/test/test_api.g.dart create mode 100644 quill_native_bridge_platform_interface/lib/src/image_mime_utils.dart create mode 100644 quill_native_bridge_platform_interface/lib/src/types/image_save_options.dart create mode 100644 quill_native_bridge_platform_interface/lib/src/types/image_save_result.dart create mode 100644 quill_native_bridge_platform_interface/test/image_mime_utils_test.dart rename quill_native_bridge_platform_interface/test/{quill_native_bridge_test.dart => quill_native_bridge_platform_interface.dart} (59%) create mode 100644 quill_native_bridge_windows/lib/src/environment_provider.dart create mode 100644 quill_native_bridge_windows/lib/src/image_saver.dart create mode 100644 quill_native_bridge_windows/test/environment_provider_test.dart create mode 100644 quill_native_bridge_windows/test/quill_native_bridge_windows_test.dart create mode 100644 quill_native_bridge_windows/test/quill_native_bridge_windows_test.mocks.dart diff --git a/README.md b/README.md index 38e9a96..6ecd3f7 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,19 @@ -# πŸͺΆ Quill Native Bridge +# πŸͺΆ Flutter quill_native_bridge plugin -An internal plugin for [`flutter_quill`](https://pub.dev/packages/flutter_quill) package to access platform-specific APIs. +An internal Flutter plugin for [`flutter_quill`](https://pub.dev/packages/flutter_quill) package to access platform-specific APIs, +built following the [federated plugin architecture](https://docs.google.com/document/d/1LD7QjmzJZLCopUrFAAE98wOUQpjmguyGTN2wd_89Srs/). +A detailed explanation of the federated plugin concept can be found in the [Flutter documentation](https://docs.flutter.dev/packages-and-plugins/developing-packages#federated-plugins). -> [!NOTE] -> -> **Internal Use Only**: Exclusively for `flutter_quill`. Breaking changes may occur. +This means the project is separated into the following packages: -For more details, refer to [quill_native_bridge](./quill_native_bridge/README.md). \ No newline at end of file +1. [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge): The app-facing package that clients depend on to use the plugin. This package specifies the API used by the Flutter app. +2. [`quill_native_bridge_platform_interface`](https://pub.dev/packages/quill_native_bridge_platform_interface): The package that declares an interface that any platform package must implement to support the app-facing package. +3. The platform packages: One or more packages that contain the platform-specific implementation code. The app-facing package calls into these packagesβ€”they aren't included into an app, unless they contain platform-specific functionality: + * [`quill_native_bridge_android`](https://pub.dev/packages/quill_native_bridge_android) + * [`quill_native_bridge_ios`](https://pub.dev/packages/quill_native_bridge_ios) + * [`quill_native_bridge_macos`](https://pub.dev/packages/quill_native_bridge_macos) + * [`quill_native_bridge_linux`](https://pub.dev/packages/quill_native_bridge_linux) + * [`quill_native_bridge_windows`](https://pub.dev/packages/quill_native_bridge_windows) + * [`quill_native_bridge_web`](https://pub.dev/packages/quill_native_bridge_web) + +For more details, refer to [quill_native_bridge README](./quill_native_bridge/README.md). diff --git a/quill_native_bridge/.pubignore b/quill_native_bridge/.pubignore new file mode 100644 index 0000000..ed54ac3 --- /dev/null +++ b/quill_native_bridge/.pubignore @@ -0,0 +1,12 @@ +readme_assets/ +example/assets/ + +example/android/ +example/ios/ +example/macos/ +example/web/ +example/windows/ +example/linux/ +example/test_driver/ +example/integration_test/ +test/ \ No newline at end of file diff --git a/quill_native_bridge/CHANGELOG.md b/quill_native_bridge/CHANGELOG.md index 7f7f0d5..43a4567 100644 --- a/quill_native_bridge/CHANGELOG.md +++ b/quill_native_bridge/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. +## 11.0.0 + +- Improves `README.md`. Adds more details to `README.md`. +- Updates the section `Platform configuration` to `Setup` in `README.md`. +- Improves doc comments. +- Adds unit tests for `QuillNativeBridge`. +- Adds support for saving images. +- Updates Java compatibility version to 11. Related [flutter#156111](https://github.com/flutter/flutter/issues/156111). +- **BREAKING CHANGE**: Converted all static methods in `QuillNativeBridge` to instance methods to improve unit testing and extensibility. + ## 10.7.11 - Adds pub topics to package metadata. diff --git a/quill_native_bridge/README.md b/quill_native_bridge/README.md index e39646c..09fba88 100644 --- a/quill_native_bridge/README.md +++ b/quill_native_bridge/README.md @@ -1,10 +1,10 @@ # πŸͺΆ Quill Native Bridge -An internal plugin for [`flutter_quill`](https://pub.dev/packages/flutter_quill) package to access platform-specific APIs. +An internal Flutter plugin for [`flutter_quill`](https://pub.dev/packages/flutter_quill) package to access platform-specific APIs. -> [!NOTE] -> -> **Internal Use Only**: Exclusively for `flutter_quill`. Breaking changes may occur. +For details about the plugin architecture, refer to the [README of the repo](../README.md). + +## ✨ Features | Feature | iOS | Android | macOS | Windows | Linux | Web | |--------------------------|------|---------|-------|---------|-------|-------| @@ -15,20 +15,119 @@ An internal plugin for [`flutter_quill`](https://pub.dev/packages/flutter_quill) | **getClipboardImage** | βœ… | βœ… | βœ… | ❌ | βœ… | βœ… | | **getClipboardGif** | βœ… | βœ… | βšͺ | βšͺ | βšͺ | βšͺ | | **getClipboardFiles** | βšͺ | βšͺ | βœ… | ❌ | βœ… | ❌ | +| **openGalleryApp** | βœ… | βœ… | βœ… | βœ… | βšͺ | βšͺ | +| **saveImageToGallery** | βœ… | βœ… | βœ… | ❌ | βšͺ | βšͺ | +| **saveImage** | βšͺ | βšͺ | βœ… | βœ… | βœ… | βœ… | -## πŸ”§ Platform Configuration +- `βšͺ`: Not applicable, not expected, or unsupported on this platform (e.g., checking **iOS simulator** on **Android**, saving images to the gallery on the web, or retrieving GIFs on desktop/web). +- `❌`: The plugin doesn't currently implement it. +- `βœ…`: Supported and functional. -To support copying images to the system clipboard on **Android**. A platform configuration setup is required. -If not set up, a warning will appear in the log during debug mode only -if `copyImageToClipboard` was called without configuring the Android project. -An exception with less details will be thrown in production mode. +See the [API reference](https://pub.dev/documentation/quill_native_bridge/latest/) for more details. -> [!IMPORTANT] -> -> This configuration is required on **Android** platform for using `copyImageToClipboard`. -> Other features on Android will work without it if this method isn't used. +## πŸ“œ Usage + +Some features require a platform-specific setup. See the [Setup](#-setup) section for details. + +Always review the doc comment of a method before use for special notes. + +Check if a method is supported on the platform/os version before using it: + +```dart +if (await QuillNativeBridge().isSupported(QuillNativeBridgeFeature.copyHtmlToClipboard)) { +// Replace copyHtmlToClipboard with the method or functionality name +} +``` + +**To check if the iOS app is running on iOS simulator**: + +```dart +import 'package:flutter/foundation.dart'; + +final isIOSApp = !kIsWeb && defaultTargetPlatform == TargetPlatform.iOS; + +if (isIOSApp && await QuillNativeBridge().isIOSSimulator()) { + // The app is running on an iOS simulator. +} +``` + +**To retrive the HTML from the system clipboard**: + +```dart +final String? html = await QuillNativeBridge().getClipboardHtml(); // Null in case permission denied on iOS or HTML is not available +``` + +**To copy an HTML to the system clipboard**: + +```dart +const exampleHtml = 'Bold text'; +await QuillNativeBridge().copyHtmlToClipboard(exampleHtml); +``` + +**To copy an image to the system clipboard**: + +```dart +final Uint8List imageBytes = ...; // Load the image bytes + +await QuillNativeBridge().copyImageToClipboard(imageBytes); +``` + +**To retrive the image from the system clipboard**: + +```dart +final Uint8List? imageBytes = await QuillNativeBridge().getClipboardImage(); // Null if the image is not available + +// OR a GIF image + +final Uint8List? gifBytes = await QuillNativeBridge().getClipboardGif(); // Null if the image is not available +``` + +**To retrive copied files from the system clipboard on desktop**: + +```dart +final List filePaths = await QuillNativeBridge().getClipboardFiles(); // Empty list if no files are available +``` + +**To open the system gallery app**: + +```dart +await QuillNativeBridge().openGalleryApp(); // Work only for platforms that have a system gallery app +``` + +**To save an image to the system gallery**: + +```dart +final Uint8List imageBytes = ...; // Load the image bytes + +await QuillNativeBridge().saveImageToGallery(imageBytes, options: GalleryImageSaveOptions(name: 'ExampleImageName', fileExtension: 'png', albumName: null)); // Work only for platforms that have a system gallery app +``` + +**To save an image using save dialog on desktop or download it on web**: + +```dart +final Uint8List imageBytes = ...; // Load the image bytes + +await QuillNativeBridge().saveImage(imageBytes, options: ImageSaveOptions(name: 'ExampleImageName', fileExtension: 'png')); // Doesn't work on mobile platforms +``` + +## πŸ”§ Setup + +Certain functionalities require a platform-specific configuration. +If this configuration is not properly set up in: + +* **πŸ› οΈ Debug mode**: A warning will be displayed in the log with a link to this section. +* **πŸš€ Production mode**: An exception with fewer details will be thrown. + +### πŸ“‹ Copying images to the system clipboard + +> [!NOTE] +> This configuration is only required on **Android** platform for using `copyImageToClipboard`. > For more information, refer to the [Android FileProvider documentation](https://developer.android.com/reference/androidx/core/content/FileProvider). +#### Android + + + **1. Update `AndroidManifest.xml`** Open `android/app/src/main/AndroidManifest.xml` and add the following inside the `` tag: @@ -61,6 +160,148 @@ Create the file `android/app/src/main/res/xml/file_paths.xml` with the following ``` +### πŸ–ΌοΈ Saving images to the gallery + +#### Android + +Depending on the Android version, the app might need permission: + +* **Android 10 (Api 29) and later**: The permission `android.permission.WRITE_EXTERNAL_STORAGE` is no longer supported or required. The plugin makes use of the [Android scoped storage](https://source.android.com/docs/core/storage/scoped), no runtime permission is needed. +* **Android 9 (API 28) and earlier**: Scoped storage is not supported. The `android.permission.WRITE_EXTERNAL_STORAGE` permission is still required, and both modifying the `AndroidManifest.xml` and requesting runtime permission are necessary for writing to external storage. **This setup is only needed for backward compatibility.** + +To support previous versions, +open `android/app/src/main/AndroidManifest.xml` and add the following inside the `` tag: + +```xml + + ... + + ... + +``` + +> [!TIP] +> The `maxSdkVersion` attribute must be set to `28` since this +> is no longer required or supported on **Android 10 and later**. + +The plugin will request permission from the user in runtime +when `saveImageToGallery` is called and permission is not granted yet, +**but only on Android 9 (API 28) and earlier.** + +An example of the permission dialog on **Android 9 (API 28) and earlier**, requesting write access to the external storage: + +Android 9 dialog requesting write-to external storage permission + +#### iOS + +To save images to the gallery, the app needs permission, and the required permission depends on the **iOS version** and **whether the album name was specified**: + +* `NSPhotoLibraryAddUsageDescription`: Permission to add images to the photo library, labeled as `Privacy - Photo Library Additions Usage Description` in Xcode. This key is available only on **iOS 14 and later** and is requested at runtime if no album name is specified, otherwise, it requests read-write permission (`NSPhotoLibraryUsageDescription`). +* `NSPhotoLibraryUsageDescription`: Read-write permission to the photos library, labeled as `Privacy - Photo Library Usage Description` in Xcode. This key has been available since **iOS 6** and is requested at runtime on **iOS 13 and earlier** (as add-only permission is unavailable) and is always requested if the album name is specified, even on **iOS 14 and later**. + +> [!IMPORTANT] +> If the album name was specified, read-write permission (`NSPhotoLibraryUsageDescription`) is always required even on **iOS 14 and later**. + +Open the file `/ios/Runner/Info.plist` and add the following keys inside the `` tag: + +```plist + +NSPhotoLibraryAddUsageDescription +Your description here + + +NSPhotoLibraryUsageDescription +Your description here +``` + +> [!IMPORTANT] +> Replace `Your description here` with an explanation of why your app requires **add-only** or **read-write** access to the photo library (e.g., `Used to demonstrate quill_native_bridge plugin`). The comments in the template above are not required. + +An example of the permission dialog on iOS 18, requesting access to **add-only** to the photo library without specifying the album name: + +iOS dialog requesting permission to add photos + +An example of the permission dialog on iOS 18, requesting +access to **read-write** when the app already has **add-only**, **read-write** is required when specifying the album name: + +iOS dialog requesting read-write permission to the photos library + +> [!TIP] +> If you've followed the [image_picker iOS setup](https://pub.dev/packages/image_picker#ios) instructions, you might have already added the `NSPhotoLibraryUsageDescription` key. + +#### macOS + +> [!IMPORTANT] +> This feature is supported on **macOS 10.15 and later**, currently, [the minimum supported version by Flutter is `10.14`](https://docs.flutter.dev/reference/supported-platforms). Use `isSupported()` to check before calling this method to avoid runtime exception. + +To save images to the gallery, the app needs permission, and the required permission depends on the **macOS version** and **whether the album name was specified**: + +* `NSPhotoLibraryAddUsageDescription`: Permission to add images to the photo library, labeled as `Privacy - Photo Library Additions Usage Description` in Xcode. This key is available only on **macOS 11 and later** and is requested at runtime if no album name is specified, otherwise, it requests read-write permission (`NSPhotoLibraryUsageDescription`). +* `NSPhotoLibraryUsageDescription`: Read-write permission to the photos library, labeled as `Privacy - Photo Library Usage Description` in Xcode. This key has been available since **macOS 10.14 (Mojave)** and is requested at runtime on **macOS 10.15 and earlier** (as add-only permission is unavailable) and is always requested if the album name is specified, even on **macOS 11 and later**. + +> [!IMPORTANT] +> If the album name was specified, read-write permission (`NSPhotoLibraryUsageDescription`) is always required even on **macOS 11 and later**. + +Open the file `/macos/Runner/Info.plist` and add the following keys inside the `` tag: + +```plist + +NSPhotoLibraryAddUsageDescription +Your description here + + +NSPhotoLibraryUsageDescription +Your description here +``` + +> [!IMPORTANT] +> Replace `Your description here` with an explanation of why your app requires **add-only** or **read-write** access to the photo library (e.g., `Used to demonstrate quill_native_bridge plugin`). The comments in the template above are not required. + +An example of the permission dialog on macOS 14, requesting access to **add-only** to the photo library without specifying the album name: + +macOS dialog requesting permission to add photos + +An example of the permission dialog on macOS 14, requesting +access to **read-write** when the macOS supports **add-only**, but **read-write** is always required when specifying the album name: + +macOS dialog requesting read-write permission to the photos library + +> [!WARNING] +> The permission is **always denied on macOS** while testing if you're running the app with [Android Studio IDE](https://developer.android.com/studio) or [VS Code](https://code.visualstudio.com/) even with the built-in terminal. This restriction is imposed by Apple macOS. However, this is not an issue when running the production app or in development using **Xcode** or **macOS terminal** (`flutter run -d macos`). See [flutter#134191](https://github.com/flutter/flutter/issues/134191) for more details. + +### πŸ’Ύ Saving images + +This functionality differs from [Saving Images to the Gallery](#️-saving-images-to-the-gallery). +Instead of saving directly to the system gallery (the default behavior on mobile platforms). +The behavior varies by platform: + +* **🌐 Web**: Downloads the file directly with the browser. +* **πŸ–₯️ Desktop**: Opens the native save dialog, allowing the user to specify where to save the file without runtime permission. + +> [!NOTE] +> The plugin currently delegates to [file_selector_linux](https://pub.dev/packages/file_selector_linux) on **Linux desktop** or +[file_selector_windows](https://pub.dev/packages/file_selector_windows) on **Microsoft Windows** with the appropriate file +type set. Similarly to [image_picker](https://pub.dev/packages/image_picker#windows-macos-and-linux). + +#### macOS + +The implementation is using [`NSSavePanel`](https://developer.apple.com/documentation/appkit/nssavepanel) which requires an entitlement in sandboxed apps, add the following to `macos/Runner/Release.entitlements` and `macos/Runner/DebugProfile.entitlements`: + +```xml +com.apple.security.files.user-selected.read-write + +``` + +A screenshot of the native save dialog on macOS that's backed by NSSavePanel + +> [!NOTE] +> No runtime permission is required. + +> [!TIP] +> If you've followed the [image_picker macOS setup](https://pub.dev/packages/image_picker#ios) or [file_selector macOS setup](https://pub.dev/packages/file_selector#macos) instructions, you might have already added the `com.apple.security.files.user-selected.read-write` key. + ## 🚧 Experimental This package is in early development despite the version since it previously had the same version as [flutter_quill](https://pub.dev/packages/flutter_quill), now they have been separated. The [Flutter Quill](https://github.com/singerdmx/flutter-quill/tree/master/.github/workflows) publishing workflow releases one stable version for all packages even if no changes were introduced. diff --git a/quill_native_bridge/example/README.md b/quill_native_bridge/example/README.md index d659a55..99d2ec4 100644 --- a/quill_native_bridge/example/README.md +++ b/quill_native_bridge/example/README.md @@ -1,3 +1,5 @@ # πŸͺΆ Quill Native Bridge Example -Demonstrates the usage of [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge) plugin. \ No newline at end of file +Demonstrates the usage of [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge) plugin. + +Refer to [example_test.dart](./test/example_test.dart) for a minimal example of mocking `QuillNativeBridge` for tests. \ No newline at end of file diff --git a/quill_native_bridge/example/android/app/build.gradle b/quill_native_bridge/example/android/app/build.gradle index f69a5f2..3bc64d0 100644 --- a/quill_native_bridge/example/android/app/build.gradle +++ b/quill_native_bridge/example/android/app/build.gradle @@ -11,12 +11,12 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8 + jvmTarget = JavaVersion.VERSION_11 } defaultConfig { diff --git a/quill_native_bridge/example/android/app/src/debug/AndroidManifest.xml b/quill_native_bridge/example/android/app/src/debug/AndroidManifest.xml index 399f698..4d95910 100644 --- a/quill_native_bridge/example/android/app/src/debug/AndroidManifest.xml +++ b/quill_native_bridge/example/android/app/src/debug/AndroidManifest.xml @@ -3,5 +3,5 @@ the Flutter tool needs it to communicate with the running application to allow setting breakpoints, to provide hot reload, etc. --> - + diff --git a/quill_native_bridge/example/android/app/src/main/AndroidManifest.xml b/quill_native_bridge/example/android/app/src/main/AndroidManifest.xml index 5510612..0a519ff 100644 --- a/quill_native_bridge/example/android/app/src/main/AndroidManifest.xml +++ b/quill_native_bridge/example/android/app/src/main/AndroidManifest.xml @@ -1,28 +1,35 @@ + + + + + + + android:icon="@mipmap/ic_launcher" + android:label="quill_native_bridge_example"> + android:name="io.flutter.embedding.android.NormalTheme" + android:resource="@style/NormalTheme" /> - - + + + + android:grantUriPermissions="true"> + - - + + diff --git a/quill_native_bridge/example/android/gradle/wrapper/gradle-wrapper.properties b/quill_native_bridge/example/android/gradle/wrapper/gradle-wrapper.properties index 7bb2df6..e2847c8 100644 --- a/quill_native_bridge/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/quill_native_bridge/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip diff --git a/quill_native_bridge/example/android/settings.gradle b/quill_native_bridge/example/android/settings.gradle index b9e43bd..32ebf80 100644 --- a/quill_native_bridge/example/android/settings.gradle +++ b/quill_native_bridge/example/android/settings.gradle @@ -18,8 +18,8 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.1.0" apply false - id "org.jetbrains.kotlin.android" version "1.8.22" apply false + id "com.android.application" version "8.7.2" apply false + id "org.jetbrains.kotlin.android" version "1.9.0" apply false } include ":app" diff --git a/quill_native_bridge/example/assets/flutter-casual-games-toolkit.webp b/quill_native_bridge/example/assets/flutter-casual-games-toolkit.webp new file mode 100644 index 0000000000000000000000000000000000000000..d197485f87ede2d2640c8c48eccf23856eeb5cfe GIT binary patch literal 29124 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 Q4)e!8{Zk~Y}VsDKEH3Wyj&?;Yuc-aFFK(3B=! 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 D+V;U! literal 0 HcmV?d00001 diff --git a/quill_native_bridge/example/integration_test/integration_test.dart b/quill_native_bridge/example/integration_test/quill_native_bridge_test.dart similarity index 65% rename from quill_native_bridge/example/integration_test/integration_test.dart rename to quill_native_bridge/example/integration_test/quill_native_bridge_test.dart index 82c8203..cc8fc95 100644 --- a/quill_native_bridge/example/integration_test/integration_test.dart +++ b/quill_native_bridge/example/integration_test/quill_native_bridge_test.dart @@ -1,10 +1,11 @@ -import 'package:flutter/services.dart' as services - show Clipboard, ClipboardData; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_compare/image_compare.dart'; import 'package:integration_test/integration_test.dart'; import 'package:quill_native_bridge/quill_native_bridge.dart'; import 'package:quill_native_bridge_example/assets.dart'; +import 'package:quill_native_bridge_example/main.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -15,8 +16,8 @@ void main() { () async { Future verifyImageCopiedToClipboard(String assetPath) async { final imageBytes = await loadAssetFile(assetPath); - await QuillNativeBridge.copyImageToClipboard(imageBytes); - final clipboardImageBytes = await QuillNativeBridge.getClipboardImage(); + await quillNativeBridge.copyImageToClipboard(imageBytes); + final clipboardImageBytes = await quillNativeBridge.getClipboardImage(); final pixelMismatchPercentage = await compareImages(src1: imageBytes, src2: clipboardImageBytes); expect(pixelMismatchPercentage, 0); @@ -34,10 +35,10 @@ void main() { final imageBytes = await loadAssetFile(kFlutterQuillAssetImage); final imageBytes2 = await loadAssetFile(kQuillJsRichTextEditor); - await QuillNativeBridge.copyImageToClipboard(imageBytes); - await QuillNativeBridge.copyImageToClipboard(imageBytes2); + await quillNativeBridge.copyImageToClipboard(imageBytes); + await quillNativeBridge.copyImageToClipboard(imageBytes2); - final clipboardImageBytes = await QuillNativeBridge.getClipboardImage(); + final clipboardImageBytes = await quillNativeBridge.getClipboardImage(); final pixelMismatchPercentage = await compareImages(src1: imageBytes, src2: clipboardImageBytes); expect(pixelMismatchPercentage, isNot(0)); @@ -53,8 +54,8 @@ void main() { test('copying HTML to the clipboard should make it accessible', () async { const htmlToCopy = '

Test Document

This is a sample paragraph with a link and some red text.

  • Item 1
  • Item 2
  • Item 3
Footer content here
'; - await QuillNativeBridge.copyHtmlToClipboard(htmlToCopy); - final clipboardHtml = await QuillNativeBridge.getClipboardHtml(); + await quillNativeBridge.copyHtmlToClipboard(htmlToCopy); + final clipboardHtml = await quillNativeBridge.getClipboardHtml(); expect(htmlToCopy, clipboardHtml); }); @@ -63,10 +64,10 @@ void main() { const html1 = '
HTML
'; const html2 = '
HTML Div
'; - await QuillNativeBridge.copyHtmlToClipboard(html1); - await QuillNativeBridge.copyHtmlToClipboard(html2); + await quillNativeBridge.copyHtmlToClipboard(html1); + await quillNativeBridge.copyHtmlToClipboard(html2); - final clipboardHtml = await QuillNativeBridge.getClipboardHtml(); + final clipboardHtml = await quillNativeBridge.getClipboardHtml(); expect(clipboardHtml, isNot(html1)); expect(clipboardHtml, html2); }); @@ -80,44 +81,43 @@ void main() { // Copy HTML to clipboard before copying an image - await QuillNativeBridge.copyHtmlToClipboard(html); + await quillNativeBridge.copyHtmlToClipboard(html); expect( - await QuillNativeBridge.getClipboardHtml(), + await quillNativeBridge.getClipboardHtml(), html, ); // Image clipboard item final imageBytes = await loadAssetFile(kFlutterQuillAssetImage); - await QuillNativeBridge.copyImageToClipboard(imageBytes); + await quillNativeBridge.copyImageToClipboard(imageBytes); expect( - await QuillNativeBridge.getClipboardHtml(), + await quillNativeBridge.getClipboardHtml(), null, ); // Copy HTML to clipboard before copying plain text - await QuillNativeBridge.copyHtmlToClipboard(html); + await quillNativeBridge.copyHtmlToClipboard(html); expect( - await QuillNativeBridge.getClipboardHtml(), + await quillNativeBridge.getClipboardHtml(), html, ); // Plain text clipboard item const plainTextExample = 'Flutter Quill'; - services.Clipboard.setData( - const services.ClipboardData(text: plainTextExample), + Clipboard.setData( + const ClipboardData(text: plainTextExample), ); expect( - (await services.Clipboard.getData(services.Clipboard.kTextPlain)) - ?.text, + (await Clipboard.getData(Clipboard.kTextPlain))?.text, plainTextExample, ); expect( - await QuillNativeBridge.getClipboardHtml(), + await quillNativeBridge.getClipboardHtml(), null, ); }, @@ -130,8 +130,8 @@ void main() { () async { const exampleHtml = '
HTML Div
'; - await QuillNativeBridge.copyHtmlToClipboard(exampleHtml); - final clipboardHtml = await QuillNativeBridge.getClipboardHtml(); + await quillNativeBridge.copyHtmlToClipboard(exampleHtml); + final clipboardHtml = await quillNativeBridge.getClipboardHtml(); if (clipboardHtml == null) { fail( @@ -150,4 +150,31 @@ void main() { }, ); }); + + group( + 'saveImageToGallery', + () { + test('throws an error if image bytes are invalid', () async { + if (!(await quillNativeBridge + .isSupported(QuillNativeBridgeFeature.saveImageToGallery))) { + markTestSkipped( + 'The platform $defaultTargetPlatform does not apply to save images to the gallery feature'); + return; + } + await expectLater( + quillNativeBridge.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: const GalleryImageSaveOptions( + name: 'ExampleImageName', + fileExtension: 'png', + albumName: null, + )), + throwsA(isA().having( + (e) => e.code, + 'code', + equals('INVALID_IMAGE'), + )), + ); + }); + }, + ); } diff --git a/quill_native_bridge/example/ios/Runner/Info.plist b/quill_native_bridge/example/ios/Runner/Info.plist index 629de38..dffc101 100644 --- a/quill_native_bridge/example/ios/Runner/Info.plist +++ b/quill_native_bridge/example/ios/Runner/Info.plist @@ -45,5 +45,17 @@ UIApplicationSupportsIndirectInputEvents + + + + NSPhotoLibraryAddUsageDescription + Used to demonstrate quill_native_bridge plugin + + + + + NSPhotoLibraryUsageDescription + Used to demonstrate quill_native_bridge plugin on iOS 13 and earlier or if the album was specified + diff --git a/quill_native_bridge/example/lib/album_name_input_dialog.dart b/quill_native_bridge/example/lib/album_name_input_dialog.dart new file mode 100644 index 0000000..d3056c1 --- /dev/null +++ b/quill_native_bridge/example/lib/album_name_input_dialog.dart @@ -0,0 +1,75 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'cupertino.dart'; + +/// Platforms that require full permission access to the gallery to save an image to an album. +final _albumRequiresAppleReadWritePermission = { + TargetPlatform.iOS, + TargetPlatform.macOS + }.contains(defaultTargetPlatform) && + !kIsWeb; + +class AlbumNameInputDialog extends StatefulWidget { + const AlbumNameInputDialog({super.key}); + + @override + State createState() => _AlbumNameInputDialogState(); +} + +class _AlbumNameInputDialogState extends State { + final TextEditingController _albumNameController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return AlertDialog.adaptive( + title: const Text('Saving to Gallery'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_albumRequiresAppleReadWritePermission) ...[ + const Text( + 'Specifying the album requires read-write permission on iOS / macOS even when add-only permission is available (iOS 14 / macOS 11 and newer).'), + const SizedBox(height: 6) + ], + usesCupertino + ? CupertinoTextField.borderless( + controller: _albumNameController, + placeholder: 'Album name', + ) + : TextField( + controller: _albumNameController, + decoration: const InputDecoration( + hintText: 'Album name', labelText: 'Album name'), + ) + ], + ), + actions: [ + AdaptiveDialogAction( + onPressed: () => Navigator.pop(context, null), + child: const Text('Cancel', textAlign: TextAlign.end), + ), + AdaptiveDialogAction( + onPressed: () => Navigator.pop(context, _albumNameController.text), + child: const Text('Confirm', textAlign: TextAlign.end), + ), + ], + ); + } + + @override + void dispose() { + _albumNameController.dispose(); + super.dispose(); + } +} + +Future showAlbumNameInputDialog( + {required BuildContext context}) async { + final albumName = await showAdaptiveDialog( + context: context, + builder: (context) => const AlbumNameInputDialog(), + ); + return albumName; +} diff --git a/quill_native_bridge/example/lib/assets.dart b/quill_native_bridge/example/lib/assets.dart index 8cdd1ae..93d6346 100644 --- a/quill_native_bridge/example/lib/assets.dart +++ b/quill_native_bridge/example/lib/assets.dart @@ -2,6 +2,9 @@ import 'package:flutter/services.dart' show Uint8List, rootBundle; const kFlutterQuillAssetImage = 'assets/flutter-quill.png'; const kQuillJsRichTextEditor = 'assets/quilljs-rich-text-editor.png'; +const kFlutterCasualGamesToolkit = 'assets/flutter-casual-games-toolkit.webp'; +const kIntroducingFlutter = 'assets/introducing-flutter.jpg'; +const kLoading = 'assets/loading.gif'; Future loadAssetFile(String assetFilePath) async { return (await rootBundle.load(assetFilePath)).buffer.asUint8List(); diff --git a/quill_native_bridge/example/lib/cupertino.dart b/quill_native_bridge/example/lib/cupertino.dart new file mode 100644 index 0000000..6e6a046 --- /dev/null +++ b/quill_native_bridge/example/lib/cupertino.dart @@ -0,0 +1,31 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +final usesCupertino = + {TargetPlatform.macOS, TargetPlatform.iOS}.contains(defaultTargetPlatform); + +class AdaptiveDialogAction extends StatelessWidget { + const AdaptiveDialogAction({ + required this.onPressed, + required this.child, + super.key, + }); + + final VoidCallback? onPressed; + final Widget child; + + @override + Widget build(BuildContext context) { + if (usesCupertino) { + return CupertinoDialogAction( + onPressed: onPressed, + child: child, + ); + } + return TextButton( + onPressed: onPressed, + child: child, + ); + } +} diff --git a/quill_native_bridge/example/lib/main.dart b/quill_native_bridge/example/lib/main.dart index 19d938c..323dd6b 100644 --- a/quill_native_bridge/example/lib/main.dart +++ b/quill_native_bridge/example/lib/main.dart @@ -1,16 +1,18 @@ -import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:quill_native_bridge/quill_native_bridge.dart' - show QuillNativeBridge, QuillNativeBridgeFeature; +import 'package:quill_native_bridge/quill_native_bridge.dart'; +import 'album_name_input_dialog.dart'; import 'assets.dart'; +import 'select_image_dialog.dart'; -void main() { - runApp(const MyApp()); -} +/// Creates a global instance of [QuillNativeBridge], allowing it to be overridden in tests. +QuillNativeBridge quillNativeBridge = QuillNativeBridge(); + +void main() => runApp(const MainApp()); -class MyApp extends StatelessWidget { - const MyApp({super.key}); +class MainApp extends StatelessWidget { + const MainApp({super.key}); @override Widget build(BuildContext context) { @@ -19,8 +21,8 @@ class MyApp extends StatelessWidget { appBar: AppBar( title: const Text('Quill Native Bridge'), ), - body: const Center( - child: Buttons(), + body: const SingleChildScrollView( + child: Center(child: Buttons()), ), ), ); @@ -41,7 +43,7 @@ class Buttons extends StatelessWidget { ), const SizedBox(height: 50), ElevatedButton.icon( - onPressed: () => _onButtonClick( + onPressed: () => _onButtonPressed( QuillNativeBridgeFeature.isIOSSimulator, context: context, ), @@ -49,7 +51,7 @@ class Buttons extends StatelessWidget { icon: const Icon(Icons.apple), ), ElevatedButton.icon( - onPressed: () => _onButtonClick( + onPressed: () => _onButtonPressed( QuillNativeBridgeFeature.getClipboardHtml, context: context, ), @@ -57,7 +59,7 @@ class Buttons extends StatelessWidget { icon: const Icon(Icons.html), ), ElevatedButton.icon( - onPressed: () => _onButtonClick( + onPressed: () => _onButtonPressed( QuillNativeBridgeFeature.copyHtmlToClipboard, context: context, ), @@ -65,7 +67,7 @@ class Buttons extends StatelessWidget { icon: const Icon(Icons.copy), ), ElevatedButton.icon( - onPressed: () => _onButtonClick( + onPressed: () => _onButtonPressed( QuillNativeBridgeFeature.copyImageToClipboard, context: context, ), @@ -73,7 +75,7 @@ class Buttons extends StatelessWidget { icon: const Icon(Icons.copy), ), ElevatedButton.icon( - onPressed: () => _onButtonClick( + onPressed: () => _onButtonPressed( QuillNativeBridgeFeature.getClipboardImage, context: context, ), @@ -81,7 +83,7 @@ class Buttons extends StatelessWidget { icon: const Icon(Icons.image), ), ElevatedButton.icon( - onPressed: () => _onButtonClick( + onPressed: () => _onButtonPressed( QuillNativeBridgeFeature.getClipboardGif, context: context, ), @@ -89,194 +91,290 @@ class Buttons extends StatelessWidget { icon: const Icon(Icons.gif), ), ElevatedButton.icon( - onPressed: () => _onButtonClick( + onPressed: () => _onButtonPressed( QuillNativeBridgeFeature.getClipboardFiles, context: context, ), label: const Text('Retrieve Files from Clipboard'), icon: const Icon(Icons.file_open), ), + ElevatedButton.icon( + onPressed: () => _onButtonPressed( + QuillNativeBridgeFeature.openGalleryApp, + context: context, + ), + label: const Text('Open the gallery app'), + icon: const Icon(Icons.photo_album), + ), + ElevatedButton.icon( + onPressed: () => _onButtonPressed( + QuillNativeBridgeFeature.saveImageToGallery, + context: context, + ), + label: const Text('Save image to gallery'), + icon: const Icon(Icons.photo_album), + ), + ElevatedButton.icon( + onPressed: () => _onButtonPressed( + QuillNativeBridgeFeature.saveImage, + context: context, + ), + label: const Text('Save image'), + icon: const Icon(Icons.image), + ), ], ); } +} + +Future _onButtonPressed( + QuillNativeBridgeFeature feature, { + required BuildContext context, +}) async { + final scaffoldMessenger = ScaffoldMessenger.of(context); - Future _onButtonClick( - QuillNativeBridgeFeature feature, { - required BuildContext context, - }) async { - final scaffoldMessenger = ScaffoldMessenger.of(context); + final isFeatureUnsupported = !(await quillNativeBridge.isSupported(feature)); - final isFeatureUnsupported = - !(await QuillNativeBridge.isSupported(feature)); - final isFeatureWebUnsupported = isFeatureUnsupported && kIsWeb; - switch (feature) { - case QuillNativeBridgeFeature.isIOSSimulator: - if (isFeatureUnsupported) { - scaffoldMessenger.showText( - isFeatureWebUnsupported - ? "Can't check if the device is iOS simulator on the web." - : 'Must be on iOS to check if simualtor.', - ); - return; - } - final result = await QuillNativeBridge.isIOSSimulator(); - scaffoldMessenger.showText(result - ? "You're running the app on iOS simulator" - : "You're running the app on real iOS device."); - break; - case QuillNativeBridgeFeature.getClipboardHtml: - if (isFeatureUnsupported) { - scaffoldMessenger.showText( - isFeatureWebUnsupported - ? 'Retrieving HTML from the Clipboard is currently not supported on the web.' - : 'Getting HTML from the Clipboard is not supported on ${defaultTargetPlatform.name}', - ); - return; - } - final result = await QuillNativeBridge.getClipboardHtml(); - if (result == null) { - scaffoldMessenger.showText( - 'The HTML is not available on the clipboard.', - ); - return; - } + switch (feature) { + case QuillNativeBridgeFeature.isIOSSimulator: + if (isFeatureUnsupported) { scaffoldMessenger.showText( - 'HTML from the clipboard: $result', + kIsWeb + ? "Can't check if the device is an iOS simulator on the web." + : 'Available only on iOS to determine if the device is a simulator.', ); - debugPrint('HTML from the clipboard: $result'); - break; - case QuillNativeBridgeFeature.copyHtmlToClipboard: - if (isFeatureUnsupported) { - scaffoldMessenger.showText( - isFeatureWebUnsupported - ? 'Copying HTML to the Clipboard is currently not supported on the web.' - : 'Copying HTML to the Clipboard is not supported on ${defaultTargetPlatform.name}', - ); - return; - } - const html = ''' + return; + } + final result = await quillNativeBridge.isIOSSimulator(); + scaffoldMessenger.showText(result + ? "You're running the app on iOS simulator." + : "You're running the app on a real iOS device."); + break; + case QuillNativeBridgeFeature.getClipboardHtml: + if (isFeatureUnsupported) { + scaffoldMessenger.showText( + kIsWeb + ? 'Retrieving HTML from the clipboard is currently not supported on the web.' + : 'Retrieving HTML from the clipboard is currently not supported on ${defaultTargetPlatform.name}.', + ); + return; + } + final result = await quillNativeBridge.getClipboardHtml(); + if (result == null) { + scaffoldMessenger + .showText('The HTML is not available on the clipboard.'); + return; + } + scaffoldMessenger.showText('HTML from the clipboard: $result'); + debugPrint('HTML from the clipboard: $result'); + break; + case QuillNativeBridgeFeature.copyHtmlToClipboard: + if (isFeatureUnsupported) { + scaffoldMessenger.showText( + kIsWeb + ? 'Copying HTML to the clipboard is not supported on the web.' + : 'Copying HTML to the clipboard is not supported on ${defaultTargetPlatform.name}.', + ); + return; + } + const html = ''' Bold text Italic text Underlined text Red text Highlighted text '''; - await QuillNativeBridge.copyHtmlToClipboard(html); + await quillNativeBridge.copyHtmlToClipboard(html); + scaffoldMessenger.showText('HTML copied to the clipboard: $html'); + break; + case QuillNativeBridgeFeature.copyImageToClipboard: + if (isFeatureUnsupported) { scaffoldMessenger.showText( - 'HTML copied to the clipboard: $html', + kIsWeb + ? 'Copying an image to the clipboard is not supported on web.' + : 'Copying an image to the Clipboard is not supported on ${defaultTargetPlatform.name}.', ); - break; - case QuillNativeBridgeFeature.copyImageToClipboard: - if (isFeatureUnsupported) { - scaffoldMessenger.showText( - isFeatureWebUnsupported - ? 'Copying an image to the clipboard is currently not supported on web.' - : 'Copying an image to the Clipboard is not supported on ${defaultTargetPlatform.name}', - ); - return; - } - final imageBytes = await loadAssetFile(kFlutterQuillAssetImage); - await QuillNativeBridge.copyImageToClipboard(imageBytes); + return; + } + final imageBytes = await loadAssetFile(kFlutterQuillAssetImage); + await quillNativeBridge.copyImageToClipboard(imageBytes); - // Not widely supported but some apps copy the image as a text: - // final file = File( - // '${Directory.systemTemp.path}/clipboard-image.png', - // ); - // await file.create(recursive: true); - // await file.writeAsBytes(imageBytes); - // Clipboard.setData( - // ClipboardData( - // // Currently the Android plugin doesn't support content:// - // text: 'file://${file.absolute.path}', - // ), - // ); + // Not widely supported but some apps copy the image as text: + // final file = File( + // '${Directory.systemTemp.path}/clipboard-image.png', + // ); + // await file.create(recursive: true); + // await file.writeAsBytes(imageBytes); + // Clipboard.setData( + // ClipboardData( + // // Currently the Android plugin doesn't support content:// + // text: 'file://${file.absolute.path}', + // ), + // ); + scaffoldMessenger.showText('Image has been copied to the clipboard.'); + break; + case QuillNativeBridgeFeature.getClipboardImage: + if (isFeatureUnsupported) { scaffoldMessenger.showText( - 'Image has been copied to the clipboard.', + kIsWeb + ? 'Retrieving an image from the clipboard is currently not supported on web.' + : 'Retrieving an image from the clipboard is currently not supported on ${defaultTargetPlatform.name}.', ); - break; - case QuillNativeBridgeFeature.getClipboardImage: - if (isFeatureUnsupported) { - scaffoldMessenger.showText( - isFeatureWebUnsupported - ? 'Retrieving an image from the clipboard is currently not supported on web.' - : 'Retrieving an image from the clipboard is currently not supported on ${defaultTargetPlatform.name}.', - ); - return; - } - final imageBytes = await QuillNativeBridge.getClipboardImage(); - if (imageBytes == null) { - scaffoldMessenger.showText( - 'The image is not available on the clipboard.', - ); - return; - } - if (!context.mounted) { - return; - } - showDialog( - context: context, - builder: (context) => Dialog( - child: Image.memory(imageBytes), - ), + return; + } + final imageBytes = await quillNativeBridge.getClipboardImage(); + if (imageBytes == null) { + scaffoldMessenger + .showText('The image is not available on the clipboard.'); + return; + } + if (!context.mounted) { + return; + } + showDialog( + context: context, + builder: (context) => Dialog( + child: Image.memory(imageBytes), + ), + ); + break; + case QuillNativeBridgeFeature.getClipboardGif: + if (isFeatureUnsupported) { + scaffoldMessenger.showText( + kIsWeb + ? 'Retrieving a gif from the clipboard is not supported on web.' + : 'Retrieving a gif from the clipboard is not supported on ${defaultTargetPlatform.name}.', ); - break; - case QuillNativeBridgeFeature.getClipboardGif: - if (isFeatureUnsupported) { - scaffoldMessenger.showText( - isFeatureWebUnsupported - ? 'Retrieving a gif from the clipboard is currently not supported on web.' - : 'Retrieving a gif from the clipboard is currently not supported on ${defaultTargetPlatform.name}.', - ); - return; - } - final gifBytes = await QuillNativeBridge.getClipboardGif(); - if (gifBytes == null) { - scaffoldMessenger.showText( - 'The gif is not available on the clipboard.', - ); - return; - } - if (!context.mounted) { - return; - } - showDialog( - context: context, - builder: (context) => Dialog( - child: Image.memory(gifBytes), - ), + return; + } + final gifBytes = await quillNativeBridge.getClipboardGif(); + if (gifBytes == null) { + scaffoldMessenger.showText( + 'The gif is not available on the clipboard.', + ); + return; + } + if (!context.mounted) { + return; + } + showDialog( + context: context, + builder: (context) => Dialog( + child: Image.memory(gifBytes), + ), + ); + break; + case QuillNativeBridgeFeature.getClipboardFiles: + if (isFeatureUnsupported) { + scaffoldMessenger.showText( + kIsWeb + ? 'Retrieving files from the clipboard is not supported on web.' + : 'Retrieving files from the clipboard is not supported on ${defaultTargetPlatform.name}.', + ); + return; + } + final files = await quillNativeBridge.getClipboardFiles(); + if (files.isEmpty) { + scaffoldMessenger.showText('There are no files on the clipboard.'); + return; + } + scaffoldMessenger.showText( + '${files.length} Files from the clipboard: ${files.toString()}', + ); + debugPrint('Files from the clipboard: $files'); + break; + case QuillNativeBridgeFeature.openGalleryApp: + if (isFeatureUnsupported) { + scaffoldMessenger.showText( + kIsWeb + ? 'Opening the gallery app is not supported on web.' + : 'Opening the gallery app is not supported on ${defaultTargetPlatform.name}.', + ); + return; + } + await quillNativeBridge.openGalleryApp(); + break; + case QuillNativeBridgeFeature.saveImageToGallery: + if (isFeatureUnsupported) { + scaffoldMessenger.showText( + kIsWeb + ? 'Saving an image to the gallery is not supported on web.' + : 'Saving an image is not supported on ${defaultTargetPlatform.name}.', ); - break; - case QuillNativeBridgeFeature.getClipboardFiles: - if (isFeatureUnsupported) { - scaffoldMessenger.showText( - isFeatureWebUnsupported - ? 'Retrieving files from the clipboard is currently not supported on web.' - : 'Retrieving files from the clipboard is currently not supported on ${defaultTargetPlatform.name}.', - ); - return; - } - final files = await QuillNativeBridge.getClipboardFiles(); - if (files.isEmpty) { - scaffoldMessenger.showText('There are no files on the clipboard.'); - return; - } + return; + } + + if (!context.mounted) return; + final selectedImage = await showSelectImageDialog(context: context); + + if (selectedImage == null) { + scaffoldMessenger.showText('Image save was canceled.'); + return; + } + final imageBytes = await loadAssetFile(selectedImage.assetPath); + + if (!context.mounted) return; + final albumName = await showAlbumNameInputDialog(context: context); + if (albumName == null) { + scaffoldMessenger.showText('Image save was canceled.'); + return; + } + + await quillNativeBridge.saveImageToGallery( + imageBytes, + options: GalleryImageSaveOptions( + name: selectedImage.description, + fileExtension: selectedImage.fileType, + // On iOS and macOS, read-write permission (instead of add-only even when supported) is required to save to an album. + albumName: albumName.isNotEmpty ? albumName : null, + ), + ); + scaffoldMessenger.showText( + 'The image has been saved to the gallery.', + action: SnackBarAction( + label: 'Open Gallery', onPressed: quillNativeBridge.openGalleryApp), + ); + break; + case QuillNativeBridgeFeature.saveImage: + if (isFeatureUnsupported) { scaffoldMessenger.showText( - '${files.length} Files from the clipboard: ${files.toString()}', + kIsWeb + ? 'Saving an image is not supported on web.' + : 'Saving an image is not supported on ${defaultTargetPlatform.name}.', ); - debugPrint('Files from the clipboard: $files'); - break; - } + return; + } + + if (!context.mounted) return; + final selectedImage = await showSelectImageDialog(context: context); + + if (selectedImage == null) { + scaffoldMessenger.showText('Image save was canceled.'); + return; + } + final imageBytes = await loadAssetFile(selectedImage.assetPath); + + final imagePath = (await quillNativeBridge.saveImage( + imageBytes, + options: ImageSaveOptions( + name: selectedImage.description, + fileExtension: selectedImage.fileType, + ), + )) + .filePath; + if (!kIsWeb && imagePath == null) { + scaffoldMessenger.showText('Image save was canceled.'); + return; + } + scaffoldMessenger.showText('The image has been saved at: $imagePath.'); + break; } } extension ScaffoldMessengerX on ScaffoldMessengerState { - void showText(String text) { + void showText(String text, {SnackBarAction? action}) { clearSnackBars(); - showSnackBar( - SnackBar( - content: Text(text), - ), - ); + showSnackBar(SnackBar(content: Text(text), action: action)); } } diff --git a/quill_native_bridge/example/lib/select_image_dialog.dart b/quill_native_bridge/example/lib/select_image_dialog.dart new file mode 100644 index 0000000..d936810 --- /dev/null +++ b/quill_native_bridge/example/lib/select_image_dialog.dart @@ -0,0 +1,75 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'assets.dart'; +import 'cupertino.dart'; + +class ExampleImage { + const ExampleImage({ + required this.assetPath, + required this.description, + }); + + final String assetPath; + final String description; + + String get fileType => assetPath.split('.').last; +} + +const List _images = [ + ExampleImage( + assetPath: kFlutterQuillAssetImage, description: '(PNG) Flutter Quill'), + ExampleImage( + assetPath: kQuillJsRichTextEditor, description: '(PNG) Quill JS'), + ExampleImage( + assetPath: kIntroducingFlutter, description: '(JPG) Introducing Flutter'), + ExampleImage( + assetPath: kFlutterCasualGamesToolkit, + description: '(WEBp) Flutter Casual Games Toolkit'), + ExampleImage(assetPath: kLoading, description: '(GIF) Loading'), +]; + +class SelectImageDialog extends StatelessWidget { + const SelectImageDialog({super.key}); + + @override + Widget build(BuildContext context) { + return AlertDialog.adaptive( + title: const Text('Choose an image'), + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: _images + .map((image) => usesCupertino + ? CupertinoListTile( + title: Text(image.description), + leading: + Image.asset(image.assetPath, width: 50, height: 50), + onTap: () => Navigator.pop(context, image), + ) + : ListTile( + title: Text(image.description), + leading: + Image.asset(image.assetPath, width: 50, height: 50), + onTap: () => Navigator.pop(context, image), + )) + .toList(), + ), + ), + actions: [ + AdaptiveDialogAction( + onPressed: () => Navigator.pop(context, null), + child: const Text('Cancel', textAlign: TextAlign.end), + ), + ], + ); + } +} + +Future showSelectImageDialog({ + required BuildContext context, +}) => + showAdaptiveDialog( + context: context, + builder: (context) => const SelectImageDialog(), + ); diff --git a/quill_native_bridge/example/linux/flutter/generated_plugin_registrant.cc b/quill_native_bridge/example/linux/flutter/generated_plugin_registrant.cc index e71a16d..64a0ece 100644 --- a/quill_native_bridge/example/linux/flutter/generated_plugin_registrant.cc +++ b/quill_native_bridge/example/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); + file_selector_plugin_register_with_registrar(file_selector_linux_registrar); } diff --git a/quill_native_bridge/example/linux/flutter/generated_plugins.cmake b/quill_native_bridge/example/linux/flutter/generated_plugins.cmake index 2e1de87..2db3c22 100644 --- a/quill_native_bridge/example/linux/flutter/generated_plugins.cmake +++ b/quill_native_bridge/example/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + file_selector_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/quill_native_bridge/example/macos/Runner/DebugProfile.entitlements b/quill_native_bridge/example/macos/Runner/DebugProfile.entitlements index dddb8a3..228c4fb 100644 --- a/quill_native_bridge/example/macos/Runner/DebugProfile.entitlements +++ b/quill_native_bridge/example/macos/Runner/DebugProfile.entitlements @@ -8,5 +8,10 @@ com.apple.security.network.server + + + com.apple.security.files.user-selected.read-write + + diff --git a/quill_native_bridge/example/macos/Runner/Info.plist b/quill_native_bridge/example/macos/Runner/Info.plist index 4789daa..0d51545 100644 --- a/quill_native_bridge/example/macos/Runner/Info.plist +++ b/quill_native_bridge/example/macos/Runner/Info.plist @@ -28,5 +28,17 @@ MainMenu NSPrincipalClass NSApplication + + + + NSPhotoLibraryAddUsageDescription + Used to demonstrate quill_native_bridge plugin + + + + + NSPhotoLibraryUsageDescription + Used to demonstrate quill_native_bridge plugin on macOS 10.15 and earlier or if the album was specified + diff --git a/quill_native_bridge/example/macos/Runner/Release.entitlements b/quill_native_bridge/example/macos/Runner/Release.entitlements index 852fa1a..3c7a62f 100644 --- a/quill_native_bridge/example/macos/Runner/Release.entitlements +++ b/quill_native_bridge/example/macos/Runner/Release.entitlements @@ -4,5 +4,10 @@ com.apple.security.app-sandbox + + + com.apple.security.files.user-selected.read-write + + diff --git a/quill_native_bridge/example/pubspec.lock b/quill_native_bridge/example/pubspec.lock index 72131bf..f1d5d3a 100644 --- a/quill_native_bridge/example/pubspec.lock +++ b/quill_native_bridge/example/pubspec.lock @@ -1,6 +1,27 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + url: "https://pub.dev" + source: hosted + version: "76.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.3" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + url: "https://pub.dev" + source: hosted + version: "6.11.0" archive: dependency: transitive description: @@ -9,6 +30,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.6.1" + args: + dependency: transitive + description: + name: args + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + url: "https://pub.dev" + source: hosted + version: "2.6.0" async: dependency: transitive description: @@ -25,6 +54,70 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" + url: "https://pub.dev" + source: hosted + version: "2.4.13" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 + url: "https://pub.dev" + source: hosted + version: "7.3.2" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb + url: "https://pub.dev" + source: hosted + version: "8.9.2" characters: dependency: transitive description: @@ -33,6 +126,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" clock: dependency: transitive description: @@ -41,6 +142,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + url: "https://pub.dev" + source: hosted + version: "4.10.1" collection: dependency: transitive description: @@ -49,6 +158,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.0" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.dev" + source: hosted + version: "0.3.4+2" crypto: dependency: transitive description: @@ -57,6 +182,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.6" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" + url: "https://pub.dev" + source: hosted + version: "2.3.7" fake_async: dependency: transitive description: @@ -81,6 +214,38 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.1" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" + url: "https://pub.dev" + source: hosted + version: "0.9.3+2" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.dev" + source: hosted + version: "2.6.2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "8f5d2f6590d51ecd9179ba39c64f722edc15226cc93dcc8698466ad36a4a85a4" + url: "https://pub.dev" + source: hosted + version: "0.9.3+3" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -109,11 +274,59 @@ packages: description: flutter source: sdk version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter source: sdk version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + http: + dependency: transitive + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360" + url: "https://pub.dev" + source: hosted + version: "4.1.1" image: dependency: transitive description: @@ -135,6 +348,30 @@ packages: description: flutter source: sdk version: "0.0.0" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + js: + dependency: transitive + description: + name: js + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + url: "https://pub.dev" + source: hosted + version: "0.7.1" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" leak_tracker: dependency: transitive description: @@ -167,6 +404,22 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + macros: + dependency: transitive + description: + name: macros + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" + url: "https://pub.dev" + source: hosted + version: "0.1.3-main.0" matcher: dependency: transitive description: @@ -191,6 +444,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.15.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + mockito: + dependency: "direct dev" + description: + name: mockito + sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" + url: "https://pub.dev" + source: hosted + version: "5.4.4" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: @@ -223,6 +500,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" process: dependency: transitive description: @@ -231,67 +516,107 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.3" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + url: "https://pub.dev" + source: hosted + version: "1.3.0" quill_native_bridge: dependency: "direct main" description: path: ".." relative: true source: path - version: "10.7.11" + version: "11.0.0" quill_native_bridge_android: dependency: "direct overridden" description: path: "../../quill_native_bridge_android" relative: true source: path - version: "0.0.1-dev.5" + version: "0.0.1" quill_native_bridge_ios: dependency: "direct overridden" description: path: "../../quill_native_bridge_ios" relative: true source: path - version: "0.0.1-dev.6" + version: "0.0.1" quill_native_bridge_linux: dependency: "direct overridden" description: path: "../../quill_native_bridge_linux" relative: true source: path - version: "0.0.1-dev.4" + version: "0.0.1" quill_native_bridge_macos: dependency: "direct overridden" description: path: "../../quill_native_bridge_macos" relative: true source: path - version: "0.0.1-dev.5" + version: "0.0.1" quill_native_bridge_platform_interface: dependency: "direct overridden" description: path: "../../quill_native_bridge_platform_interface" relative: true source: path - version: "0.0.1-dev.5" + version: "0.0.1" quill_native_bridge_web: dependency: "direct overridden" description: path: "../../quill_native_bridge_web" relative: true source: path - version: "0.0.1-dev.6" + version: "0.0.1" quill_native_bridge_windows: dependency: "direct overridden" description: path: "../../quill_native_bridge_windows" relative: true source: path - version: "0.0.1-dev.4" + version: "0.0.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 + url: "https://pub.dev" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.0" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.dev" + source: hosted + version: "1.5.0" source_span: dependency: transitive description: @@ -316,6 +641,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -348,6 +681,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.3" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" typed_data: dependency: transitive description: @@ -380,6 +721,14 @@ packages: url: "https://pub.dev" source: hosted version: "14.3.1" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" web: dependency: transitive description: @@ -388,6 +737,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + url: "https://pub.dev" + source: hosted + version: "3.0.1" webdriver: dependency: transitive description: @@ -400,10 +765,10 @@ packages: dependency: transitive description: name: win32 - sha256: "84ba388638ed7a8cb3445a320c8273136ab2631cd5f2c57888335504ddab1bc2" + sha256: "8b338d4486ab3fbc0ba0db9f9b4f5239b6697fcee427939a40e720cbb9ee0a69" url: "https://pub.dev" source: hosted - version: "5.8.0" + version: "5.9.0" xml: dependency: transitive description: @@ -412,6 +777,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.5.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" sdks: dart: ">=3.6.0-0 <4.0.0" flutter: ">=3.24.0" diff --git a/quill_native_bridge/example/pubspec.yaml b/quill_native_bridge/example/pubspec.yaml index c9dce92..7f034b1 100644 --- a/quill_native_bridge/example/pubspec.yaml +++ b/quill_native_bridge/example/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: flutter: sdk: flutter - quill_native_bridge: ^10.7.10 + quill_native_bridge: ^11.0.0 dependency_overrides: quill_native_bridge: @@ -35,10 +35,10 @@ dev_dependencies: sdk: flutter flutter_test: sdk: flutter - flutter_lints: ^5.0.0 - image_compare: ^1.1.2 + mockito: ^5.4.4 + build_runner: ^2.4.13 flutter: uses-material-design: true diff --git a/quill_native_bridge/example/test/example_test.dart b/quill_native_bridge/example/test/example_test.dart new file mode 100644 index 0000000..2232bd6 --- /dev/null +++ b/quill_native_bridge/example/test/example_test.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:quill_native_bridge/quill_native_bridge.dart'; +import 'package:quill_native_bridge_example/main.dart'; + +@GenerateMocks([QuillNativeBridge]) +import 'example_test.mocks.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + late MockQuillNativeBridge mockQuillNativeBridge; + + setUp(() { + mockQuillNativeBridge = MockQuillNativeBridge(); + quillNativeBridge = mockQuillNativeBridge; + }); + + testWidgets( + 'pressing the `Is iOS Simulator` button shows a $SnackBar with the correct text on iOS devices', + (tester) async { + await tester.pumpWidget(const MainApp()); + + Future runIsIOSSimulatorTest( + {required bool isIOSSimulator, expectedSnackbarMessage}) async { + when(mockQuillNativeBridge + .isSupported(QuillNativeBridgeFeature.isIOSSimulator)) + .thenAnswer((_) async => true); + + when(mockQuillNativeBridge.isIOSSimulator()) + .thenAnswer((_) async => isIOSSimulator); + + final isIOSButton = find.text('Is iOS Simulator'); + + expect(isIOSButton, findsOneWidget); + + await tester.tap(isIOSButton); + await tester.pump(); + + expect(find.text(expectedSnackbarMessage), findsOneWidget); + } + + await runIsIOSSimulatorTest( + isIOSSimulator: true, + expectedSnackbarMessage: "You're running the app on iOS simulator.", + ); + await runIsIOSSimulatorTest( + isIOSSimulator: false, + expectedSnackbarMessage: "You're running the app on a real iOS device.", + ); + }, + ); + + testWidgets( + 'pressing the `Is iOS Simulator` button shows a $SnackBar with the correct text on non-iOS devices', + (tester) async { + await tester.pumpWidget(const MainApp()); + + when(mockQuillNativeBridge + .isSupported(QuillNativeBridgeFeature.isIOSSimulator)) + .thenAnswer((_) async => false); + + final isIOSButton = find.text('Is iOS Simulator'); + + expect(isIOSButton, findsOneWidget); + + await tester.tap(isIOSButton); + await tester.pump(); + + expect( + find.text( + 'Available only on iOS to determine if the device is a simulator.'), + findsOneWidget, + ); + }); +} diff --git a/quill_native_bridge/example/test/example_test.mocks.dart b/quill_native_bridge/example/test/example_test.mocks.dart new file mode 100644 index 0000000..6479745 --- /dev/null +++ b/quill_native_bridge/example/test/example_test.mocks.dart @@ -0,0 +1,168 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in quill_native_bridge_example/test/example_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:typed_data' as _i5; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:quill_native_bridge/quill_native_bridge.dart' as _i3; +import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart' + as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeImageSaveResult_0 extends _i1.SmartFake + implements _i2.ImageSaveResult { + _FakeImageSaveResult_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [QuillNativeBridge]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockQuillNativeBridge extends _i1.Mock implements _i3.QuillNativeBridge { + MockQuillNativeBridge() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future isSupported(_i2.QuillNativeBridgeFeature? feature) => + (super.noSuchMethod( + Invocation.method( + #isSupported, + [feature], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future isIOSSimulator() => (super.noSuchMethod( + Invocation.method( + #isIOSSimulator, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future getClipboardHtml() => (super.noSuchMethod( + Invocation.method( + #getClipboardHtml, + [], + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future copyHtmlToClipboard(String? html) => (super.noSuchMethod( + Invocation.method( + #copyHtmlToClipboard, + [html], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future copyImageToClipboard(_i5.Uint8List? imageBytes) => + (super.noSuchMethod( + Invocation.method( + #copyImageToClipboard, + [imageBytes], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future<_i5.Uint8List?> getClipboardImage() => (super.noSuchMethod( + Invocation.method( + #getClipboardImage, + [], + ), + returnValue: _i4.Future<_i5.Uint8List?>.value(), + ) as _i4.Future<_i5.Uint8List?>); + + @override + _i4.Future<_i5.Uint8List?> getClipboardGif() => (super.noSuchMethod( + Invocation.method( + #getClipboardGif, + [], + ), + returnValue: _i4.Future<_i5.Uint8List?>.value(), + ) as _i4.Future<_i5.Uint8List?>); + + @override + _i4.Future> getClipboardFiles() => (super.noSuchMethod( + Invocation.method( + #getClipboardFiles, + [], + ), + returnValue: _i4.Future>.value([]), + ) as _i4.Future>); + + @override + _i4.Future openGalleryApp() => (super.noSuchMethod( + Invocation.method( + #openGalleryApp, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future saveImageToGallery( + _i5.Uint8List? imageBytes, { + required _i2.GalleryImageSaveOptions? options, + }) => + (super.noSuchMethod( + Invocation.method( + #saveImageToGallery, + [imageBytes], + {#options: options}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future<_i2.ImageSaveResult> saveImage( + _i5.Uint8List? imageBytes, { + required _i2.ImageSaveOptions? options, + }) => + (super.noSuchMethod( + Invocation.method( + #saveImage, + [imageBytes], + {#options: options}, + ), + returnValue: + _i4.Future<_i2.ImageSaveResult>.value(_FakeImageSaveResult_0( + this, + Invocation.method( + #saveImage, + [imageBytes], + {#options: options}, + ), + )), + ) as _i4.Future<_i2.ImageSaveResult>); +} diff --git a/quill_native_bridge/example/test_driver/integration_test.dart b/quill_native_bridge/example/test_driver/integration_test.dart new file mode 100644 index 0000000..b38629c --- /dev/null +++ b/quill_native_bridge/example/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/quill_native_bridge/example/windows/flutter/generated_plugin_registrant.cc b/quill_native_bridge/example/windows/flutter/generated_plugin_registrant.cc index 8b6d468..77ab7a0 100644 --- a/quill_native_bridge/example/windows/flutter/generated_plugin_registrant.cc +++ b/quill_native_bridge/example/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); } diff --git a/quill_native_bridge/example/windows/flutter/generated_plugins.cmake b/quill_native_bridge/example/windows/flutter/generated_plugins.cmake index b93c4c3..a423a02 100644 --- a/quill_native_bridge/example/windows/flutter/generated_plugins.cmake +++ b/quill_native_bridge/example/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + file_selector_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/quill_native_bridge/lib/quill_native_bridge.dart b/quill_native_bridge/lib/quill_native_bridge.dart index e174359..f80b821 100644 --- a/quill_native_bridge/lib/quill_native_bridge.dart +++ b/quill_native_bridge/lib/quill_native_bridge.dart @@ -2,104 +2,208 @@ /// package to access platform-specific APIs. library; -import 'package:flutter/foundation.dart' - show TargetPlatform, Uint8List, defaultTargetPlatform, kIsWeb; +import 'package:flutter/foundation.dart'; import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; -export 'package:quill_native_bridge_platform_interface/src/platform_feature.dart' - show QuillNativeBridgeFeature; +export 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart' + show + QuillNativeBridgeFeature, + ImageSaveOptions, + GalleryImageSaveOptions, + ImageSaveResult; /// An internal plugin for [`flutter_quill`](https://pub.dev/packages/flutter_quill) /// package to access platform-specific APIs. /// /// Use [QuillNativeBridge.isSupported] to check whether a feature is supported. -abstract final class QuillNativeBridge { +class QuillNativeBridge { + /// The platform interface that drives this plugin. static QuillNativeBridgePlatform get _platform => QuillNativeBridgePlatform.instance; - /// Check if the app is running on [iOS Simulator](https://developer.apple.com/documentation/xcode/running-your-app-in-simulator-or-on-a-device). - /// - /// Should only be called when [defaultTargetPlatform] - /// is [TargetPlatform.iOS] and [kIsWeb] is `false`. - static Future isIOSSimulator() => _platform.isIOSSimulator(); - /// Checks if the specified [feature] is supported in the current implementation. /// - /// Will verify if this is supported in the platform itself: + /// Will verify if the platform supports this feature, the platform + /// implementation of the plugin, and the current running OS version. + /// + /// For example if [feature] is: /// - /// - If [feature] is supported on **Android API 21** (as an example) and the - /// current Android API is `19` then will return `false` - /// - If [feature] is supported on the web if Clipboard API (as another example) + /// - Supported on **Android API 21** (as an example) and the + /// current Android API is `19` then will return `false`. + /// + /// - Supported on the web if Clipboard API (as another example) /// available in the current browser, and the current browser doesn't support it, /// will return `false` too. For this specific example, you will need /// to fallback to **Clipboard events** on **Firefox** or browsers that doesn't /// support **Clipboard API**. /// - /// Always check the docs of the method you're calling to see if there - /// are special notes. + /// - Supported by the platform itself but the plugin currently implements it, + /// then return `false`. + /// + /// Always review the doc comment of a method before use for special notes. /// - /// Also see: [QuillNativeBridgeFeature] - static Future isSupported(QuillNativeBridgeFeature feature) => + /// See also: [QuillNativeBridgeFeature] + Future isSupported(QuillNativeBridgeFeature feature) => _platform.isSupported(feature); - /// Return HTML from the Clipboard. + /// Checks if the app runs on [iOS Simulator](https://developer.apple.com/documentation/xcode/running-your-app-in-simulator-or-on-a-device). + /// + /// Should be called only on an iOS app. + Future isIOSSimulator() => _platform.isIOSSimulator(); + + /// Returns a HTML from the system clipboard. The HTML can be platform-dependent. /// /// **Important for web**: If [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) /// is not supported on the web browser, should fallback to [Clipboard Events](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent) /// such as the [paste_event](https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event). /// - /// The HTML can be platform-dependent. - /// /// Returns `null` if the HTML content is not available or if the user has not granted - /// permission for pasting (on some platforms such as iOS). - /// - /// Currently only supports **Android**, **iOS**, **macOS**, **Windows**, **Linux**, and the **Web**. - static Future getClipboardHtml() => _platform.getClipboardHtml(); + /// permission for pasting on iOS. + @Category(['Clipboard']) + Future getClipboardHtml() => _platform.getClipboardHtml(); - /// Copy the [html] to the clipboard to be pasted on other apps. + /// Copies an HTML to the system clipboard to be pasted on other apps. /// - /// **Important for web**: If [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) - /// is not supported on the web browser, should fallback to [Clipboard Events](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent) - /// such as the [copy_event](https://developer.mozilla.org/en-US/docs/Web/API/Element/copy_event). - /// - /// Currently only supports **Android**, **iOS**, **macOS**, **Linux**, **Windows** and the **Web**. - static Future copyHtmlToClipboard(String html) => + /// **Important for web**: Should fallback to [Clipboard Events](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent) + /// if [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) is unsupported, + /// not available or restricted (the case for Firefox and Safari). See [copy_event](https://developer.mozilla.org/en-US/docs/Web/API/Element/copy_event). + @Category(['Clipboard']) + Future copyHtmlToClipboard(String html) => _platform.copyHtmlToClipboard(html); - /// Copy the [imageBytes] to Clipboard to be pasted on other apps. + /// Copies an image to the system clipboard to be pasted on other apps. /// - /// Require modifying `AndroidManifest.xml` to work on **Android**. - /// Otherwise, you will get a warning available only on debug-builds. - /// See: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge#-platform-configuration + /// Requires modifying `AndroidManifest.xml` to work on **Android**. + /// See [Copying images to the system clipboard](https://pub.dev/packages/quill_native_bridge#-copying-images-to-the-system-clipboard). /// /// **Important for web**: If [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) /// is not supported on the web browser, should fallback to [Clipboard Events](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent) /// such as the [copy_event](https://developer.mozilla.org/en-US/docs/Web/API/Element/copy_event). /// - /// - /// Currently only supports **Android**, **iOS**, **macOS**, **Linux**, and the **Web**. - static Future copyImageToClipboard(Uint8List imageBytes) => + /// Currently, it's not supported on **Windows**. + @Category(['Clipboard']) + Future copyImageToClipboard(Uint8List imageBytes) => _platform.copyImageToClipboard(imageBytes); - /// Return the copied image from the Clipboard. + /// Returns the copied image from the system clipboard. /// /// **Important for web**: If [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) /// is not supported on the web browser, should fallback to [Clipboard Events](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent) /// such as the [paste_event](https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event). /// - /// Currently only supports **Android**, **iOS**, **macOS**, **Linux**, and the **Web**. - static Future getClipboardImage() => - _platform.getClipboardImage(); + /// Currently, it's not supported on **Windows**. + @Category(['Clipboard']) + Future getClipboardImage() => _platform.getClipboardImage(); - /// Return the copied gif from the Clipboard. + /// Returns the copied GIF image from the system clipboard. /// - /// Currently only supports **Android**, **iOS**. - static Future getClipboardGif() => _platform.getClipboardGif(); + /// **Supports Android and iOS only.** + @Category(['Clipboard']) + Future getClipboardGif() => _platform.getClipboardGif(); - /// Return the file paths from the Clipboard. + /// Returns the file paths from the system clipboard. /// - /// Currently only supports **macOS** and **Linux**. - static Future> getClipboardFiles() => - _platform.getClipboardFiles(); + /// Supports **macOS** and **Linux**. + /// **Windows** and the web are currently unsupported. + @Category(['Clipboard']) + Future> getClipboardFiles() => _platform.getClipboardFiles(); + + /// Opens the system gallery app. + /// **Supports Android, iOS, Windows and macOS only.** + /// + /// Calling this on unsupported platforms will throw [UnimplementedError]. + @Category(['Gallery']) + Future openGalleryApp() => _platform.openGalleryApp(); + + /// Saves an image to the gallery app on supported platforms. + /// **Supports Android, iOS, and macOS**. + /// + /// **Requires Android, iOS and macOS setup.** + /// See [Saving images to the gallery](https://pub.dev/packages/quill_native_bridge#-saving-images-to-the-gallery) + /// for more details. + /// + /// Requests necessary permission if not + /// already granted on Android 9 (API 28) and earlier, iOS, and macOS. + /// On Android 10 (Api 29) and later, the plugin makes use + /// of the [Android scoped storage](https://source.android.com/docs/core/storage/scoped). + /// + /// NOTE: On macOS, permission is denied if the app is running using + /// sources other than Xcode or macOS terminal such as Android Studio or VS Code. + /// However, this does not affect the final production app. + /// + /// The [GalleryImageSaveOptions.name] is the image's name without the extension (e.g., `image`). + /// It doesn't need to be unique, as it's handled by the gallery/system. + /// + /// The [GalleryImageSaveOptions.fileExtension] is the image's file extension (e.g., `png`). + /// This is silently ignored on macOS and iOS. + /// On Android 10 (API 29) and later, it determines the image MIME type. + /// On Android 9 (API 28) and earlier, it is used as the file name + /// and to extract the MIME type. + /// + /// The [GalleryImageSaveOptions.albumName] sets the album in the gallery app. + /// A new album will be created if it doesn't exist. + /// If `null`, the default album is used. + /// **If not `null`, read-write access to the photos library is always + /// required on iOS and macOS (even on newer versions where add-only is supported).** + /// + /// Calling this on unsupported platforms will throw [UnimplementedError]. + /// Calling this on **macOS 10.14 and earlier** will throw [UnsupportedError] (unsupported by the platform). + /// + /// Use [isSupported] to check before calling: + /// + /// ```dart + /// if (await isSupported(QuillNativeBridgeFeature.saveImageToGallery)) { + /// // The method saveImageToGallery() is both implemented and supported by the device / OS version. + /// // Call saveImageToGallery() + /// } + /// ``` + /// + /// See also [saveImage] to save the image on desktop and web platforms. + @Category(['Gallery']) + Future saveImageToGallery( + Uint8List imageBytes, { + required GalleryImageSaveOptions options, + }) => + _platform.saveImageToGallery(imageBytes, options: options); + + /// Saves an image to the user's device based on the platform: + /// + /// - **Web**: Downloads the image using the browser's download functionality. + /// - **macOS**: Opens the native save dialog using [`NSSavePanel`](https://developer.apple.com/documentation/appkit/nssavepanel), + /// defaulting to the user's `Pictures` directory. + /// **Requires platform setup**. Refer to [Saving images](pub.dev/packages/quill_native_bridge#-saving-images). + /// - **Linux** and **Windows**: Opens the native save dialog, defaulting to the user's `Pictures` directory. + /// The plugin delegates to [file_selector_linux](https://pub.dev/packages/file_selector_linux) or + /// [file_selector_windows](https://pub.dev/packages/file_selector_windows) with the appropriate file + /// type set. + /// + /// Not supported on mobile platforms (use [saveImageToGallery] instead). + /// Calling this on unsupported platforms will throw [UnimplementedError]. + /// + /// The [ImageSaveOptions.name] represents the image name without the extension (e.g., `image`). + /// On web, the browser handles name conflicts. + /// On macOS and Windows, prompts the user to confirm file overwrite. + /// On Linux, behavior depends on the desktop environment (e.g., Gnome, KDE), + /// and **file overwrite confirmation may be skipped**. + /// + /// The [ImageSaveOptions.fileExtension] specifies the file extension (e.g., `png`) + /// for saving the image on all platforms. + /// Also used to determine the MIME type on Linux and the web. + /// + /// Returns [ImageSaveResult] where: + /// + /// * [ImageSaveResult.filePath]: For desktop platforms, `null` if the user + /// cancels the operation while selecting the destination using the system file picker. + /// Always `null` on web platforms. + /// + /// * [ImageSaveResult.blobUrl]: For web platforms, returns the blob object URL (e.g., `blob:http://localhost:64030/e58f63d4-2890-469c-9c8e-69e839da6a93`), + /// **which will be revoked before returning it**. Always `null` on non-web platforms. + /// + /// See also [saveImageToGallery] for platforms with a native gallery app. + Future saveImage( + Uint8List imageBytes, { + required ImageSaveOptions options, + }) => + _platform.saveImage(imageBytes, options: options); } diff --git a/quill_native_bridge/pubspec.yaml b/quill_native_bridge/pubspec.yaml index ee0f917..48f4d1e 100644 --- a/quill_native_bridge/pubspec.yaml +++ b/quill_native_bridge/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge -description: "An internal plugin for flutter_quill package to access platform-specific APIs" -version: 10.7.11 +description: "An internal Flutter plugin for flutter_quill package to access platform-specific APIs" +version: 11.0.0 homepage: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge repository: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge issue_tracker: https://github.com/FlutterQuill/quill-native-bridge/issues @@ -14,18 +14,21 @@ environment: dependencies: flutter: sdk: flutter - quill_native_bridge_android: ^0.0.1-dev.5 - quill_native_bridge_platform_interface: ^0.0.1-dev.5 - quill_native_bridge_web: ^0.0.1-dev.6 - quill_native_bridge_windows: ^0.0.1-dev.4 - quill_native_bridge_linux: ^0.0.1-dev.4 - quill_native_bridge_ios: ^0.0.1-dev.6 - quill_native_bridge_macos: ^0.0.1-dev.5 + quill_native_bridge_android: ^0.0.1 + quill_native_bridge_platform_interface: ^0.0.1 + quill_native_bridge_web: ^0.0.1 + quill_native_bridge_windows: ^0.0.1 + quill_native_bridge_linux: ^0.0.1 + quill_native_bridge_ios: ^0.0.1 + quill_native_bridge_macos: ^0.0.1 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 + mockito: ^5.4.4 + build_runner: ^2.4.13 + plugin_platform_interface: ^2.1.8 flutter: plugin: @@ -41,4 +44,4 @@ flutter: windows: default_package: quill_native_bridge_windows linux: - default_package: quill_native_bridge_linux \ No newline at end of file + default_package: quill_native_bridge_linux diff --git a/quill_native_bridge/readme_assets/android_9_write_to_external_storage_permission_dialog.png b/quill_native_bridge/readme_assets/android_9_write_to_external_storage_permission_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea0f05d577dd4d15ca13702ca3c5bb06924046d GIT binary patch literal 17947 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 literal 0 HcmV?d00001 diff --git a/quill_native_bridge/readme_assets/ios_add_to_photos_permission_dialog.png b/quill_native_bridge/readme_assets/ios_add_to_photos_permission_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..3d58634f3a4cd268204d74dc86055b9f7bed9552 GIT binary patch literal 45060 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ÛhkhZQ~~bssC`FlSrC;IUsb_ubN|BrV%)^ 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≠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 F3~BYIn_TEm-f=g1Y_ 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 Y%5>@>s{1oPFb%)&15ef;zx31p0Nzq5HUIzs literal 0 HcmV?d00001 diff --git a/quill_native_bridge/readme_assets/macos_add_to_photos_with_album_read_write_permission_dialog.png b/quill_native_bridge/readme_assets/macos_add_to_photos_with_album_read_write_permission_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..ff61df1600fd061f031da5dc40f3a81fa16c3710 GIT binary patch literal 68580 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%0DHUM%qpmVgBRWVsh;K_=*6q=8E$w8& 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�|sPc^J( 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 L*n_Q6f4llW#=8A^ literal 0 HcmV?d00001 diff --git a/quill_native_bridge/test/quill_native_bridge_test.dart b/quill_native_bridge/test/quill_native_bridge_test.dart new file mode 100644 index 0000000..1c33922 --- /dev/null +++ b/quill_native_bridge/test/quill_native_bridge_test.dart @@ -0,0 +1,248 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:quill_native_bridge/quill_native_bridge.dart'; +import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; + +@GenerateMocks([], customMocks: [MockSpec()]) +import 'quill_native_bridge_test.mocks.dart' as base_mock; + +// Add the mixin to make the platform interface accept the mock. +// For more details, refer to https://pub.dev/packages/plugin_platform_interface#mocking-or-faking-platform-interfaces +class _MockQuillNativeBridgePlatform extends base_mock + .MockQuillNativeBridgePlatform with MockPlatformInterfaceMixin {} + +void main() { + final plugin = QuillNativeBridge(); + late _MockQuillNativeBridgePlatform mockQuillNativeBridgePlatform; + + setUp(() { + mockQuillNativeBridgePlatform = _MockQuillNativeBridgePlatform(); + + QuillNativeBridgePlatform.instance = mockQuillNativeBridgePlatform; + }); + + group('isSupported', () { + test( + 'returns correct value based on platform implementation', + () async { + for (final isSupported in {true, false}) { + const exampleFeature = QuillNativeBridgeFeature.isIOSSimulator; + when(mockQuillNativeBridgePlatform.isSupported(exampleFeature)) + .thenAnswer((_) async => isSupported); + + final result = await plugin.isSupported(exampleFeature); + verify(mockQuillNativeBridgePlatform.isSupported(exampleFeature)) + .called(1); + expect(result, isSupported); + } + }, + ); + + test( + 'passes the $QuillNativeBridgeFeature correctly to the platform implementation', + () async { + for (final feature in QuillNativeBridgeFeature.values) { + when(mockQuillNativeBridgePlatform.isSupported(any)) + .thenAnswer((_) async => false); + + await plugin.isSupported(feature); + verify(mockQuillNativeBridgePlatform.isSupported(feature)).called(1); + } + }, + ); + }); + + test('isIOSSimulator returns correct value based on platform implementation', + () async { + for (final isSimulator in {true, false}) { + when(mockQuillNativeBridgePlatform.isIOSSimulator()) + .thenAnswer((_) async => isSimulator); + final result = await plugin.isIOSSimulator(); + verify(mockQuillNativeBridgePlatform.isIOSSimulator()).called(1); + expect(result, isSimulator); + } + }); + + test( + 'getClipboardHtml returns correct value based on platform implementation', + () async { + for (final html in {'

', ''}) { + when(mockQuillNativeBridgePlatform.getClipboardHtml()) + .thenAnswer((_) async => html); + final result = await plugin.getClipboardHtml(); + verify(mockQuillNativeBridgePlatform.getClipboardHtml()).called(1); + expect(result, html); + } + }); + + test( + 'copyHtmlToClipboard passes the HTML correctly to the platform implementation', + () async { + const exampleHtml = ''; + when(mockQuillNativeBridgePlatform.copyHtmlToClipboard(any)) + .thenAnswer((_) async {}); + + await plugin.copyHtmlToClipboard(exampleHtml); + verify(mockQuillNativeBridgePlatform.copyHtmlToClipboard(exampleHtml)) + .called(1); + }, + ); + + test( + 'copyImageToClipboard passes the image bytes correctly to the platform implementation', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + when(mockQuillNativeBridgePlatform.copyImageToClipboard(any)) + .thenAnswer((_) async {}); + + await plugin.copyImageToClipboard(imageBytes); + verify(mockQuillNativeBridgePlatform.copyImageToClipboard(imageBytes)) + .called(1); + }, + ); + + test( + 'getClipboardImage returns correct value based on platform implementation', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + when(mockQuillNativeBridgePlatform.getClipboardImage()) + .thenAnswer((_) async => imageBytes); + final result = await plugin.getClipboardImage(); + verify(mockQuillNativeBridgePlatform.getClipboardImage()).called(1); + expect(result, imageBytes); + }); + + test('getClipboardGif returns correct value based on platform implementation', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + when(mockQuillNativeBridgePlatform.getClipboardGif()) + .thenAnswer((_) async => imageBytes); + final result = await plugin.getClipboardGif(); + verify(mockQuillNativeBridgePlatform.getClipboardGif()).called(1); + expect(result, imageBytes); + }); + + test( + 'getClipboardFiles returns correct value based on platform implementation', + () async { + final clipboardFiles = ['/path/to/file', '/foo/bar']; + when(mockQuillNativeBridgePlatform.getClipboardFiles()) + .thenAnswer((_) async => clipboardFiles); + final result = await plugin.getClipboardFiles(); + verify(mockQuillNativeBridgePlatform.getClipboardFiles()).called(1); + expect(result, clipboardFiles); + }); + + test( + 'openGalleryApp calls platform implementation', + () async { + when(mockQuillNativeBridgePlatform.openGalleryApp()) + .thenAnswer((_) async {}); + + await plugin.openGalleryApp(); + verify(mockQuillNativeBridgePlatform.openGalleryApp()).called(1); + }, + ); + + group( + 'saveImageToGallery', + () { + test( + 'calls platform implementation', + () async { + when(mockQuillNativeBridgePlatform.saveImageToGallery( + any, + options: anyNamed('options'), + )).thenAnswer((_) async {}); + + await plugin.saveImageToGallery( + Uint8List.fromList([0, 1, 0]), + options: const GalleryImageSaveOptions( + name: 'ExampleImage', + albumName: 'ExampleAlbum', + fileExtension: 'jpg', + ), + ); + verify(mockQuillNativeBridgePlatform.saveImageToGallery( + any, + options: anyNamed('options'), + )).called(1); + }, + ); + test('passes the arguments to the platform implementation correctly', + () async { + final imageBytes = Uint8List.fromList([0, 1, 0]); + const options = GalleryImageSaveOptions( + name: 'Example Image', fileExtension: 'jpg', albumName: 'AnAlbum'); + + when(mockQuillNativeBridgePlatform.saveImageToGallery( + any, + options: anyNamed('options'), + )).thenAnswer((_) async {}); + + await plugin.saveImageToGallery( + imageBytes, + options: options, + ); + final capturedOptions = + verify(mockQuillNativeBridgePlatform.saveImageToGallery( + captureAny, + options: captureAnyNamed('options'), + )).captured; + + expect(capturedOptions[0] as Uint8List, imageBytes); + expect(capturedOptions[1] as GalleryImageSaveOptions, options); + }); + }, + ); + + group( + 'saveImage', + () { + test( + 'calls platform implementation', + () async { + when(mockQuillNativeBridgePlatform.saveImage( + any, + options: anyNamed('options'), + )).thenAnswer((_) async => ImageSaveResult.io(filePath: null)); + + await plugin.saveImage(Uint8List.fromList([0, 1, 0]), + options: const ImageSaveOptions( + name: 'ExampleImage', fileExtension: 'jpg')); + verify(mockQuillNativeBridgePlatform.saveImage( + any, + options: anyNamed('options'), + )).called(1); + }, + ); + test('passes the arguments to the platform implementation correctly', + () async { + final imageBytes = Uint8List.fromList([0, 1, 0]); + + const options = + ImageSaveOptions(name: 'Example Image', fileExtension: 'jpg'); + + when(mockQuillNativeBridgePlatform.saveImage( + any, + options: anyNamed('options'), + )).thenAnswer((_) async => ImageSaveResult.io(filePath: null)); + + await plugin.saveImage( + imageBytes, + options: options, + ); + final capturedOptions = verify(mockQuillNativeBridgePlatform.saveImage( + captureAny, + options: captureAnyNamed('options'), + )).captured; + + expect(capturedOptions[0] as Uint8List, imageBytes); + expect(capturedOptions[1] as ImageSaveOptions, options); + }); + }, + ); +} diff --git a/quill_native_bridge/test/quill_native_bridge_test.mocks.dart b/quill_native_bridge/test/quill_native_bridge_test.mocks.dart new file mode 100644 index 0000000..9b9084c --- /dev/null +++ b/quill_native_bridge/test/quill_native_bridge_test.mocks.dart @@ -0,0 +1,174 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in quill_native_bridge/test/quill_native_bridge_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:typed_data' as _i6; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart' + as _i3; +import 'package:quill_native_bridge_platform_interface/src/platform_feature.dart' + as _i5; +import 'package:quill_native_bridge_platform_interface/src/types/image_save_options.dart' + as _i7; +import 'package:quill_native_bridge_platform_interface/src/types/image_save_result.dart' + as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeImageSaveResult_0 extends _i1.SmartFake + implements _i2.ImageSaveResult { + _FakeImageSaveResult_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [QuillNativeBridgePlatform]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockQuillNativeBridgePlatform extends _i1.Mock + implements _i3.QuillNativeBridgePlatform { + MockQuillNativeBridgePlatform() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future isSupported(_i5.QuillNativeBridgeFeature? feature) => + (super.noSuchMethod( + Invocation.method( + #isSupported, + [feature], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future isIOSSimulator() => (super.noSuchMethod( + Invocation.method( + #isIOSSimulator, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future getClipboardHtml() => (super.noSuchMethod( + Invocation.method( + #getClipboardHtml, + [], + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future copyHtmlToClipboard(String? html) => (super.noSuchMethod( + Invocation.method( + #copyHtmlToClipboard, + [html], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future copyImageToClipboard(_i6.Uint8List? imageBytes) => + (super.noSuchMethod( + Invocation.method( + #copyImageToClipboard, + [imageBytes], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future<_i6.Uint8List?> getClipboardImage() => (super.noSuchMethod( + Invocation.method( + #getClipboardImage, + [], + ), + returnValue: _i4.Future<_i6.Uint8List?>.value(), + ) as _i4.Future<_i6.Uint8List?>); + + @override + _i4.Future<_i6.Uint8List?> getClipboardGif() => (super.noSuchMethod( + Invocation.method( + #getClipboardGif, + [], + ), + returnValue: _i4.Future<_i6.Uint8List?>.value(), + ) as _i4.Future<_i6.Uint8List?>); + + @override + _i4.Future> getClipboardFiles() => (super.noSuchMethod( + Invocation.method( + #getClipboardFiles, + [], + ), + returnValue: _i4.Future>.value([]), + ) as _i4.Future>); + + @override + _i4.Future openGalleryApp() => (super.noSuchMethod( + Invocation.method( + #openGalleryApp, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future saveImageToGallery( + _i6.Uint8List? imageBytes, { + required _i7.GalleryImageSaveOptions? options, + }) => + (super.noSuchMethod( + Invocation.method( + #saveImageToGallery, + [imageBytes], + {#options: options}, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future<_i2.ImageSaveResult> saveImage( + _i6.Uint8List? imageBytes, { + required _i7.ImageSaveOptions? options, + }) => + (super.noSuchMethod( + Invocation.method( + #saveImage, + [imageBytes], + {#options: options}, + ), + returnValue: + _i4.Future<_i2.ImageSaveResult>.value(_FakeImageSaveResult_0( + this, + Invocation.method( + #saveImage, + [imageBytes], + {#options: options}, + ), + )), + ) as _i4.Future<_i2.ImageSaveResult>); +} diff --git a/quill_native_bridge_android/CHANGELOG.md b/quill_native_bridge_android/CHANGELOG.md index 2d3c31e..879c764 100644 --- a/quill_native_bridge_android/CHANGELOG.md +++ b/quill_native_bridge_android/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. +## 0.0.1 + +- Adds support for saving images. + +## 0.0.1-dev.6 + +- Deregister platform method channel correctly in `onDetachedFromEngine`. +- Adds Dart unit tests. +- Supports saving an image to the system gallery app. +- Supports opening the system gallery app. +- Updates Java compatibility version to 11. Related [flutter#156111](https://github.com/flutter/flutter/issues/156111). + ## 0.0.1-dev.5 - Adds pub topics to package metadata. diff --git a/quill_native_bridge_android/android/build.gradle b/quill_native_bridge_android/android/build.gradle index 6232173..d138afe 100644 --- a/quill_native_bridge_android/android/build.gradle +++ b/quill_native_bridge_android/android/build.gradle @@ -25,22 +25,18 @@ apply plugin: "com.android.library" apply plugin: "kotlin-android" android { - if (project.android.hasProperty("namespace")) { - namespace = "dev.flutterquill.quill_native_bridge" - } + namespace = "dev.flutterquill.quill_native_bridge" - // Using outdated compileSdk can prevent apps - // from build using newer API - // https://github.com/flutter/flutter/issues/63533 + // Using outdated compileSdk can prevent apps from targeting newer versions. See https://github.com/flutter/flutter/issues/63533 compileSdk = 34 compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8 + jvmTarget = JavaVersion.VERSION_11 } sourceSets { diff --git a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/QuillNativeBridgeImpl.kt b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/QuillNativeBridgeImpl.kt index c8c6abf..3fa326a 100644 --- a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/QuillNativeBridgeImpl.kt +++ b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/QuillNativeBridgeImpl.kt @@ -1,12 +1,18 @@ package dev.flutterquill.quill_native_bridge import android.content.Context +import android.content.Intent +import android.provider.MediaStore import dev.flutterquill.quill_native_bridge.clipboard.ClipboardReadImageHandler import dev.flutterquill.quill_native_bridge.clipboard.ClipboardRichTextHandler import dev.flutterquill.quill_native_bridge.clipboard.ClipboardWriteImageHandler import dev.flutterquill.quill_native_bridge.generated.QuillNativeBridgeApi +import dev.flutterquill.quill_native_bridge.saveImage.SaveImageHandler +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding class QuillNativeBridgeImpl(private val context: Context) : QuillNativeBridgeApi { + private var activityPluginBinding: ActivityPluginBinding? = null + override fun getClipboardHtml(): String? = ClipboardRichTextHandler.getClipboardHtml(context) override fun copyHtmlToClipboard(html: String) = @@ -25,4 +31,40 @@ class QuillNativeBridgeImpl(private val context: Context) : QuillNativeBridgeApi context, imageType = ClipboardReadImageHandler.ImageType.Gif, ) + + override fun openGalleryApp() { + // TODO(save-image): Test on Android marshmallow (API 23) + val intent = + Intent(Intent.ACTION_VIEW, MediaStore.Images.Media.EXTERNAL_CONTENT_URI).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK + } + getActivityPluginBindingOrThrow().activity.startActivity(intent) + } + + override fun saveImageToGallery( + imageBytes: ByteArray, + name: String, + fileExtension: String, + mimeType: String, + albumName: String?, + callback: (Result) -> Unit + ) = SaveImageHandler.saveImageToGallery( + context, + getActivityPluginBindingOrThrow(), + imageBytes = imageBytes, + name = name, + fileExtension = fileExtension, + mimeType = mimeType, + albumName = albumName, + callback = callback + ) + + private fun getActivityPluginBindingOrThrow(): ActivityPluginBinding { + return activityPluginBinding + ?: throw IllegalStateException("The Flutter activity binding was not set. This indicates a bug in `${QuillNativeBridgePlugin::class.simpleName}`.") + } + + fun setActivityPluginBinding(activityPluginBinding: ActivityPluginBinding?) { + this.activityPluginBinding = activityPluginBinding + } } \ No newline at end of file diff --git a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/QuillNativeBridgePlugin.kt b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/QuillNativeBridgePlugin.kt index 6224999..1441448 100644 --- a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/QuillNativeBridgePlugin.kt +++ b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/QuillNativeBridgePlugin.kt @@ -1,19 +1,67 @@ package dev.flutterquill.quill_native_bridge +import android.util.Log import dev.flutterquill.quill_native_bridge.generated.QuillNativeBridgeApi import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding -class QuillNativeBridgePlugin : FlutterPlugin { - private var api: QuillNativeBridgeApi? = null +class QuillNativeBridgePlugin : FlutterPlugin, ActivityAware { + + companion object { + const val TAG = "QuillNativeBridgePlugin" + } + + private var pluginApi: QuillNativeBridgeImpl? = null + private var activityPluginBinding: ActivityPluginBinding? = null override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { - api = QuillNativeBridgeImpl(binding.applicationContext) - requireNotNull(api) { "A new instance of $QuillNativeBridgeApi was created that appeared to be null" } - QuillNativeBridgeApi.setUp(binding.binaryMessenger, api) + val pluginApi = QuillNativeBridgeImpl(binding.applicationContext) + this.pluginApi = pluginApi + QuillNativeBridgeApi.setUp(binding.binaryMessenger, pluginApi) } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { - QuillNativeBridgeApi.setUp(binding.binaryMessenger, api) - api = null + if (pluginApi == null) { + Log.wtf(TAG, "Already detached from the Flutter engine.") + return + } + + QuillNativeBridgeApi.setUp(binding.binaryMessenger, null) + pluginApi = null + } + + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + setActivityPluginBinding(binding, ::onAttachedToActivity.name) + } + + override fun onDetachedFromActivityForConfigChanges() { + disposeActivityPluginBinding(::onDetachedFromActivityForConfigChanges.name) + } + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + setActivityPluginBinding(binding, ::onReattachedToActivityForConfigChanges.name) + } + + override fun onDetachedFromActivity() { + disposeActivityPluginBinding(::onDetachedFromActivity.name) + } + + private fun logApiNotSetError(methodName: String) { + Log.wtf( + TAG, + "The `${::pluginApi.name}` is not initialized. Failed to update Flutter activity binding " + + "reference for `${QuillNativeBridgeImpl::class.simpleName}` in `$methodName`." + ) + } + + private fun setActivityPluginBinding(binding: ActivityPluginBinding, methodName: String) { + activityPluginBinding = binding + pluginApi?.setActivityPluginBinding(binding) ?: logApiNotSetError(methodName) + } + + private fun disposeActivityPluginBinding(methodName: String) { + activityPluginBinding = null + pluginApi?.setActivityPluginBinding(null) ?: logApiNotSetError(methodName) } } diff --git a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/clipboard/ClipboardReadImageHandler.kt b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/clipboard/ClipboardReadImageHandler.kt index 5709473..e55f9f0 100644 --- a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/clipboard/ClipboardReadImageHandler.kt +++ b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/clipboard/ClipboardReadImageHandler.kt @@ -4,13 +4,12 @@ import android.content.ClipData import android.content.ClipboardManager import android.content.Context import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.graphics.ImageDecoder import android.net.Uri -import android.os.Build import dev.flutterquill.quill_native_bridge.generated.FlutterError +import dev.flutterquill.quill_native_bridge.util.ImageDecoderCompat import java.io.ByteArrayOutputStream import java.io.FileNotFoundException +import java.io.IOException object ClipboardReadImageHandler { private const val MIME_TYPE_IMAGE_ALL = "image/*" @@ -170,22 +169,9 @@ object ClipboardReadImageHandler { context: Context, imageUri: Uri ): ByteArray { - val bitmap = try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - // Api 29 and above (use a newer API) - val source = ImageDecoder.createSource(context.contentResolver, imageUri) - ImageDecoder.decodeBitmap(source) - } else { - // Backward compatibility with older versions - checkNotNull(context.contentResolver.openInputStream(imageUri)) { - "Input stream is null, the provider might have recently crashed." - }.use { inputStream -> - val bitmap: Bitmap? = BitmapFactory.decodeStream(inputStream) - checkNotNull(bitmap) { "The image could not be decoded" } - bitmap - } - } - } catch (e: Exception) { + val bitmap: Bitmap = try { + ImageDecoderCompat.decodeBitmapFromUri(context.contentResolver, imageUri) + } catch (e: IOException) { throw FlutterError( "COULD_NOT_DECODE_IMAGE", "Could not decode bitmap from Uri: ${e.message}", diff --git a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/clipboard/ClipboardWriteImageHandler.kt b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/clipboard/ClipboardWriteImageHandler.kt index 8a78540..e6cb5ae 100644 --- a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/clipboard/ClipboardWriteImageHandler.kt +++ b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/clipboard/ClipboardWriteImageHandler.kt @@ -4,40 +4,25 @@ import android.content.ClipData import android.content.ClipboardManager import android.content.Context import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.graphics.ImageDecoder -import android.os.Build import androidx.core.content.FileProvider import dev.flutterquill.quill_native_bridge.generated.FlutterError +import dev.flutterquill.quill_native_bridge.util.ImageDecoderCompat import java.io.File +import java.io.IOException object ClipboardWriteImageHandler { fun copyImageToClipboard( context: Context, imageBytes: ByteArray, ) { - val bitmap: Bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - // Api 29 and above (use a newer API) - try { - val source = ImageDecoder.createSource(imageBytes) - ImageDecoder.decodeBitmap(source) - } catch (e: Exception) { - throw FlutterError( - "INVALID_IMAGE", - "The provided image bytes are invalid, image could not be decoded: ${e.message}", - e.toString(), - ) - } - } else { - // Backward compatibility with older versions - val bitmap: Bitmap = - BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) - ?: throw FlutterError( - "INVALID_IMAGE", - "The provided image bytes are invalid. Image could not be decoded.", - null, - ) - bitmap + val bitmap: Bitmap = try { + ImageDecoderCompat.decodeBitmapFromBytes(imageBytes) + } catch (e: IOException) { + throw FlutterError( + "INVALID_IMAGE", + "The provided image bytes are invalid, image could not be decoded: ${e.message}", + e.toString(), + ) } val tempImageFile = File(context.cacheDir, "temp_clipboard_image.png") diff --git a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/generated/GeneratedMessages.kt b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/generated/GeneratedMessages.kt index ee6cad3..f80bddd 100644 --- a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/generated/GeneratedMessages.kt +++ b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/generated/GeneratedMessages.kt @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v22.4.1), do not edit directly. +// Autogenerated from Pigeon (v22.6.2), do not edit directly. // See also: https://pub.dev/packages/pigeon @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") @@ -52,6 +52,7 @@ private open class GeneratedMessagesPigeonCodec : StandardMessageCodec() { } } + /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ interface QuillNativeBridgeApi { fun getClipboardHtml(): String? @@ -59,6 +60,9 @@ interface QuillNativeBridgeApi { fun getClipboardImage(): ByteArray? fun copyImageToClipboard(imageBytes: ByteArray) fun getClipboardGif(): ByteArray? + fun openGalleryApp() + /** The [fileExtension] is only required for Android APIs before 29. */ + fun saveImageToGallery(imageBytes: ByteArray, name: String, fileExtension: String, mimeType: String, albumName: String?, callback: (Result) -> Unit) companion object { /** The codec used by QuillNativeBridgeApi. */ @@ -150,6 +154,45 @@ interface QuillNativeBridgeApi { channel.setMessageHandler(null) } } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.openGalleryApp$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + val wrapped: List = try { + api.openGalleryApp() + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.saveImageToGallery$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val imageBytesArg = args[0] as ByteArray + val nameArg = args[1] as String + val fileExtensionArg = args[2] as String + val mimeTypeArg = args[3] as String + val albumNameArg = args[4] as String? + api.saveImageToGallery(imageBytesArg, nameArg, fileExtensionArg, mimeTypeArg, albumNameArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } } } } diff --git a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/saveImage/SaveImageHandler.kt b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/saveImage/SaveImageHandler.kt new file mode 100644 index 0000000..e7211f2 --- /dev/null +++ b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/saveImage/SaveImageHandler.kt @@ -0,0 +1,282 @@ +package dev.flutterquill.quill_native_bridge.saveImage + +import android.content.ContentValues +import android.content.Context +import android.content.pm.PackageManager +import android.media.MediaScannerConnection +import android.os.Build +import android.os.Environment +import android.provider.MediaStore +import android.util.Log +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import dev.flutterquill.quill_native_bridge.QuillNativeBridgePlugin +import dev.flutterquill.quill_native_bridge.util.ImageDecoderCompat +import dev.flutterquill.quill_native_bridge.util.respondFlutterPigeonError +import dev.flutterquill.quill_native_bridge.util.respondFlutterPigeonSuccess +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import io.flutter.plugin.common.PluginRegistry +import java.io.File +import java.io.IOException +import java.nio.file.Paths +import java.util.UUID + +object SaveImageHandler { + + /** + * @return `true` if running on API 29 or newer version. + * */ + private fun supportsScopedStorage(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q + + private const val WRITE_TO_EXTERNAL_STORAGE_REQUEST_CODE = + 449612150 // A unique code to distinguish between requests + + private const val WRITE_EXTERNAL_STORAGE_PERMISSION_NAME = + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + + private fun isWriteExternalStoragePermissionDeclared(context: Context): Boolean { + return try { + val packageInfo = context.packageManager.getPackageInfo( + context.packageName, + PackageManager.GET_PERMISSIONS + ) + val permissions = packageInfo.requestedPermissions + + if (permissions.isNullOrEmpty()) { + return false + } + return permissions.contains(WRITE_EXTERNAL_STORAGE_PERMISSION_NAME) + } catch (e: PackageManager.NameNotFoundException) { + false + } + } + + /** + * Write an image to the gallery with external storage permission for only Android API 28 and earlier. + * */ + private fun saveImageToGalleryLegacy( + imageBytes: ByteArray, + name: String, + albumName: String?, + fileExtension: String, + callback: (Result) -> Unit, + mimeType: String, + context: Context, + ) { + val imageSaveDirectory = if (albumName != null) { + File( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), + albumName + ) + } else { + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + } + + if (!imageSaveDirectory.exists() && !imageSaveDirectory.mkdirs()) { + callback.respondFlutterPigeonError( + "DIRECTORY_CREATION_FAILED", + "Failed to create directory: ${imageSaveDirectory.absolutePath}", + null, + ) + return + } + + val imageFile = + File( + imageSaveDirectory, + "${name}-${System.currentTimeMillis()}-${UUID.randomUUID()}.${fileExtension}" + ) + if (imageFile.exists()) { + callback.respondFlutterPigeonError( + "FILE_EXISTS", + "A file with the name `${imageFile}` already exists.", + null, + ) + return + } + + imageFile.outputStream().use { outputStream -> + try { + outputStream.write(imageBytes) + } catch (e: IOException) { + callback.respondFlutterPigeonError( + "SAVE_FAILED", + "Failed to save the image to the gallery: ${e.message}", + e.toString() + ) + return + } + } + + MediaScannerConnection.scanFile( + context, + arrayOf(imageFile.absolutePath), + arrayOf(mimeType), + null, + ) + + callback.respondFlutterPigeonSuccess(Unit) + } + + fun saveImageToGallery( + context: Context, + activityPluginBinding: ActivityPluginBinding, + imageBytes: ByteArray, + name: String, + fileExtension: String, + mimeType: String, + albumName: String?, + callback: (Result) -> Unit + ) { + if (!ImageDecoderCompat.isValidImage(imageBytes)) { + callback.respondFlutterPigeonError( + "INVALID_IMAGE", + "The provided image bytes are invalid. Image could not be decoded.", + ) + return + } + + if (!supportsScopedStorage()) { + if (!isWriteExternalStoragePermissionDeclared(context)) { + callback.respondFlutterPigeonError( + "ANDROID_MANIFEST_NOT_CONFIGURED", + "The uses-permission '${WRITE_EXTERNAL_STORAGE_PERMISSION_NAME}' is not declared in AndroidManifest.xml", + "The app is running on Android API ${Build.VERSION.SDK_INT}. Scoped storage" + + " was introduced in ${Build.VERSION_CODES.Q} and is not available on this version.\n" + + "Write to external storage permission is required to save an image to the gallery." + ) + return + } + // Need to request runtime permission for API 28 and older versions + val hasNecessaryPermission = ContextCompat.checkSelfPermission( + context, + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + ) == PackageManager.PERMISSION_GRANTED + if (!hasNecessaryPermission) { + ActivityCompat.requestPermissions( + activityPluginBinding.activity, + arrayOf(WRITE_EXTERNAL_STORAGE_PERMISSION_NAME), + WRITE_TO_EXTERNAL_STORAGE_REQUEST_CODE + ) + + activityPluginBinding.addRequestPermissionsResultListener(object : + PluginRegistry.RequestPermissionsResultListener { + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ): Boolean { + try { + if (requestCode != WRITE_TO_EXTERNAL_STORAGE_REQUEST_CODE) { + return false + } + val onlyWriteExternalStorageIsRequested = permissions.contentEquals( + arrayOf(WRITE_EXTERNAL_STORAGE_PERMISSION_NAME) + ) + if (!onlyWriteExternalStorageIsRequested) { + Log.w( + QuillNativeBridgePlugin.TAG, + "The only expected permission that's requested is ${WRITE_EXTERNAL_STORAGE_PERMISSION_NAME}." + ) + } + val isGranted = + grantResults.isNotEmpty() && grantResults.first() == PackageManager.PERMISSION_GRANTED + if (!isGranted) { + callback.respondFlutterPigeonError( + "PERMISSION_DENIED", + "Write to external storage permission request has been denied." + ) + return true + } + saveImageToGalleryLegacy( + imageBytes = imageBytes, + name = name, + albumName = albumName, + fileExtension = fileExtension, + callback = callback, + mimeType = mimeType, + context = context, + ) + return true + } finally { + activityPluginBinding.removeRequestPermissionsResultListener(this) + } + } + }) + return + } + + saveImageToGalleryLegacy( + imageBytes = imageBytes, + name = name, + albumName = albumName, + fileExtension = fileExtension, + callback = callback, + mimeType = mimeType, + context = context, + ) + return + } + + // Scoped Storage is enforced + + val contentResolver = context.contentResolver + + val contentValues = ContentValues().apply { + put(MediaStore.Images.Media.DISPLAY_NAME, name) + put(MediaStore.Images.Media.MIME_TYPE, mimeType) + put(MediaStore.Images.Media.IS_PENDING, 1) + + albumName?.let { + put( + MediaStore.Images.Media.RELATIVE_PATH, + Paths.get(Environment.DIRECTORY_PICTURES, it).toString() + ) + } + } + + val imageUri = + contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) + ?: run { + callback.respondFlutterPigeonError( + "FAILED_TO_INSERT_IMAGE", + "Either the underlying content provider returns `null` or the provider crashes.", + ) + return + } + + fun notifyImageUpdate() { + contentValues.clear() + contentValues.put(MediaStore.Images.Media.IS_PENDING, 0) + val rowsUpdated = contentResolver.update(imageUri, contentValues, null, null) + if (rowsUpdated == 0) { + Log.e( + QuillNativeBridgePlugin.TAG, + "Failed to update image state for URI: $imageUri" + ) + } + } + + val outputStream = contentResolver.openOutputStream(imageUri) ?: run { + callback.respondFlutterPigeonError( + "SAVE_FAILED", + "Could not open the output stream. The provider might have recently crashed." + ) + notifyImageUpdate() + return + } + + try { + outputStream.use { stream -> stream.write(imageBytes) } + notifyImageUpdate() + callback.respondFlutterPigeonSuccess(Unit) + } catch (e: IOException) { + callback.respondFlutterPigeonError( + "SAVE_FAILED", + "Failed to save the image to the gallery: ${e.message}", + e.toString() + ) + notifyImageUpdate() + } + } +} \ No newline at end of file diff --git a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/util/ImageDecoderCompat.kt b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/util/ImageDecoderCompat.kt new file mode 100644 index 0000000..6ebdfa4 --- /dev/null +++ b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/util/ImageDecoderCompat.kt @@ -0,0 +1,62 @@ +package dev.flutterquill.quill_native_bridge.util + +import android.content.ContentResolver +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.ImageDecoder +import android.net.Uri +import android.os.Build +import java.io.IOException + +/** + * Similar to [ImageDecoder] but compatible with older Android versions by fallback to use + * older APIs. + * */ +object ImageDecoderCompat { + /** + * Uses [ImageDecoder.decodeBitmap] on Android API 31 and newer, fallback to [BitmapFactory.decodeByteArray] + * on older versions. + * + * @throws IOException if unsupported, or or cannot be decoded for any reason. + * @see decodeBitmapFromUri + * */ + @Throws(IOException::class) + fun decodeBitmapFromBytes(imageBytes: ByteArray): Bitmap { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + // API 31 and above (use a newer API) + val source = ImageDecoder.createSource(imageBytes) + ImageDecoder.decodeBitmap(source) + } else { + // Backward compatibility with older versions + BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) + ?: throw IOException("Image could not be decoded using the `BitmapFactory.decodeByteArray`.") + } + } + + /** + * Uses [ImageDecoder.decodeBitmap] on Android API 28 and newer, fallback to [BitmapFactory.decodeStream] + * on older versions. + * + * @throws IOException if unsupported, or or cannot be decoded for any reason. + * @see decodeBitmapFromBytes + * */ + @Throws(IOException::class) + fun decodeBitmapFromUri(contentResolver: ContentResolver, imageUri: Uri): Bitmap { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + // API 28 and above (use a newer API) + val source = ImageDecoder.createSource(contentResolver, imageUri) + ImageDecoder.decodeBitmap(source) + } else { + // Backward compatibility with older versions + checkNotNull(contentResolver.openInputStream(imageUri)) { + "Input stream is null, the provider might have recently crashed." + }.use { inputStream -> + val bitmap: Bitmap = BitmapFactory.decodeStream(inputStream) + ?: throw IOException("The image could not be decoded using the `BitmapFactory.decodeStream`.") + bitmap + } + } + } + + fun isValidImage(imageBytes: ByteArray) = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) != null +} \ No newline at end of file diff --git a/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/util/PigeonExtension.kt b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/util/PigeonExtension.kt new file mode 100644 index 0000000..ba23728 --- /dev/null +++ b/quill_native_bridge_android/android/src/main/kotlin/dev/flutterquill/quill_native_bridge/util/PigeonExtension.kt @@ -0,0 +1,25 @@ +package dev.flutterquill.quill_native_bridge.util + +import dev.flutterquill.quill_native_bridge.generated.FlutterError + +// See https://github.com/flutter/packages/blob/main/packages/pigeon/example/README.md#kotlin + +fun ((Result) -> Unit).respondFlutterPigeonError( + code: String, + message: String? = null, + details: Any? = null +) { + this( + Result.failure( + FlutterError( + code = code, + message = message, + details = details, + ) + ) + ) +} + +fun ((Result) -> Unit).respondFlutterPigeonSuccess(value: T) { + this(Result.success(value)) +} diff --git a/quill_native_bridge_android/lib/quill_native_bridge_android.dart b/quill_native_bridge_android/lib/quill_native_bridge_android.dart index 34a44f7..912f2c6 100644 --- a/quill_native_bridge_android/lib/quill_native_bridge_android.dart +++ b/quill_native_bridge_android/lib/quill_native_bridge_android.dart @@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; +import 'package:quill_native_bridge_platform_interface/src/image_mime_utils.dart'; import 'src/messages.g.dart'; @@ -23,6 +24,8 @@ class QuillNativeBridgeAndroid extends QuillNativeBridgePlatform { QuillNativeBridgeFeature.copyImageToClipboard, QuillNativeBridgeFeature.getClipboardImage, QuillNativeBridgeFeature.getClipboardGif, + QuillNativeBridgeFeature.openGalleryApp, + QuillNativeBridgeFeature.saveImageToGallery, }.contains(feature); @override @@ -52,21 +55,18 @@ class QuillNativeBridgeAndroid extends QuillNativeBridgePlatform { try { await _hostApi.copyImageToClipboard(imageBytes); } on PlatformException catch (e) { - if (kDebugMode && e.code == 'ANDROID_MANIFEST_NOT_CONFIGURED') { - debugPrint( - 'It looks like your AndroidManifest.xml is not configured properly ' - 'to support copying images to the clipboard on Android.\n' - "If you're interested in this feature, refer to https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge#-platform-configuration\n" - 'This message will only shown in debug mode.\n' - 'Platform details: ${e.toString()}', - ); - throw AssertionError( - 'Optional AndroidManifest configuration is missing. ' - 'Copying images to the clipboard on Android require modifying `AndroidManifest.xml`. ' - 'A message was shown above this error for more details. This' - 'error will only arise in debug mode.', - ); - } + assert(() { + if (e.code == 'ANDROID_MANIFEST_NOT_CONFIGURED') { + throw StateError( + '\nThe AndroidManifest.xml file was not configured to support copying images to the clipboard on Android\n' + 'For more details, refer to https://pub.dev/packages/quill_native_bridge#-copying-images-to-the-system-clipboard\n' + 'This exception will be only thrown in debug mode.\n\n' + 'Platform error details: ${e.toString()}', + ); + } + return true; + }()); + rethrow; } } @@ -96,14 +96,6 @@ class QuillNativeBridgeAndroid extends QuillNativeBridgePlatform { /// /// See [#2243](https://github.com/singerdmx/flutter-quill/issues/2243) for more details. void _printAndroidClipboardImageAccessKnownIssue(PlatformException e) { - assert( - defaultTargetPlatform == TargetPlatform.android, - '_printAndroidClipboardImageAccessKnownIssue() should be only used for Android.', - ); - assert( - kDebugMode, - '_printAndroidClipboardImageAccessKnownIssue() should be only called in debug mode', - ); if (kDebugMode) { debugPrint( 'Could not retrieve the image from clipbaord as the app no longer have access to the image.\n' @@ -111,8 +103,41 @@ class QuillNativeBridgeAndroid extends QuillNativeBridgePlatform { 'This is known issue on Android and this message will be only shown in debug mode.\n' 'Refer to https://github.com/singerdmx/flutter-quill/issues/2243 for discussion.\n' 'A similar but unrelated issue in Flutter `imager_picker`: https://github.com/flutter/flutter/issues/100025' - 'Platform details: ${e.toString()}', + 'Platform error details: ${e.toString()}', + ); + } + } + + @override + Future openGalleryApp() => _hostApi.openGalleryApp(); + + @override + Future saveImageToGallery( + Uint8List imageBytes, { + required GalleryImageSaveOptions options, + }) async { + try { + await _hostApi.saveImageToGallery( + imageBytes, + name: options.name, + fileExtension: options.fileExtension, + mimeType: getImageMimeType(options.fileExtension), + albumName: options.albumName, ); + } on PlatformException catch (e) { + assert(() { + if (e.code == 'ANDROID_MANIFEST_NOT_CONFIGURED') { + throw StateError( + '\nThe AndroidManifest.xml file was not configured to support saving images to the gallery on Android 9 (API 28).\n' + 'The `WRITE_EXTERNAL_STORAGE` permission is required only on previous versions of Android.\n' + 'For more details, refer to https://pub.dev/packages/quill_native_bridge#-saving-images-to-the-gallery\n' + 'This exception will be only thrown in debug mode.\n\n' + 'Platform error details: ${e.toString()}', + ); + } + return true; + }()); + rethrow; } } } diff --git a/quill_native_bridge_android/lib/src/messages.g.dart b/quill_native_bridge_android/lib/src/messages.g.dart index 01c5152..eb6189b 100644 --- a/quill_native_bridge_android/lib/src/messages.g.dart +++ b/quill_native_bridge_android/lib/src/messages.g.dart @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v22.4.1), do not edit directly. +// Autogenerated from Pigeon (v22.6.2), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers @@ -15,6 +15,17 @@ PlatformException _createConnectionError(String channelName) { ); } +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override @@ -170,4 +181,60 @@ class QuillNativeBridgeApi { return (pigeonVar_replyList[0] as Uint8List?); } } + + Future openGalleryApp() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.openGalleryApp$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// The [fileExtension] is only required for Android APIs before 29. + Future saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String fileExtension, + required String mimeType, + required String? albumName, + }) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.saveImageToGallery$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel.send( + [imageBytes, name, fileExtension, mimeType, albumName]) + as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } } diff --git a/quill_native_bridge_android/pigeons/messages.dart b/quill_native_bridge_android/pigeons/messages.dart index cd84ded..67be81a 100644 --- a/quill_native_bridge_android/pigeons/messages.dart +++ b/quill_native_bridge_android/pigeons/messages.dart @@ -2,6 +2,7 @@ import 'package:pigeon/pigeon.dart'; @ConfigurePigeon(PigeonOptions( dartOut: 'lib/src/messages.g.dart', + dartTestOut: 'test/test_api.g.dart', // Using `GeneratedMessages.kt` instead of `Messages.g.kt` to follow // Kotlin conventions: https://kotlinlang.org/docs/coding-conventions.html#source-file-names kotlinOut: @@ -11,7 +12,7 @@ import 'package:pigeon/pigeon.dart'; ), dartPackageName: 'quill_native_bridge_android', )) -@HostApi() +@HostApi(dartHostTestHandler: 'TestQuillNativeBridgeApi') abstract class QuillNativeBridgeApi { // HTML String? getClipboardHtml(); @@ -21,4 +22,16 @@ abstract class QuillNativeBridgeApi { Uint8List? getClipboardImage(); void copyImageToClipboard(Uint8List imageBytes); Uint8List? getClipboardGif(); + + void openGalleryApp(); + + /// The [fileExtension] is only required for Android APIs before 29. + @async + void saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String fileExtension, + required String mimeType, + required String? albumName, + }); } diff --git a/quill_native_bridge_android/pubspec.yaml b/quill_native_bridge_android/pubspec.yaml index 6522553..1fdf32e 100644 --- a/quill_native_bridge_android/pubspec.yaml +++ b/quill_native_bridge_android/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge_android description: "Android implementation of the quill_native_bridge plugin." -version: 0.0.1-dev.5 +version: 0.0.1 homepage: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_android repository: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_android issue_tracker: https://github.com/FlutterQuill/quill-native-bridge/issues?q=is%3Aissue+is%3Aopen+label%3A%22platform-android%22 @@ -14,13 +14,15 @@ environment: dependencies: flutter: sdk: flutter - quill_native_bridge_platform_interface: ^0.0.1-dev.4 + quill_native_bridge_platform_interface: ^0.0.1 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 - pigeon: ^22.4.1 + pigeon: ^22.6.2 + mockito: ^5.4.4 + build_runner: ^2.4.13 flutter: plugin: diff --git a/quill_native_bridge_android/test/quill_native_bridge_android_test.dart b/quill_native_bridge_android/test/quill_native_bridge_android_test.dart new file mode 100644 index 0000000..3f7e3fd --- /dev/null +++ b/quill_native_bridge_android/test/quill_native_bridge_android_test.dart @@ -0,0 +1,338 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:quill_native_bridge_android/quill_native_bridge_android.dart'; +import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; +import 'package:quill_native_bridge_platform_interface/src/image_mime_utils.dart'; + +import 'test_api.g.dart'; + +@GenerateMocks([TestQuillNativeBridgeApi]) +import 'quill_native_bridge_android_test.mocks.dart'; + +void main() { + // Required when calling TestQuillNativeBridgeApi.setUp() + TestWidgetsFlutterBinding.ensureInitialized(); + + late QuillNativeBridgeAndroid plugin; + late MockTestQuillNativeBridgeApi mockHostApi; + + setUp(() { + plugin = QuillNativeBridgeAndroid(); + mockHostApi = MockTestQuillNativeBridgeApi(); + TestQuillNativeBridgeApi.setUp(mockHostApi); + + when(mockHostApi.openGalleryApp()).thenAnswer((_) async {}); + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + fileExtension: anyNamed('fileExtension'), + mimeType: anyNamed('mimeType'), + )).thenAnswer((_) async {}); + }); + + test('registered instance', () { + QuillNativeBridgeAndroid.registerWith(); + expect(QuillNativeBridgePlatform.instance, isA()); + }); + + group( + 'clipboard', + () { + test( + 'getClipboardHtml delegates to _hostApi.getClipboardHtml', + () async { + when(mockHostApi.getClipboardHtml()).thenReturn(null); + final nullHtml = await plugin.getClipboardHtml(); + verify(mockHostApi.getClipboardHtml()).called(1); + expect(nullHtml, isNull); + + final exampleHtml = 'An HTML'; + + when(mockHostApi.getClipboardHtml()).thenReturn(exampleHtml); + final nonNullHtml = await plugin.getClipboardHtml(); + verify(mockHostApi.getClipboardHtml()).called(1); + expect(nonNullHtml, equals(exampleHtml)); + }, + ); + + test( + 'copyHtmlToClipboard delegates to _hostApi.copyHtmlToClipboard', + () async { + final input = 'Example HTML'; + when(mockHostApi.copyHtmlToClipboard(input)).thenReturn(null); + await plugin.copyHtmlToClipboard(input); + verify(mockHostApi.copyHtmlToClipboard(input)).called(1); + }, + ); + + test( + 'getClipboardImage delegates to _hostApi.getClipboardImage', + () async { + when(mockHostApi.getClipboardImage()).thenReturn(null); + final nullImage = await plugin.getClipboardImage(); + verify(mockHostApi.getClipboardImage()).called(1); + expect(nullImage, isNull); + + final exampleImage = Uint8List.fromList([1, 0, 1]); + + when(mockHostApi.getClipboardImage()).thenReturn(exampleImage); + final nonNullImage = await plugin.getClipboardImage(); + verify(mockHostApi.getClipboardImage()).called(1); + expect(nonNullImage, equals(exampleImage)); + }, + ); + + test( + 'copyImageToClipboard delegates to _hostApi.copyImageToClipboard', + () async { + final input = Uint8List.fromList([1, 0, 1]); + when(mockHostApi.copyImageToClipboard(input)).thenReturn(null); + await plugin.copyImageToClipboard(input); + verify(mockHostApi.copyImageToClipboard(input)).called(1); + }, + ); + + test( + 'getClipboardGif delegates to _hostApi.getClipboardGif', + () async { + when(mockHostApi.getClipboardGif()).thenReturn(null); + final nullImage = await plugin.getClipboardGif(); + verify(mockHostApi.getClipboardGif()).called(1); + expect(nullImage, isNull); + + final exampleImage = Uint8List.fromList([1, 0, 1]); + + when(mockHostApi.getClipboardGif()).thenReturn(exampleImage); + final nonNullImage = await plugin.getClipboardGif(); + verify(mockHostApi.getClipboardGif()).called(1); + expect(nonNullImage, equals(exampleImage)); + }, + ); + + test( + 'copyImageToClipboard throws $StateError in debug mode when AndroidManifest.xml is not configured', + () async { + when(mockHostApi.copyImageToClipboard(any)).thenThrow( + PlatformException(code: 'ANDROID_MANIFEST_NOT_CONFIGURED')); + await expectLater( + plugin.copyImageToClipboard(Uint8List.fromList([])), + throwsA(isA().having( + (e) => e.message, + 'message', + contains( + 'The AndroidManifest.xml file was not configured to support copying images to the clipboard on Android'), + )), + ); + }, + ); + + test( + 'getClipboardImage returns null in case of Android file access read denied', + () async { + when(mockHostApi.getClipboardImage()).thenThrow( + PlatformException(code: 'FILE_READ_PERMISSION_DENIED')); + final image = await plugin.getClipboardImage(); + expect(image, isNull); + + when(mockHostApi.getClipboardGif()).thenThrow( + PlatformException(code: 'FILE_READ_PERMISSION_DENIED')); + final gif = await plugin.getClipboardGif(); + expect(gif, isNull); + }, + ); + + test( + 'getClipboardImage returns null in case of Android file not found error', + () async { + when(mockHostApi.getClipboardImage()) + .thenThrow(PlatformException(code: 'FILE_NOT_FOUND')); + final result = await plugin.getClipboardImage(); + expect(result, isNull); + + when(mockHostApi.getClipboardGif()) + .thenThrow(PlatformException(code: 'FILE_NOT_FOUND')); + final gif = await plugin.getClipboardGif(); + expect(gif, isNull); + }, + ); + }, + ); + + group('gallery', () { + test( + 'openGalleryApp delegates to _hostApi.openGalleryApp', + () async { + await plugin.openGalleryApp(); + verify(mockHostApi.openGalleryApp()).called(1); + }, + ); + + group('saveImageToGallery', () { + test( + 'delegates to _hostApi.saveImageToGallery', + () async { + await plugin.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + )); + verify(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + fileExtension: anyNamed('fileExtension'), + albumName: anyNamed('albumName'), + mimeType: anyNamed('mimeType'), + )).called(1); + }, + ); + + test( + 'passes the arguments correctly to the platform host API', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + + final options = GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'jpg', + albumName: 'ExampleAlbum', + ); + + when(mockHostApi.saveImageToGallery( + imageBytes, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + fileExtension: anyNamed('fileExtension'), + mimeType: anyNamed('mimeType'), + )).thenAnswer((_) async => null); + + await plugin.saveImageToGallery(imageBytes, options: options); + + final capturedOptions = verify(mockHostApi.saveImageToGallery( + captureAny, + name: captureAnyNamed('name'), + albumName: captureAnyNamed('albumName'), + fileExtension: captureAnyNamed('fileExtension'), + mimeType: captureAnyNamed('mimeType'), + )).captured; + + expect(capturedOptions[0] as Uint8List, imageBytes); + expect(capturedOptions[1] as String, options.name); + expect(capturedOptions[2] as String, options.albumName); + expect(capturedOptions[3] as String, options.fileExtension); + expect(capturedOptions[4] as String, + getImageMimeType(options.fileExtension)); + }, + ); + + test( + 'passes the mime type correctly to the platform host API', + () async { + final options = GalleryImageSaveOptions( + name: 'ImageName', + // IMPORTANT: Use jpg specifically instead of jpeg or png + // since the "image/jpg" is invalid and it will verify behavior, + // ensuring the mimeType is passed correctly. + fileExtension: 'jpg', + albumName: 'ExampleAlbum', + ); + await plugin.saveImageToGallery(Uint8List.fromList([]), + options: options); + + final capturedOptions = verify(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + fileExtension: anyNamed('fileExtension'), + mimeType: captureAnyNamed('mimeType'), + )).captured; + expect( + capturedOptions[0] as String, + getImageMimeType(options.fileExtension), + ); + }, + ); + + test( + 'throws $StateError in debug mode for common issues', + () { + void expectThrowsForCode(String errorCode, + {required String containsMessage}) { + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + fileExtension: anyNamed('fileExtension'), + mimeType: anyNamed('mimeType'), + )).thenThrow(PlatformException(code: errorCode)); + expect( + plugin.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + )), + throwsA(isA().having( + (e) => e.message, + 'message', + contains(containsMessage), + )), + ); + } + + expectThrowsForCode('ANDROID_MANIFEST_NOT_CONFIGURED', + containsMessage: + 'The AndroidManifest.xml file was not configured to support saving images to the gallery on Android 9 (API 28).'); + }, + ); + + test( + 'rethrows the $PlatformException from _hostApi.saveImageToGallery if not handled', + () async { + // Currently, that's the expected behavior but it is subject to changes for improvements. + // See https://github.com/FlutterQuill/quill-native-bridge/issues/2 + + const errorCode = '404'; + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + fileExtension: anyNamed('fileExtension'), + mimeType: anyNamed('mimeType'), + )).thenThrow(PlatformException(code: errorCode)); + expect( + plugin.saveImageToGallery( + Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + ), + ), + throwsA(isA() + .having((e) => e.code, 'code', errorCode)), + ); + + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + fileExtension: anyNamed('fileExtension'), + mimeType: anyNamed('mimeType'), + )).thenAnswer((_) async {}); + await expectLater( + plugin.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + )), + completes, + ); + }); + }); + }); +} diff --git a/quill_native_bridge_android/test/quill_native_bridge_android_test.mocks.dart b/quill_native_bridge_android/test/quill_native_bridge_android_test.mocks.dart new file mode 100644 index 0000000..2bbc5d9 --- /dev/null +++ b/quill_native_bridge_android/test/quill_native_bridge_android_test.mocks.dart @@ -0,0 +1,84 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in quill_native_bridge_android/test/quill_native_bridge_android_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:typed_data' as _i3; + +import 'package:mockito/mockito.dart' as _i1; + +import 'test_api.g.dart' as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [TestQuillNativeBridgeApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockTestQuillNativeBridgeApi extends _i1.Mock + implements _i2.TestQuillNativeBridgeApi { + MockTestQuillNativeBridgeApi() { + _i1.throwOnMissingStub(this); + } + + @override + void copyHtmlToClipboard(String? html) => super.noSuchMethod( + Invocation.method( + #copyHtmlToClipboard, + [html], + ), + returnValueForMissingStub: null, + ); + + @override + void copyImageToClipboard(_i3.Uint8List? imageBytes) => super.noSuchMethod( + Invocation.method( + #copyImageToClipboard, + [imageBytes], + ), + returnValueForMissingStub: null, + ); + + @override + void openGalleryApp() => super.noSuchMethod( + Invocation.method( + #openGalleryApp, + [], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future saveImageToGallery( + _i3.Uint8List? imageBytes, { + required String? name, + required String? fileExtension, + required String? mimeType, + required String? albumName, + }) => + (super.noSuchMethod( + Invocation.method( + #saveImageToGallery, + [imageBytes], + { + #name: name, + #fileExtension: fileExtension, + #mimeType: mimeType, + #albumName: albumName, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); +} diff --git a/quill_native_bridge_android/test/test_api.g.dart b/quill_native_bridge_android/test/test_api.g.dart new file mode 100644 index 0000000..e0d6bbd --- /dev/null +++ b/quill_native_bridge_android/test/test_api.g.dart @@ -0,0 +1,282 @@ +// Autogenerated from Pigeon (v22.6.2), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: avoid_relative_lib_imports +import 'dart:async'; +import 'dart:typed_data' show Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:quill_native_bridge_android/src/messages.g.dart'; + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class TestQuillNativeBridgeApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + String? getClipboardHtml(); + + void copyHtmlToClipboard(String html); + + Uint8List? getClipboardImage(); + + void copyImageToClipboard(Uint8List imageBytes); + + Uint8List? getClipboardGif(); + + void openGalleryApp(); + + /// The [fileExtension] is only required for Android APIs before 29. + Future saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String fileExtension, + required String mimeType, + required String? albumName, + }); + + static void setUp( + TestQuillNativeBridgeApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.getClipboardHtml$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final String? output = api.getClipboardHtml(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.copyHtmlToClipboard$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.copyHtmlToClipboard was null.'); + final List args = (message as List?)!; + final String? arg_html = (args[0] as String?); + assert(arg_html != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.copyHtmlToClipboard was null, expected non-null String.'); + try { + api.copyHtmlToClipboard(arg_html!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.getClipboardImage$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final Uint8List? output = api.getClipboardImage(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.copyImageToClipboard$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.copyImageToClipboard was null.'); + final List args = (message as List?)!; + final Uint8List? arg_imageBytes = (args[0] as Uint8List?); + assert(arg_imageBytes != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.copyImageToClipboard was null, expected non-null Uint8List.'); + try { + api.copyImageToClipboard(arg_imageBytes!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.getClipboardGif$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final Uint8List? output = api.getClipboardGif(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.openGalleryApp$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + api.openGalleryApp(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.saveImageToGallery$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.saveImageToGallery was null.'); + final List args = (message as List?)!; + final Uint8List? arg_imageBytes = (args[0] as Uint8List?); + assert(arg_imageBytes != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.saveImageToGallery was null, expected non-null Uint8List.'); + final String? arg_name = (args[1] as String?); + assert(arg_name != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.saveImageToGallery was null, expected non-null String.'); + final String? arg_fileExtension = (args[2] as String?); + assert(arg_fileExtension != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.saveImageToGallery was null, expected non-null String.'); + final String? arg_mimeType = (args[3] as String?); + assert(arg_mimeType != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_android.QuillNativeBridgeApi.saveImageToGallery was null, expected non-null String.'); + final String? arg_albumName = (args[4] as String?); + try { + await api.saveImageToGallery(arg_imageBytes!, + name: arg_name!, + fileExtension: arg_fileExtension!, + mimeType: arg_mimeType!, + albumName: arg_albumName); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} diff --git a/quill_native_bridge_ios/CHANGELOG.md b/quill_native_bridge_ios/CHANGELOG.md index 2a18e5d..d49dc7f 100644 --- a/quill_native_bridge_ios/CHANGELOG.md +++ b/quill_native_bridge_ios/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 0.0.1 + +- Adds support for saving images. + ## 0.0.1-dev.6 - Adds pub topics to package metadata. diff --git a/quill_native_bridge_ios/ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/Messages.g.swift b/quill_native_bridge_ios/ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/Messages.g.swift index 3cbdf35..94f2285 100644 --- a/quill_native_bridge_ios/ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/Messages.g.swift +++ b/quill_native_bridge_ios/ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/Messages.g.swift @@ -84,6 +84,7 @@ class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { static let shared = MessagesPigeonCodec(readerWriter: MessagesPigeonCodecReaderWriter()) } + /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol QuillNativeBridgeApi { func isIosSimulator() throws -> Bool @@ -92,6 +93,8 @@ protocol QuillNativeBridgeApi { func getClipboardImage() throws -> FlutterStandardTypedData? func copyImageToClipboard(imageBytes: FlutterStandardTypedData) throws func getClipboardGif() throws -> FlutterStandardTypedData? + func openGalleryApp(completion: @escaping (Result) -> Void) + func saveImageToGallery(imageBytes: FlutterStandardTypedData, name: String, albumName: String?, completion: @escaping (Result) -> Void) } /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. @@ -182,5 +185,39 @@ class QuillNativeBridgeApiSetup { } else { getClipboardGifChannel.setMessageHandler(nil) } + let openGalleryAppChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.openGalleryApp\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + openGalleryAppChannel.setMessageHandler { _, reply in + api.openGalleryApp { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + openGalleryAppChannel.setMessageHandler(nil) + } + let saveImageToGalleryChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.saveImageToGallery\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + saveImageToGalleryChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let imageBytesArg = args[0] as! FlutterStandardTypedData + let nameArg = args[1] as! String + let albumNameArg: String? = nilOrValue(args[2]) + api.saveImageToGallery(imageBytes: imageBytesArg, name: nameArg, albumName: albumNameArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + saveImageToGalleryChannel.setMessageHandler(nil) + } } } diff --git a/quill_native_bridge_ios/ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/QuillNativeBridgeImpl.swift b/quill_native_bridge_ios/ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/QuillNativeBridgeImpl.swift index bf43e22..eb58b40 100644 --- a/quill_native_bridge_ios/ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/QuillNativeBridgeImpl.swift +++ b/quill_native_bridge_ios/ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/QuillNativeBridgeImpl.swift @@ -1,5 +1,6 @@ import Foundation import Flutter +import Photos class QuillNativeBridgeImpl: QuillNativeBridgeApi { func isIosSimulator() throws -> Bool { @@ -51,4 +52,130 @@ class QuillNativeBridgeImpl: QuillNativeBridgeApi { return FlutterStandardTypedData(bytes: data) } + + func openGalleryApp(completion: @escaping (Result) -> Void) { + guard let url = URL(string: "photos-redirect://") else { + completion(.failure(PigeonError(code: "INVALID_URL", message: "The URL scheme is invalid.", details: "Unable to create a URL for 'photos-redirect://'."))) + return + } + guard UIApplication.shared.canOpenURL(url) else { + completion(.failure(PigeonError(code: "CANNOT_OPEN_URL", message: "Cannot open the Photos app.", details: "The device may not have the Photos app installed or it may not support the URL scheme."))) + return + } + UIApplication.shared.open(url, completionHandler: { success in + if success { + completion(.success(())) + } else { + completion(.failure(PigeonError(code: "UNKNOWN_ERROR", message: "Failed to open the Photos app.", details: "An unknown error occurred when trying to open the Photos app."))) + } + }) + + } + + func saveImageToGallery(imageBytes: FlutterStandardTypedData, name: String, albumName: String?, completion: @escaping (Result) -> Void) { + guard UIImage(data: imageBytes.data) != nil else { + completion(.failure(PigeonError(code: "INVALID_IMAGE", message: "Unable to create UIImage from image bytes.", details: nil))) + return + } + + let needsReadWritePermission = ProcessInfo.processInfo.operatingSystemVersion.majorVersion < 14 || albumName != nil + + let permissionKey = needsReadWritePermission ? "NSPhotoLibraryUsageDescription" : "NSPhotoLibraryAddUsageDescription" + guard let infoPlist = Bundle.main.infoDictionary, + let permissionDescription = infoPlist[permissionKey] as? String else { + completion(.failure(PigeonError( + code: "IOS_INFO_PLIST_NOT_CONFIGURED", + message: "The iOS `Info.plist` file has not been configured. The key `\(permissionKey)` is not set.", + details: nil + ))) + return + } + + func handlePermissionDenied(status: PHAuthorizationStatus) { + completion(.failure(PigeonError( + code: "PERMISSION_DENIED", + message: "The app doesn't have permission to save photos to the gallery.", + details: String(describing: status) + ))) + } + + func isAccessBlocked(status: PHAuthorizationStatus) -> Bool { + return status == .denied || status == .restricted + } + + if #available(iOS 14, *) { + let accessLevel: PHAccessLevel = needsReadWritePermission ? .readWrite : .addOnly + + let currentStatus = PHPhotoLibrary.authorizationStatus(for: accessLevel) + + guard !isAccessBlocked(status: currentStatus) else { + handlePermissionDenied(status: currentStatus) + return + } + + if currentStatus == .notDetermined { + PHPhotoLibrary.requestAuthorization(for: accessLevel) { status in + guard !isAccessBlocked(status: status) else { + handlePermissionDenied(status: status) + return + } + } + } + } else { + // For iOS 13 and previous versions + let currentStatus = PHPhotoLibrary.authorizationStatus() + + guard !isAccessBlocked(status: currentStatus) else { + handlePermissionDenied(status: currentStatus) + return + } + + if currentStatus == .notDetermined { + PHPhotoLibrary.requestAuthorization { status in + guard !isAccessBlocked(status: status) else { + handlePermissionDenied(status: status) + return + } + } + } + } + + // TODO(save-image): Warning "Attempted fetch within change block can trigger deadlock, returning unauthorized fetch result", fix for macOS too. + + PHPhotoLibrary.shared().performChanges({ + let assetRequest = PHAssetCreationRequest.forAsset() + + let options = PHAssetResourceCreationOptions() + options.originalFilename = name + assetRequest.addResource(with: .photo, data: imageBytes.data, options: options) + + if let albumName = albumName { + + let albumFetchOptions = PHFetchOptions() + albumFetchOptions.predicate = NSPredicate(format: "title = %@", albumName) + let existingAlbum = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: albumFetchOptions).firstObject + + if existingAlbum == nil { + // Create the album + let albumChangeRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName) + albumChangeRequest.addAssets([assetRequest.placeholderForCreatedAsset] as NSArray) + + } else if let album = existingAlbum { + // Add the image to the existing album + let albumChangeRequest = PHAssetCollectionChangeRequest(for: album) + albumChangeRequest?.addAssets([assetRequest.placeholderForCreatedAsset] as NSArray) + } + } + }) { success, error in + guard success else { + completion(.failure(PigeonError( + code: "SAVE_FAILED", + message: "Failed to save the image to the gallery: \(error?.localizedDescription)", + details: String(describing: error) + ))) + return + } + completion(.success(())) + } + } } diff --git a/quill_native_bridge_ios/lib/quill_native_bridge_ios.dart b/quill_native_bridge_ios/lib/quill_native_bridge_ios.dart index 0dd3919..53643cf 100644 --- a/quill_native_bridge_ios/lib/quill_native_bridge_ios.dart +++ b/quill_native_bridge_ios/lib/quill_native_bridge_ios.dart @@ -1,7 +1,7 @@ // This file is referenced by pubspec.yaml. If you plan on moving this file // Make sure to update pubspec.yaml to the new location. -import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; import 'src/messages.g.dart'; @@ -23,6 +23,8 @@ class QuillNativeBridgeIos extends QuillNativeBridgePlatform { QuillNativeBridgeFeature.copyImageToClipboard, QuillNativeBridgeFeature.getClipboardImage, QuillNativeBridgeFeature.getClipboardGif, + QuillNativeBridgeFeature.openGalleryApp, + QuillNativeBridgeFeature.saveImageToGallery, }.contains(feature); @override @@ -44,4 +46,32 @@ class QuillNativeBridgeIos extends QuillNativeBridgePlatform { @override Future getClipboardGif() => _hostApi.getClipboardGif(); + + @override + Future openGalleryApp() => _hostApi.openGalleryApp(); + + @override + Future saveImageToGallery( + Uint8List imageBytes, { + required GalleryImageSaveOptions options, + }) async { + try { + await _hostApi.saveImageToGallery(imageBytes, + name: options.name, albumName: options.albumName); + } on PlatformException catch (e) { + assert(() { + if (e.code == 'IOS_INFO_PLIST_NOT_CONFIGURED') { + throw StateError( + '\nThe Info.plist file was not configured to support saving images to the gallery on iOS.\n' + 'For more details, refer to https://pub.dev/packages/quill_native_bridge#-saving-images-to-the-gallery\n' + 'This exception will be only thrown in debug mode.\n\n' + 'Platform error details: ${e.toString()}', + ); + } + return true; + }()); + + rethrow; + } + } } diff --git a/quill_native_bridge_ios/lib/src/messages.g.dart b/quill_native_bridge_ios/lib/src/messages.g.dart index fb2f4f4..13a53a7 100644 --- a/quill_native_bridge_ios/lib/src/messages.g.dart +++ b/quill_native_bridge_ios/lib/src/messages.g.dart @@ -15,6 +15,17 @@ PlatformException _createConnectionError(String channelName) { ); } +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override @@ -199,4 +210,56 @@ class QuillNativeBridgeApi { return (pigeonVar_replyList[0] as Uint8List?); } } + + Future openGalleryApp() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.openGalleryApp$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String? albumName, + }) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.saveImageToGallery$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([imageBytes, name, albumName]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } } diff --git a/quill_native_bridge_ios/pigeons/messages.dart b/quill_native_bridge_ios/pigeons/messages.dart index 5f8a202..001139b 100644 --- a/quill_native_bridge_ios/pigeons/messages.dart +++ b/quill_native_bridge_ios/pigeons/messages.dart @@ -2,11 +2,12 @@ import 'package:pigeon/pigeon.dart'; @ConfigurePigeon(PigeonOptions( dartOut: 'lib/src/messages.g.dart', + dartTestOut: 'test/test_api.g.dart', swiftOut: 'ios/quill_native_bridge_ios/Sources/quill_native_bridge_ios/Messages.g.swift', dartPackageName: 'quill_native_bridge_ios', )) -@HostApi() +@HostApi(dartHostTestHandler: 'TestQuillNativeBridgeApi') abstract class QuillNativeBridgeApi { bool isIosSimulator(); @@ -18,4 +19,14 @@ abstract class QuillNativeBridgeApi { Uint8List? getClipboardImage(); void copyImageToClipboard(Uint8List imageBytes); Uint8List? getClipboardGif(); + + @async + void openGalleryApp(); + + @async + void saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String? albumName, + }); } diff --git a/quill_native_bridge_ios/pubspec.yaml b/quill_native_bridge_ios/pubspec.yaml index 480cb28..cebe98e 100644 --- a/quill_native_bridge_ios/pubspec.yaml +++ b/quill_native_bridge_ios/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge_ios description: "iOS implementation of the quill_native_bridge plugin." -version: 0.0.1-dev.6 +version: 0.0.1 homepage: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_ios repository: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_ios issue_tracker: https://github.com/FlutterQuill/quill-native-bridge/issues?q=is%3Aissue+is%3Aopen+label%3A%22platform-ios%22 @@ -14,13 +14,15 @@ environment: dependencies: flutter: sdk: flutter - quill_native_bridge_platform_interface: ^0.0.1-dev.4 + quill_native_bridge_platform_interface: ^0.0.1 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 pigeon: ^22.6.2 + mockito: ^5.4.4 + build_runner: ^2.4.13 flutter: plugin: diff --git a/quill_native_bridge_ios/test/quill_native_bridge_ios_test.dart b/quill_native_bridge_ios/test/quill_native_bridge_ios_test.dart new file mode 100644 index 0000000..0f77c5d --- /dev/null +++ b/quill_native_bridge_ios/test/quill_native_bridge_ios_test.dart @@ -0,0 +1,265 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:quill_native_bridge_ios/quill_native_bridge_ios.dart'; +import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; + +import 'test_api.g.dart'; + +@GenerateMocks([TestQuillNativeBridgeApi]) +import 'quill_native_bridge_ios_test.mocks.dart'; + +void main() { + // Required when calling TestQuillNativeBridgeApi.setUp() + TestWidgetsFlutterBinding.ensureInitialized(); + + late QuillNativeBridgeIos plugin; + late MockTestQuillNativeBridgeApi mockHostApi; + + setUp(() { + plugin = QuillNativeBridgeIos(); + mockHostApi = MockTestQuillNativeBridgeApi(); + TestQuillNativeBridgeApi.setUp(mockHostApi); + + when(mockHostApi.openGalleryApp()).thenAnswer((_) async {}); + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenAnswer((_) async {}); + }); + + test('registered instance', () { + QuillNativeBridgeIos.registerWith(); + expect(QuillNativeBridgePlatform.instance, isA()); + }); + + test( + 'isIOSSimulator delegates to _hostApi.isIOSSimulator', + () async { + when(mockHostApi.isIosSimulator()).thenReturn(false); + final result = await plugin.isIOSSimulator(); + verify(mockHostApi.isIosSimulator()).called(1); + expect(result, isFalse); + + when(mockHostApi.isIosSimulator()).thenReturn(true); + final result2 = await plugin.isIOSSimulator(); + verify(mockHostApi.isIosSimulator()).called(1); + expect(result2, isTrue); + }, + ); + + group( + 'clipboard', + () { + test( + 'getClipboardHtml delegates to _hostApi.getClipboardHtml', + () async { + when(mockHostApi.getClipboardHtml()).thenReturn(null); + final nullHtml = await plugin.getClipboardHtml(); + verify(mockHostApi.getClipboardHtml()).called(1); + expect(nullHtml, isNull); + + final exampleHtml = 'An HTML'; + + when(mockHostApi.getClipboardHtml()).thenReturn(exampleHtml); + final nonNullHtml = await plugin.getClipboardHtml(); + verify(mockHostApi.getClipboardHtml()).called(1); + expect(nonNullHtml, equals(exampleHtml)); + }, + ); + + test( + 'copyHtmlToClipboard delegates to _hostApi.copyHtmlToClipboard', + () async { + final input = 'Example HTML'; + when(mockHostApi.copyHtmlToClipboard(input)).thenReturn(null); + await plugin.copyHtmlToClipboard(input); + verify(mockHostApi.copyHtmlToClipboard(input)).called(1); + }, + ); + + test( + 'getClipboardImage delegates to _hostApi.getClipboardImage', + () async { + when(mockHostApi.getClipboardImage()).thenReturn(null); + final nullImage = await plugin.getClipboardImage(); + verify(mockHostApi.getClipboardImage()).called(1); + expect(nullImage, isNull); + + final exampleImage = Uint8List.fromList([1, 0, 1]); + + when(mockHostApi.getClipboardImage()).thenReturn(exampleImage); + final nonNullImage = await plugin.getClipboardImage(); + verify(mockHostApi.getClipboardImage()).called(1); + expect(nonNullImage, equals(exampleImage)); + }, + ); + + test( + 'copyImageToClipboard delegates to _hostApi.copyImageToClipboard', + () async { + final input = Uint8List.fromList([1, 0, 1]); + when(mockHostApi.copyImageToClipboard(input)).thenReturn(null); + await plugin.copyImageToClipboard(input); + verify(mockHostApi.copyImageToClipboard(input)).called(1); + }, + ); + + test( + 'getClipboardGif delegates to _hostApi.getClipboardGif', + () async { + when(mockHostApi.getClipboardGif()).thenReturn(null); + final nullImage = await plugin.getClipboardGif(); + verify(mockHostApi.getClipboardGif()).called(1); + expect(nullImage, isNull); + + final exampleImage = Uint8List.fromList([1, 0, 1]); + + when(mockHostApi.getClipboardGif()).thenReturn(exampleImage); + final nonNullImage = await plugin.getClipboardGif(); + verify(mockHostApi.getClipboardGif()).called(1); + expect(nonNullImage, equals(exampleImage)); + }, + ); + }, + ); + + group('gallery', () { + test( + 'openGalleryApp delegates to _hostApi.openGalleryApp', + () async { + await plugin.openGalleryApp(); + verify(mockHostApi.openGalleryApp()).called(1); + }, + ); + + group('saveImageToGallery', () { + test( + 'delegates to _hostApi.saveImageToGallery', + () async { + await plugin.saveImageToGallery( + Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + ), + ); + verify(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).called(1); + }, + ); + + test( + 'passes the arguments correctly to the platform host API', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + final imageName = 'ExampleImage'; + final imageAlbumName = 'ExampleAlbum'; + + when(mockHostApi.saveImageToGallery( + imageBytes, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenAnswer((_) async => null); + + await plugin.saveImageToGallery(imageBytes, + options: GalleryImageSaveOptions( + name: imageName, + fileExtension: 'png', + albumName: imageAlbumName, + )); + + final capturedOptions = verify(mockHostApi.saveImageToGallery( + captureAny, + name: captureAnyNamed('name'), + albumName: captureAnyNamed('albumName'), + )).captured; + + expect(capturedOptions[0] as Uint8List, imageBytes); + expect(capturedOptions[1] as String, imageName); + expect(capturedOptions[2] as String, imageAlbumName); + }, + ); + + test( + 'throws $StateError in debug mode for common issues', + () { + void expectThrowsForCode(String errorCode, + {required String containsMessage}) { + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenThrow(PlatformException(code: errorCode)); + expect( + plugin.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + )), + throwsA(isA().having( + (e) => e.message, + 'message', + contains(containsMessage), + )), + ); + } + + expectThrowsForCode( + 'IOS_INFO_PLIST_NOT_CONFIGURED', + containsMessage: + 'The Info.plist file was not configured to support saving images to the gallery on iOS.', + ); + }, + ); + + test( + 'rethrows the $PlatformException from _hostApi.saveImageToGallery if not handled', + () async { + // Currently, that's the expected behavior but it is subject to changes for improvements. + // See https://github.com/FlutterQuill/quill-native-bridge/issues/2 + + const errorCode = '404'; + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenThrow(PlatformException(code: errorCode)); + expect( + plugin.saveImageToGallery( + Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + ), + ), + throwsA(isA() + .having((e) => e.code, 'code', errorCode)), + ); + + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenAnswer((_) async {}); + await expectLater( + plugin.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + )), + completes, + ); + }); + }); + }); +} diff --git a/quill_native_bridge_ios/test/quill_native_bridge_ios_test.mocks.dart b/quill_native_bridge_ios/test/quill_native_bridge_ios_test.mocks.dart new file mode 100644 index 0000000..3641a66 --- /dev/null +++ b/quill_native_bridge_ios/test/quill_native_bridge_ios_test.mocks.dart @@ -0,0 +1,90 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in quill_native_bridge_ios/test/quill_native_bridge_ios_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:typed_data' as _i3; + +import 'package:mockito/mockito.dart' as _i1; + +import 'test_api.g.dart' as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [TestQuillNativeBridgeApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockTestQuillNativeBridgeApi extends _i1.Mock + implements _i2.TestQuillNativeBridgeApi { + MockTestQuillNativeBridgeApi() { + _i1.throwOnMissingStub(this); + } + + @override + bool isIosSimulator() => (super.noSuchMethod( + Invocation.method( + #isIosSimulator, + [], + ), + returnValue: false, + ) as bool); + + @override + void copyHtmlToClipboard(String? html) => super.noSuchMethod( + Invocation.method( + #copyHtmlToClipboard, + [html], + ), + returnValueForMissingStub: null, + ); + + @override + void copyImageToClipboard(_i3.Uint8List? imageBytes) => super.noSuchMethod( + Invocation.method( + #copyImageToClipboard, + [imageBytes], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future openGalleryApp() => (super.noSuchMethod( + Invocation.method( + #openGalleryApp, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future saveImageToGallery( + _i3.Uint8List? imageBytes, { + required String? name, + required String? albumName, + }) => + (super.noSuchMethod( + Invocation.method( + #saveImageToGallery, + [imageBytes], + { + #name: name, + #albumName: albumName, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); +} diff --git a/quill_native_bridge_ios/test/test_api.g.dart b/quill_native_bridge_ios/test/test_api.g.dart new file mode 100644 index 0000000..85cab11 --- /dev/null +++ b/quill_native_bridge_ios/test/test_api.g.dart @@ -0,0 +1,298 @@ +// Autogenerated from Pigeon (v22.6.2), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers, unused_shown_name +// ignore_for_file: avoid_relative_lib_imports +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:quill_native_bridge_ios/src/messages.g.dart'; + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class TestQuillNativeBridgeApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + bool isIosSimulator(); + + String? getClipboardHtml(); + + void copyHtmlToClipboard(String html); + + Uint8List? getClipboardImage(); + + void copyImageToClipboard(Uint8List imageBytes); + + Uint8List? getClipboardGif(); + + Future openGalleryApp(); + + Future saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String? albumName, + }); + + static void setUp( + TestQuillNativeBridgeApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.isIosSimulator$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final bool output = api.isIosSimulator(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.getClipboardHtml$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final String? output = api.getClipboardHtml(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.copyHtmlToClipboard$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.copyHtmlToClipboard was null.'); + final List args = (message as List?)!; + final String? arg_html = (args[0] as String?); + assert(arg_html != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.copyHtmlToClipboard was null, expected non-null String.'); + try { + api.copyHtmlToClipboard(arg_html!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.getClipboardImage$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final Uint8List? output = api.getClipboardImage(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.copyImageToClipboard$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.copyImageToClipboard was null.'); + final List args = (message as List?)!; + final Uint8List? arg_imageBytes = (args[0] as Uint8List?); + assert(arg_imageBytes != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.copyImageToClipboard was null, expected non-null Uint8List.'); + try { + api.copyImageToClipboard(arg_imageBytes!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.getClipboardGif$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final Uint8List? output = api.getClipboardGif(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.openGalleryApp$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + await api.openGalleryApp(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.saveImageToGallery$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.saveImageToGallery was null.'); + final List args = (message as List?)!; + final Uint8List? arg_imageBytes = (args[0] as Uint8List?); + assert(arg_imageBytes != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.saveImageToGallery was null, expected non-null Uint8List.'); + final String? arg_name = (args[1] as String?); + assert(arg_name != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_ios.QuillNativeBridgeApi.saveImageToGallery was null, expected non-null String.'); + final String? arg_albumName = (args[2] as String?); + try { + await api.saveImageToGallery(arg_imageBytes!, + name: arg_name!, albumName: arg_albumName); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} diff --git a/quill_native_bridge_linux/CHANGELOG.md b/quill_native_bridge_linux/CHANGELOG.md index 0b8b338..491b56c 100644 --- a/quill_native_bridge_linux/CHANGELOG.md +++ b/quill_native_bridge_linux/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 0.0.1 + +- Adds support for saving images. + ## 0.0.1-dev.4 - Adds pub topics to package metadata. diff --git a/quill_native_bridge_linux/lib/quill_native_bridge_linux.dart b/quill_native_bridge_linux/lib/quill_native_bridge_linux.dart index 9a0d245..e268f82 100644 --- a/quill_native_bridge_linux/lib/quill_native_bridge_linux.dart +++ b/quill_native_bridge_linux/lib/quill_native_bridge_linux.dart @@ -4,8 +4,11 @@ import 'dart:convert' show utf8; import 'dart:io' show Process, File hide exitCode; -import 'package:flutter/services.dart' show Uint8List; +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:flutter/foundation.dart'; +import 'package:quill_native_bridge_linux/src/image_saver.dart'; import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; +import 'package:quill_native_bridge_platform_interface/src/image_mime_utils.dart'; import 'src/binary_runner.dart'; import 'src/constants.dart'; @@ -25,6 +28,7 @@ class QuillNativeBridgeLinux extends QuillNativeBridgePlatform { QuillNativeBridgeFeature.copyImageToClipboard, QuillNativeBridgeFeature.getClipboardImage, QuillNativeBridgeFeature.getClipboardFiles, + QuillNativeBridgeFeature.saveImage, }.contains(feature); // TODO: Improve error handling @@ -234,4 +238,36 @@ class QuillNativeBridgeLinux extends QuillNativeBridgePlatform { await xclipFile.delete(); } } + + @visibleForTesting + static ImageSaver imageSaver = ImageSaver(); + + @override + Future saveImage( + Uint8List imageBytes, { + required ImageSaveOptions options, + }) async { + final typeGroup = XTypeGroup( + label: 'Images', + // The arguments `extensions` and `mimeTypes` are both supported on Linux. See https://pub.dev/packages/file_selector#filtering-by-file-types + extensions: [options.fileExtension], + mimeTypes: [getImageMimeType(options.fileExtension)], + ); + + final saveLocation = await imageSaver.fileSelector.getSaveLocation( + options: SaveDialogOptions( + suggestedName: '${options.name}.${options.fileExtension}', + initialDirectory: imageSaver.picturesDirectoryPath, + ), + acceptedTypeGroups: [typeGroup], + ); + final imageFilePath = saveLocation?.path; + if (imageFilePath == null) { + return ImageSaveResult.io(filePath: null); + } + final imageFile = File(imageFilePath); + await imageFile.writeAsBytes(imageBytes); + + return ImageSaveResult.io(filePath: imageFile.path); + } } diff --git a/quill_native_bridge_linux/lib/src/environment_provider.dart b/quill_native_bridge_linux/lib/src/environment_provider.dart new file mode 100644 index 0000000..4fa9c2c --- /dev/null +++ b/quill_native_bridge_linux/lib/src/environment_provider.dart @@ -0,0 +1,21 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; + +abstract class EnvironmentProvider { + Map get environment; + + static EnvironmentProvider _instance = DefaultEnvironmentProvider(); + + static EnvironmentProvider get instance => _instance; + + @visibleForTesting + static void set instance(value) => _instance = value; + + static void setToDefault() => _instance = DefaultEnvironmentProvider(); +} + +class DefaultEnvironmentProvider implements EnvironmentProvider { + @override + Map get environment => Platform.environment; +} diff --git a/quill_native_bridge_linux/lib/src/image_saver.dart b/quill_native_bridge_linux/lib/src/image_saver.dart new file mode 100644 index 0000000..e3a637f --- /dev/null +++ b/quill_native_bridge_linux/lib/src/image_saver.dart @@ -0,0 +1,23 @@ +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:file_selector_linux/file_selector_linux.dart'; +import 'package:quill_native_bridge_linux/src/environment_provider.dart'; + +class ImageSaver { + /// The file selector that's used to prompt the user to choose a directory + /// for saving an image. + FileSelectorPlatform fileSelector = FileSelectorLinux(); + + static const String linuxUserHomeEnvKey = 'HOME'; + + static const String picturesDirectoryName = 'Pictures'; + + String? get userHome => + EnvironmentProvider.instance.environment[linuxUserHomeEnvKey]; + + String? get picturesDirectoryPath { + final userHome = this.userHome; + if (userHome == null) return null; + if (userHome.isEmpty) return null; + return '${userHome}/${picturesDirectoryName}'; + } +} diff --git a/quill_native_bridge_linux/pubspec.yaml b/quill_native_bridge_linux/pubspec.yaml index 6950667..c18cfea 100644 --- a/quill_native_bridge_linux/pubspec.yaml +++ b/quill_native_bridge_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge_linux description: "Linux implementation of the quill_native_bridge plugin." -version: 0.0.1-dev.4 +version: 0.0.1 homepage: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_linux repository: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_linux issue_tracker: https://github.com/FlutterQuill/quill-native-bridge/issues?q=is%3Aissue+is%3Aopen+label%3A%22platform-linux%22 @@ -14,7 +14,9 @@ environment: dependencies: flutter: sdk: flutter - quill_native_bridge_platform_interface: ^0.0.1-dev.4 + quill_native_bridge_platform_interface: ^0.0.1 + file_selector_linux: ^0.9.1+1 + file_selector_platform_interface: ^2.4.0 dev_dependencies: flutter_test: @@ -22,6 +24,8 @@ dev_dependencies: flutter_lints: ^4.0.0 crypto: ^3.0.5 yaml: ^3.1.2 + mockito: ^5.4.4 + build_runner: ^2.4.13 flutter: assets: @@ -32,4 +36,4 @@ flutter: linux: pluginClass: none dartPluginClass: QuillNativeBridgeLinux - fileName: quill_native_bridge_linux.dart \ No newline at end of file + fileName: quill_native_bridge_linux.dart diff --git a/quill_native_bridge_linux/test/environment_provider_test.dart b/quill_native_bridge_linux/test/environment_provider_test.dart new file mode 100644 index 0000000..60b937d --- /dev/null +++ b/quill_native_bridge_linux/test/environment_provider_test.dart @@ -0,0 +1,40 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:quill_native_bridge_linux/src/environment_provider.dart'; + +void main() { + test('defaults to $DefaultEnvironmentProvider', () { + expect(EnvironmentProvider.instance, isA()); + }); + test('should update the instance correctly', () { + expect( + EnvironmentProvider.instance, isNot(isA<_FakeEnvironmentProvider>())); + + EnvironmentProvider.instance = _FakeEnvironmentProvider(); + expect(EnvironmentProvider.instance, isA<_FakeEnvironmentProvider>()); + }); + + test( + 'environment getter from the instance delegates to the new provider instance', + () { + final fake = _FakeEnvironmentProvider(); + fake.testEnvironment.addAll({ + 'test': 'foo/bar', + }); + EnvironmentProvider.instance = fake; + expect(EnvironmentProvider.instance.environment, fake.environment); + }); + + test('setToDefault restore the default instance', () { + final fake = _FakeEnvironmentProvider(); + EnvironmentProvider.instance = fake; + + EnvironmentProvider.setToDefault(); + expect(EnvironmentProvider.instance, isA()); + }); +} + +class _FakeEnvironmentProvider implements DefaultEnvironmentProvider { + final Map testEnvironment = {}; + @override + Map get environment => testEnvironment; +} diff --git a/quill_native_bridge_linux/test/quill_native_bridge_linux_test.dart b/quill_native_bridge_linux/test/quill_native_bridge_linux_test.dart new file mode 100644 index 0000000..807e805 --- /dev/null +++ b/quill_native_bridge_linux/test/quill_native_bridge_linux_test.dart @@ -0,0 +1,336 @@ +import 'dart:io'; + +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:file_selector_linux/file_selector_linux.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:quill_native_bridge_linux/quill_native_bridge_linux.dart'; +import 'package:quill_native_bridge_linux/src/environment_provider.dart'; +import 'package:quill_native_bridge_linux/src/image_saver.dart'; +import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; +import 'package:quill_native_bridge_platform_interface/src/image_mime_utils.dart'; + +@GenerateMocks([FileSelectorPlatform, EnvironmentProvider]) +import 'quill_native_bridge_linux_test.mocks.dart'; + +final _fakeLinuxUserHomeDir = '/home/foo-bar/Pictures'; + +void main() { + late QuillNativeBridgeLinux plugin; + + setUp(() { + plugin = QuillNativeBridgeLinux(); + }); + + test('registered instance', () { + QuillNativeBridgeLinux.registerWith(); + expect(QuillNativeBridgePlatform.instance, isA()); + }); + + test('defaults image saver instance to $ImageSaver', () { + expect(QuillNativeBridgeLinux.imageSaver, isA()); + }); + + group('$ImageSaver', () { + // A file that always exists during tests + late File imageTestFile; + late MockEnvironmentProvider mockEnvironmentProvider; + late MockFileSelectorPlatform mockFileSelectorPlatform; + late ImageSaver imageSaver; + + setUp(() async { + mockFileSelectorPlatform = MockFileSelectorPlatform(); + + imageSaver = ImageSaver(); + imageSaver.fileSelector = mockFileSelectorPlatform; + + QuillNativeBridgeLinux.imageSaver = imageSaver; + + mockEnvironmentProvider = MockEnvironmentProvider(); + EnvironmentProvider.instance = mockEnvironmentProvider; + + imageTestFile = File( + '${Directory.systemTemp.path}/tempImageTest_${DateTime.now().millisecondsSinceEpoch}.png'); + await imageTestFile.create(); + + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => null); + when(mockEnvironmentProvider.environment).thenReturn({}); + }); + + tearDown(() async { + await imageTestFile.delete(); + }); + + test( + 'The Linux user home environment key should be correct', + () { + expect(ImageSaver.linuxUserHomeEnvKey, equals('HOME')); + }, + ); + + test('The pictures directory name should be correct', () { + expect(ImageSaver.picturesDirectoryName, equals('Pictures')); + }); + + test( + 'saveImage should return null for file path when user cancels save dialog', + () async { + final filePath = (await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ))) + .filePath; + expect(filePath, isNull); + }, + ); + + test( + 'file selector instance internally defaults to $FileSelectorLinux', + () { + expect(ImageSaver().fileSelector, isA()); + }, + ); + + test( + 'userHome delegates to Platform.environment with the correct key', + () { + when(mockEnvironmentProvider.environment).thenReturn( + {ImageSaver.linuxUserHomeEnvKey: _fakeLinuxUserHomeDir}); + expect(imageSaver.userHome, equals(_fakeLinuxUserHomeDir)); + + verify(mockEnvironmentProvider + .environment[ImageSaver.linuxUserHomeEnvKey]) + .called(1); + + when(mockEnvironmentProvider.environment) + .thenReturn({ImageSaver.linuxUserHomeEnvKey: ''}); + expect(imageSaver.userHome, equals('')); + + verify(mockEnvironmentProvider + .environment[ImageSaver.linuxUserHomeEnvKey]) + .called(1); + }, + ); + + test( + 'picturesDirectoryPath returns null when userHome is empty or null', + () { + when(mockEnvironmentProvider.environment) + .thenReturn({ImageSaver.linuxUserHomeEnvKey: ''}); + expect(imageSaver.picturesDirectoryPath, isNull); + verify(imageSaver.userHome).called(1); + + when(mockEnvironmentProvider.environment) + .thenReturn({ImageSaver.linuxUserHomeEnvKey: null}); + expect(imageSaver.picturesDirectoryPath, isNull); + verify(imageSaver.userHome).called(1); + }, + ); + + test( + 'picturesDirectoryPath depends on userHome', + () { + when(mockEnvironmentProvider.environment) + .thenReturn({ImageSaver.linuxUserHomeEnvKey: ''}); + imageSaver.picturesDirectoryPath; + verify(mockEnvironmentProvider + .environment[ImageSaver.linuxUserHomeEnvKey]); + }, + ); + + test( + 'picturesDirectoryPath correctly joins user home with pictures directory', + () { + when(mockEnvironmentProvider.environment).thenReturn( + {ImageSaver.linuxUserHomeEnvKey: _fakeLinuxUserHomeDir}); + expect( + imageSaver.picturesDirectoryPath, + equals( + '${_fakeLinuxUserHomeDir}/${ImageSaver.picturesDirectoryName}'), + ); + }, + ); + + test( + 'saveImage should return file path if save is successful', + () async { + final saveLocation = FileSaveLocation(imageTestFile.path); + + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => saveLocation); + + final filePath = (await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ))) + .filePath; + + expect(filePath, equals(saveLocation.path)); + }, + ); + test( + 'saveImage passes the arguments correctly to fileSelector.getSaveLocation', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + final options = ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'jpg', + ); + + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer( + (invocation) async => FileSaveLocation(imageTestFile.path)); + + await plugin.saveImage(imageBytes, options: options); + + final capturedOptions = verify(mockFileSelectorPlatform.getSaveLocation( + options: captureAnyNamed('options'), + acceptedTypeGroups: captureAnyNamed('acceptedTypeGroups'), + )).captured; + + SaveDialogOptions? passedOptions = + capturedOptions[0] as SaveDialogOptions; + List passedAcceptedTypeGroups = + capturedOptions[1] as List; + + expect(passedOptions.suggestedName, + '${options.name}.${options.fileExtension}'); + expect( + passedOptions.initialDirectory, imageSaver.picturesDirectoryPath); + expect(passedAcceptedTypeGroups.map((e) => e.toJSON()), [ + XTypeGroup( + label: 'Images', + extensions: [options.fileExtension], + mimeTypes: [getImageMimeType(options.fileExtension)], + ).toJSON() + ]); + }, + ); + + test('saveImage calls fileSelector.getSaveLocation only once', () async { + await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + )); + verify(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).called(1); + }); + + test( + 'saveImage returns null when $FileSaveLocation from fileSelector.getSaveLocation is null', + () async { + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => null); + + final imageFilePath = + (await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ))) + .filePath; + + expect(imageFilePath, isNull); + }, + ); + + test( + 'saveImage passes the mimeTypes correctly to fileSelector.getSaveLocation', + () async { + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => null); + + final options = ImageSaveOptions( + name: 'ImageName', + // IMPORTANT: Use jpg specifically instead of jpeg or png + // since the "image/jpg" is invalid and it will verify behavior, + // ensuring the mimeType is passed correctly. + fileExtension: 'jpg', + ); + await plugin.saveImage(Uint8List.fromList([]), options: options); + + final capturedOptions = verify(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: captureAnyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).captured; + expect((capturedOptions[0] as List).first.mimeTypes, + [getImageMimeType(options.fileExtension)]); + }, + ); + + test( + 'saveImage writes the bytes to the file on success', + () async { + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => FileSaveLocation(imageTestFile.path)); + + final imageBytes = Uint8List.fromList([1, 0, 1]); + + expect(imageTestFile.existsSync(), isTrue, + reason: 'The $setUp should create the test file'); + + final filePath = (await plugin.saveImage(imageBytes, + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ))) + .filePath; + if (filePath == null) { + fail('Expected the operation to succeed.'); + } + + expect(imageTestFile.readAsBytesSync(), imageBytes); + expect(File(filePath).readAsBytesSync(), imageBytes); + }, + ); + + test( + 'saveImage always passes null to blob URL on non-web platforms', + () async { + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('acceptedTypeGroups'), + )).thenAnswer((_) async => null); + final result = await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + )); + expect(result.blobUrl, isNull); + + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => FileSaveLocation(imageTestFile.path)); + + final result2 = await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + )); + expect(result2.blobUrl, isNull); + expect(result2.filePath, imageTestFile.path); + }, + ); + }); +} diff --git a/quill_native_bridge_linux/test/quill_native_bridge_linux_test.mocks.dart b/quill_native_bridge_linux/test/quill_native_bridge_linux_test.mocks.dart new file mode 100644 index 0000000..d890bc4 --- /dev/null +++ b/quill_native_bridge_linux/test/quill_native_bridge_linux_test.mocks.dart @@ -0,0 +1,160 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in quill_native_bridge_linux/test/quill_native_bridge_linux_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:quill_native_bridge_linux/src/environment_provider.dart' as _i4; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [FileSelectorPlatform]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockFileSelectorPlatform extends _i1.Mock + implements _i2.FileSelectorPlatform { + MockFileSelectorPlatform() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Future<_i2.XFile?> openFile({ + List<_i2.XTypeGroup>? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #openFile, + [], + { + #acceptedTypeGroups: acceptedTypeGroups, + #initialDirectory: initialDirectory, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future<_i2.XFile?>.value(), + ) as _i3.Future<_i2.XFile?>); + + @override + _i3.Future> openFiles({ + List<_i2.XTypeGroup>? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #openFiles, + [], + { + #acceptedTypeGroups: acceptedTypeGroups, + #initialDirectory: initialDirectory, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future>.value(<_i2.XFile>[]), + ) as _i3.Future>); + + @override + _i3.Future getSavePath({ + List<_i2.XTypeGroup>? acceptedTypeGroups, + String? initialDirectory, + String? suggestedName, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #getSavePath, + [], + { + #acceptedTypeGroups: acceptedTypeGroups, + #initialDirectory: initialDirectory, + #suggestedName: suggestedName, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future<_i2.FileSaveLocation?> getSaveLocation({ + List<_i2.XTypeGroup>? acceptedTypeGroups, + _i2.SaveDialogOptions? options = const _i2.SaveDialogOptions(), + }) => + (super.noSuchMethod( + Invocation.method( + #getSaveLocation, + [], + { + #acceptedTypeGroups: acceptedTypeGroups, + #options: options, + }, + ), + returnValue: _i3.Future<_i2.FileSaveLocation?>.value(), + ) as _i3.Future<_i2.FileSaveLocation?>); + + @override + _i3.Future getDirectoryPath({ + String? initialDirectory, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #getDirectoryPath, + [], + { + #initialDirectory: initialDirectory, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future> getDirectoryPaths({ + String? initialDirectory, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #getDirectoryPaths, + [], + { + #initialDirectory: initialDirectory, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future>.value([]), + ) as _i3.Future>); +} + +/// A class which mocks [EnvironmentProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockEnvironmentProvider extends _i1.Mock + implements _i4.EnvironmentProvider { + MockEnvironmentProvider() { + _i1.throwOnMissingStub(this); + } + + @override + Map get environment => (super.noSuchMethod( + Invocation.getter(#environment), + returnValue: {}, + ) as Map); +} diff --git a/quill_native_bridge_macos/CHANGELOG.md b/quill_native_bridge_macos/CHANGELOG.md index bae8e78..b8aa265 100644 --- a/quill_native_bridge_macos/CHANGELOG.md +++ b/quill_native_bridge_macos/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 0.0.1 + +- Adds support for saving images. + ## 0.0.1-dev.5 - Adds pub topics to package metadata. diff --git a/quill_native_bridge_macos/lib/quill_native_bridge_macos.dart b/quill_native_bridge_macos/lib/quill_native_bridge_macos.dart index 9b1b4eb..a1519e1 100644 --- a/quill_native_bridge_macos/lib/quill_native_bridge_macos.dart +++ b/quill_native_bridge_macos/lib/quill_native_bridge_macos.dart @@ -1,7 +1,7 @@ // This file is referenced by pubspec.yaml. If you plan on moving this file // Make sure to update pubspec.yaml to the new location. -import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; import 'src/messages.g.dart'; @@ -16,13 +16,20 @@ class QuillNativeBridgeMacOS extends QuillNativeBridgePlatform { } @override - Future isSupported(QuillNativeBridgeFeature feature) async => { - QuillNativeBridgeFeature.getClipboardHtml, - QuillNativeBridgeFeature.copyHtmlToClipboard, - QuillNativeBridgeFeature.copyImageToClipboard, - QuillNativeBridgeFeature.getClipboardImage, - QuillNativeBridgeFeature.getClipboardFiles, - }.contains(feature); + Future isSupported(QuillNativeBridgeFeature feature) async { + if (feature == QuillNativeBridgeFeature.saveImageToGallery) { + return await _hostApi.supportsGallerySave(); + } + return { + QuillNativeBridgeFeature.getClipboardHtml, + QuillNativeBridgeFeature.copyHtmlToClipboard, + QuillNativeBridgeFeature.copyImageToClipboard, + QuillNativeBridgeFeature.getClipboardImage, + QuillNativeBridgeFeature.getClipboardFiles, + QuillNativeBridgeFeature.openGalleryApp, + QuillNativeBridgeFeature.saveImage, + }.contains(feature); + } @override Future isIOSSimulator() => throw UnsupportedError( @@ -48,4 +55,71 @@ class QuillNativeBridgeMacOS extends QuillNativeBridgePlatform { @override Future> getClipboardFiles() => _hostApi.getClipboardFiles(); + + @override + Future openGalleryApp() => _hostApi.openGalleryApp(); + + @override + Future saveImageToGallery( + Uint8List imageBytes, { + required GalleryImageSaveOptions options, + }) async { + try { + await _hostApi.saveImageToGallery(imageBytes, + name: options.name, albumName: options.albumName); + } on PlatformException catch (e) { + if (e.code == 'UNSUPPORTED') { + throw UnsupportedError( + 'Saving an image to the gallery is not supported on this macOS version. Check before calling this method. Platform Details: ${e.toString()}'); + } + assert(() { + if (e.code == 'PERMISSION_DENIED') { + throw StateError( + 'Insufficient permission to save the image to the gallery.\n\n' + ''' +=============================================================== + Possible Issue Details +=============================================================== +''' + '\nApple macOS imposes security restrictions. If the app is running using sources other than Xcode or macOS terminal such as Android Studio or VS Code\n' + 'then this issue might be encountered.\n' + 'If the issue was encountered even with Xcode and you did not explicitly deny the requested permission,\n' + 'consider filing an issue to https://github.com/FlutterQuill/quill-native-bridge\n\n' + ''' +=============================================================== + Important Information +=============================================================== +''' + '\nThis exception will be only thrown in development mode.\n' + 'If you have explicitly denied the requested permission or run on Xcode / macOS terminal without this issue,\n' + 'then you can ignore this error since it is not applicable in the production app.\n\n' + 'For more details, refer to: https://pub.dev/packages/quill_native_bridge#-saving-images-to-the-gallery\n' + 'Platform error details: ${e.toString()}', + ); + } else if (e.code == 'MACOS_INFO_PLIST_NOT_CONFIGURED') { + throw StateError( + '\nThe Info.plist file was not configured to support saving images to the gallery on macOS.\n' + 'For more details, refer to https://pub.dev/packages/quill_native_bridge#-saving-images-to-the-gallery\n' + 'This exception will be only thrown in debug mode.\n\n' + 'Platform error details: ${e.toString()}', + ); + } + + return true; + }()); + rethrow; + } + } + + @override + Future saveImage( + Uint8List imageBytes, { + required ImageSaveOptions options, + }) async => + ImageSaveResult.io( + filePath: await _hostApi.saveImage( + imageBytes, + name: options.name, + fileExtension: options.fileExtension, + )); } diff --git a/quill_native_bridge_macos/lib/src/messages.g.dart b/quill_native_bridge_macos/lib/src/messages.g.dart index 86d3ca3..2e57dd4 100644 --- a/quill_native_bridge_macos/lib/src/messages.g.dart +++ b/quill_native_bridge_macos/lib/src/messages.g.dart @@ -15,6 +15,17 @@ PlatformException _createConnectionError(String channelName) { ); } +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override @@ -199,4 +210,114 @@ class QuillNativeBridgeApi { return (pigeonVar_replyList[0] as List?)!.cast(); } } + + Future openGalleryApp() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.openGalleryApp$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Supports macOS 10.15 and later. + Future supportsGallerySave() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.supportsGallerySave$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send(null) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as bool?)!; + } + } + + Future saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String? albumName, + }) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImageToGallery$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([imageBytes, name, albumName]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future saveImage( + Uint8List imageBytes, { + required String name, + required String fileExtension, + }) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImage$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([imageBytes, name, fileExtension]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return (pigeonVar_replyList[0] as String?); + } + } } diff --git a/quill_native_bridge_macos/macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/Messages.g.swift b/quill_native_bridge_macos/macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/Messages.g.swift index 902c50e..001061a 100644 --- a/quill_native_bridge_macos/macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/Messages.g.swift +++ b/quill_native_bridge_macos/macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/Messages.g.swift @@ -84,6 +84,7 @@ class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { static let shared = MessagesPigeonCodec(readerWriter: MessagesPigeonCodecReaderWriter()) } + /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol QuillNativeBridgeApi { func getClipboardHtml() throws -> String? @@ -92,6 +93,11 @@ protocol QuillNativeBridgeApi { func copyImageToClipboard(imageBytes: FlutterStandardTypedData) throws func getClipboardGif() throws -> FlutterStandardTypedData? func getClipboardFiles() throws -> [String] + func openGalleryApp() throws + /// Supports macOS 10.15 and later. + func supportsGallerySave() throws -> Bool + func saveImageToGallery(imageBytes: FlutterStandardTypedData, name: String, albumName: String?, completion: @escaping (Result) -> Void) + func saveImage(imageBytes: FlutterStandardTypedData, name: String, fileExtension: String, completion: @escaping (Result) -> Void) } /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. @@ -182,5 +188,70 @@ class QuillNativeBridgeApiSetup { } else { getClipboardFilesChannel.setMessageHandler(nil) } + let openGalleryAppChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.openGalleryApp\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + openGalleryAppChannel.setMessageHandler { _, reply in + do { + try api.openGalleryApp() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + openGalleryAppChannel.setMessageHandler(nil) + } + /// Supports macOS 10.15 and later. + let supportsGallerySaveChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.supportsGallerySave\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + supportsGallerySaveChannel.setMessageHandler { _, reply in + do { + let result = try api.supportsGallerySave() + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + supportsGallerySaveChannel.setMessageHandler(nil) + } + let saveImageToGalleryChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImageToGallery\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + saveImageToGalleryChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let imageBytesArg = args[0] as! FlutterStandardTypedData + let nameArg = args[1] as! String + let albumNameArg: String? = nilOrValue(args[2]) + api.saveImageToGallery(imageBytes: imageBytesArg, name: nameArg, albumName: albumNameArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + saveImageToGalleryChannel.setMessageHandler(nil) + } + let saveImageChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImage\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + saveImageChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let imageBytesArg = args[0] as! FlutterStandardTypedData + let nameArg = args[1] as! String + let fileExtensionArg = args[2] as! String + api.saveImage(imageBytes: imageBytesArg, name: nameArg, fileExtension: fileExtensionArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + saveImageChannel.setMessageHandler(nil) + } } } diff --git a/quill_native_bridge_macos/macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/QuillNativeBridgeImpl.swift b/quill_native_bridge_macos/macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/QuillNativeBridgeImpl.swift index 7593168..7cc48de 100644 --- a/quill_native_bridge_macos/macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/QuillNativeBridgeImpl.swift +++ b/quill_native_bridge_macos/macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/QuillNativeBridgeImpl.swift @@ -1,5 +1,6 @@ import Foundation import FlutterMacOS +import Photos class QuillNativeBridgeImpl: QuillNativeBridgeApi { func getClipboardHtml() throws -> String? { @@ -54,4 +55,184 @@ class QuillNativeBridgeImpl: QuillNativeBridgeApi { } return urlList.compactMap { url in url.path } } + + func openGalleryApp() throws { + guard let url = URL(string: "photos://") else { + throw PigeonError(code: "INVALID_URL", message: "The URL scheme is invalid.", details: "Unable to create a URL for 'photos://'.") + } + + let workspace = NSWorkspace.shared + let canOpen = workspace.urlForApplication(toOpen: url) != nil + + guard canOpen else { + throw PigeonError(code: "CANNOT_OPEN_URL", message: "Cannot open the Photos app.", details: "The desktop may not have the Photos app installed or it may not support the URL scheme.") + } + + workspace.open(url) + } + + func supportsGallerySave() throws -> Bool { + guard #available(macOS 10.15, *) else { + return false + } + return true + } + + func saveImageToGallery(imageBytes: FlutterStandardTypedData, name: String, albumName: String?, completion: @escaping (Result) -> Void) { + guard NSImage(data: imageBytes.data) != nil else { + completion(.failure(PigeonError(code: "INVALID_IMAGE", message: "Unable to create NSImage from image bytes.", details: nil))) + return + } + + let macOSVersion = ProcessInfo.processInfo.operatingSystemVersion + + guard #available(macOS 10.15, *) else { + completion(.failure(PigeonError( + code: "UNSUPPORTED", + message: "Saving images to the system gallery is supported on macOS 10.15 and later.", + details: "The current macOS version is: \(macOSVersion.majorVersion).\(macOSVersion.minorVersion).\(macOSVersion.patchVersion)" + ))) + return + } + + let needsReadWritePermission = macOSVersion.majorVersion < 11 || albumName != nil + + let permissionKey = needsReadWritePermission ? "NSPhotoLibraryUsageDescription" : "NSPhotoLibraryAddUsageDescription" + guard let infoPlist = Bundle.main.infoDictionary, + let permissionDescription = infoPlist[permissionKey] as? String else { + completion(.failure(PigeonError( + code: "MACOS_INFO_PLIST_NOT_CONFIGURED", + message: "The macOS `Info.plist` file has not been configured. The key `\(permissionKey)` is not set.", + details: nil + ))) + return + } + + func handlePermissionDenied(status: PHAuthorizationStatus) { + completion(.failure(PigeonError( + code: "PERMISSION_DENIED", + message: "The app doesn't have permission to save photos to the gallery.", + details: String(describing: status) + ))) + } + + func isAccessBlocked(status: PHAuthorizationStatus) -> Bool { + return status == .denied || status == .restricted + } + + Task { + if #available(macOS 11, *) { + let accessLevel: PHAccessLevel = needsReadWritePermission ? .readWrite : .addOnly + + let currentStatus = await PHPhotoLibrary.authorizationStatus(for: accessLevel) + + guard !isAccessBlocked(status: currentStatus) else { + handlePermissionDenied(status: currentStatus) + return + } + + if currentStatus == .notDetermined { + let status = await PHPhotoLibrary.requestAuthorization(for: accessLevel) + + guard !isAccessBlocked(status: status) else { + handlePermissionDenied(status: status) + return + } + } + } else { + // For macOS 10.15 and previous versions + let currentStatus = await PHPhotoLibrary.authorizationStatus() + + guard !isAccessBlocked(status: currentStatus) else { + handlePermissionDenied(status: currentStatus) + return + } + + if currentStatus == .notDetermined { + PHPhotoLibrary.requestAuthorization { status in + guard !isAccessBlocked(status: status) else { + handlePermissionDenied(status: status) + return + } + } + } + } + + do { + try await PHPhotoLibrary.shared().performChanges({ + let assetRequest = PHAssetCreationRequest.forAsset() + + let options = PHAssetResourceCreationOptions() + options.originalFilename = name + assetRequest.addResource(with: .photo, data: imageBytes.data, options: options) + + if let albumName = albumName { + + let albumFetchOptions = PHFetchOptions() + albumFetchOptions.predicate = NSPredicate(format: "title = %@", albumName) + let existingAlbum = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: albumFetchOptions).firstObject + + if existingAlbum == nil { + // Create the album + let albumChangeRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName) + albumChangeRequest.addAssets([assetRequest.placeholderForCreatedAsset] as NSArray) + + } else if let album = existingAlbum { + // Add the image to the existing album + let albumChangeRequest = PHAssetCollectionChangeRequest(for: album) + albumChangeRequest?.addAssets([assetRequest.placeholderForCreatedAsset] as NSArray) + } + } + }) + completion(.success(())) + } catch { + completion(.failure(PigeonError( + code: "SAVE_FAILED", + message: "Failed to save the image to the gallery: \(error.localizedDescription)", + details: String(describing: error) + ))) + } + } + } + + func saveImage(imageBytes: FlutterStandardTypedData, name: String, fileExtension: String, completion: @escaping (Result) -> Void) { + guard let picturesDirectory = FileManager.default.urls(for: .picturesDirectory, in: .userDomainMask).first else { + completion(.failure(PigeonError( + code: "DIRECTORY_NOT_FOUND", + message: "Unable to locate the Pictures directory.", + details: "Could not retrieve the user's Pictures directory." + ))) + return + } + + // TODO(save-image) The entitlement com.apple.security.files.user-selected.read-write is required, check if set to avoid crash + let savePanel = NSSavePanel() + savePanel.nameFieldStringValue = "\(name).\(fileExtension)" + savePanel.directoryURL = picturesDirectory + + if #available(macOS 11.0, *) { + savePanel.allowedContentTypes = [.image] + } else { + savePanel.allowedFileTypes = [fileExtension] + } + + savePanel.begin { result in + guard result == .OK, let selectedUrl = savePanel.url else { + completion(.success(nil)) + return + } + + do { + try imageBytes.data.write(to: selectedUrl) + completion(.success(selectedUrl.path)) + } catch { + completion(.failure(PigeonError( + code: "IMAGE_WRITE_FAILED", + message: "Failed to save the image to the specified location.", + details: "An error occurred while writing the image to \(selectedUrl.path). Error: \(error.localizedDescription)" + ))) + } + } + + } } diff --git a/quill_native_bridge_macos/pigeons/messages.dart b/quill_native_bridge_macos/pigeons/messages.dart index 70822f0..09527a6 100644 --- a/quill_native_bridge_macos/pigeons/messages.dart +++ b/quill_native_bridge_macos/pigeons/messages.dart @@ -2,11 +2,12 @@ import 'package:pigeon/pigeon.dart'; @ConfigurePigeon(PigeonOptions( dartOut: 'lib/src/messages.g.dart', + dartTestOut: 'test/test_api.g.dart', swiftOut: 'macos/quill_native_bridge_macos/Sources/quill_native_bridge_macos/Messages.g.swift', dartPackageName: 'quill_native_bridge_macos', )) -@HostApi() +@HostApi(dartHostTestHandler: 'TestQuillNativeBridgeApi') abstract class QuillNativeBridgeApi { // HTML String? getClipboardHtml(); @@ -19,4 +20,23 @@ abstract class QuillNativeBridgeApi { // File List getClipboardFiles(); + + void openGalleryApp(); + + /// Supports macOS 10.15 and later. + bool supportsGallerySave(); + + @async + void saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String? albumName, + }); + + @async + String? saveImage( + Uint8List imageBytes, { + required String name, + required String fileExtension, + }); } diff --git a/quill_native_bridge_macos/pubspec.yaml b/quill_native_bridge_macos/pubspec.yaml index f8521af..83e365e 100644 --- a/quill_native_bridge_macos/pubspec.yaml +++ b/quill_native_bridge_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge_macos description: "macOS implementation of the quill_native_bridge plugin." -version: 0.0.1-dev.5 +version: 0.0.1 homepage: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_macos repository: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_macos issue_tracker: https://github.com/FlutterQuill/quill-native-bridge/issues?q=is%3Aissue+is%3Aopen+label%3A%22platform-macos%22 @@ -14,13 +14,15 @@ environment: dependencies: flutter: sdk: flutter - quill_native_bridge_platform_interface: ^0.0.1-dev.4 + quill_native_bridge_platform_interface: ^0.0.1 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 pigeon: ^22.6.2 + mockito: ^5.4.4 + build_runner: ^2.4.13 flutter: plugin: diff --git a/quill_native_bridge_macos/test/quill_native_bridge_macos_test.dart b/quill_native_bridge_macos/test/quill_native_bridge_macos_test.dart new file mode 100644 index 0000000..abd49e3 --- /dev/null +++ b/quill_native_bridge_macos/test/quill_native_bridge_macos_test.dart @@ -0,0 +1,386 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:quill_native_bridge_macos/quill_native_bridge_macos.dart'; +import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; + +import 'test_api.g.dart'; + +@GenerateMocks([TestQuillNativeBridgeApi]) +import 'quill_native_bridge_macos_test.mocks.dart'; + +void main() { + // Required when calling TestQuillNativeBridgeApi.setUp() + TestWidgetsFlutterBinding.ensureInitialized(); + + late QuillNativeBridgeMacOS plugin; + late MockTestQuillNativeBridgeApi mockHostApi; + + setUp(() { + plugin = QuillNativeBridgeMacOS(); + mockHostApi = MockTestQuillNativeBridgeApi(); + TestQuillNativeBridgeApi.setUp(mockHostApi); + + when(mockHostApi.openGalleryApp()).thenAnswer((_) async {}); + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenAnswer((_) async {}); + when(mockHostApi.saveImage( + any, + name: anyNamed('name'), + fileExtension: anyNamed('fileExtension'), + )).thenAnswer((_) async => null); + }); + + test('registered instance', () { + QuillNativeBridgeMacOS.registerWith(); + expect(QuillNativeBridgePlatform.instance, isA()); + }); + + test('isIOSSimulator is not applicable on macOS', () async { + expect(() async => await plugin.isIOSSimulator(), throwsUnsupportedError); + }); + + group( + 'clipboard', + () { + test( + 'getClipboardHtml delegates to _hostApi.getClipboardHtml', + () async { + when(mockHostApi.getClipboardHtml()).thenReturn(null); + final nullHtml = await plugin.getClipboardHtml(); + verify(mockHostApi.getClipboardHtml()).called(1); + expect(nullHtml, isNull); + + final exampleHtml = 'An HTML'; + + when(mockHostApi.getClipboardHtml()).thenReturn(exampleHtml); + final nonNullHtml = await plugin.getClipboardHtml(); + verify(mockHostApi.getClipboardHtml()).called(1); + expect(nonNullHtml, equals(exampleHtml)); + }, + ); + + test( + 'copyHtmlToClipboard delegates to _hostApi.copyHtmlToClipboard', + () async { + final input = 'Example HTML'; + when(mockHostApi.copyHtmlToClipboard(input)).thenReturn(null); + await plugin.copyHtmlToClipboard(input); + verify(mockHostApi.copyHtmlToClipboard(input)).called(1); + }, + ); + + test( + 'getClipboardImage delegates to _hostApi.getClipboardImage', + () async { + when(mockHostApi.getClipboardImage()).thenReturn(null); + final nullImage = await plugin.getClipboardImage(); + verify(mockHostApi.getClipboardImage()).called(1); + expect(nullImage, isNull); + + final exampleImage = Uint8List.fromList([1, 0, 1]); + + when(mockHostApi.getClipboardImage()).thenReturn(exampleImage); + final nonNullImage = await plugin.getClipboardImage(); + verify(mockHostApi.getClipboardImage()).called(1); + expect(nonNullImage, equals(exampleImage)); + }, + ); + + test( + 'copyImageToClipboard delegates to _hostApi.copyImageToClipboard', + () async { + final input = Uint8List.fromList([1, 0, 1]); + when(mockHostApi.copyImageToClipboard(input)).thenReturn(null); + await plugin.copyImageToClipboard(input); + verify(mockHostApi.copyImageToClipboard(input)).called(1); + }, + ); + + test( + 'getClipboardGif delegates to _hostApi.getClipboardGif', + () async { + when(mockHostApi.getClipboardGif()).thenReturn(null); + final nullImage = await plugin.getClipboardGif(); + verify(mockHostApi.getClipboardGif()).called(1); + expect(nullImage, isNull); + + final exampleImage = Uint8List.fromList([1, 0, 1]); + + when(mockHostApi.getClipboardGif()).thenReturn(exampleImage); + final nonNullImage = await plugin.getClipboardGif(); + verify(mockHostApi.getClipboardGif()).called(1); + expect(nonNullImage, equals(exampleImage)); + }, + ); + + test( + 'getClipboardFiles delegates to _hostApi.getClipboardFiles', + () async { + when(mockHostApi.getClipboardFiles()).thenReturn([]); + final emptyFiles = await plugin.getClipboardFiles(); + verify(mockHostApi.getClipboardFiles()).called(1); + expect(emptyFiles, []); + + final exampleFiles = ['/foo/bar', '/path/to/file']; + + when(mockHostApi.getClipboardFiles()).thenReturn(exampleFiles); + final nonEmptyFiles = await plugin.getClipboardFiles(); + verify(mockHostApi.getClipboardFiles()).called(1); + expect(nonEmptyFiles, equals(exampleFiles)); + }, + ); + }, + ); + + group('gallery', () { + test( + 'isSupported delegates to _hostApi.supportsGallerySave for ${QuillNativeBridgeFeature.saveImageToGallery}', + () async { + when(mockHostApi.supportsGallerySave()).thenReturn(true); + expect( + await plugin + .isSupported(QuillNativeBridgeFeature.saveImageToGallery), + true); + verify(mockHostApi.supportsGallerySave()).called(1); + + when(mockHostApi.supportsGallerySave()).thenReturn(false); + expect( + await plugin + .isSupported(QuillNativeBridgeFeature.saveImageToGallery), + false); + verify(mockHostApi.supportsGallerySave()).called(1); + }, + ); + + test( + 'openGalleryApp delegates to _hostApi.openGalleryApp', + () async { + await plugin.openGalleryApp(); + verify(mockHostApi.openGalleryApp()).called(1); + }, + ); + + group('saveImageToGallery', () { + test( + 'delegates to _hostApi.saveImageToGallery', + () async { + await plugin.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + )); + verify(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).called(1); + }, + ); + + test( + 'passes the arguments correctly to the platform host API', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + final imageName = 'ExampleImage'; + final imageAlbumName = 'ExampleAlbum'; + + when(mockHostApi.saveImageToGallery( + imageBytes, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenAnswer((_) async => null); + + await plugin.saveImageToGallery(imageBytes, + options: GalleryImageSaveOptions( + name: imageName, + fileExtension: 'png', + albumName: imageAlbumName, + )); + + final capturedOptions = verify(mockHostApi.saveImageToGallery( + captureAny, + name: captureAnyNamed('name'), + albumName: captureAnyNamed('albumName'), + )).captured; + + expect(capturedOptions[0] as Uint8List, imageBytes); + expect(capturedOptions[1] as String, imageName); + expect(capturedOptions[2] as String, imageAlbumName); + }, + ); + + test( + 'passes the arguments correctly to the platform host API', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + final options = + ImageSaveOptions(name: 'ExampleImage', fileExtension: 'png'); + + when(mockHostApi.saveImage( + imageBytes, + name: anyNamed('name'), + fileExtension: anyNamed('fileExtension'), + )).thenAnswer((_) async => null); + + await plugin.saveImage(imageBytes, options: options); + + final capturedOptions = verify(mockHostApi.saveImage( + captureAny, + name: captureAnyNamed('name'), + fileExtension: captureAnyNamed('fileExtension'), + )).captured; + + expect(capturedOptions[0] as Uint8List, imageBytes); + expect(capturedOptions[1] as String, options.name); + expect(capturedOptions[2] as String, options.fileExtension); + }, + ); + + test( + 'throws $UnsupportedError when _hostApi.saveImageToGallery responds as unsupported', + () async { + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenThrow(PlatformException(code: 'UNSUPPORTED')); + expect( + plugin.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + )), + throwsUnsupportedError, + ); + }, + ); + + test( + 'throws $StateError in debug mode for common issues', + () { + void expectThrowsForCode(String errorCode, + {required String containsMessage}) { + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenThrow(PlatformException(code: errorCode)); + expect( + plugin.saveImageToGallery(Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + )), + throwsA(isA().having( + (e) => e.message, + 'message', + contains(containsMessage), + )), + ); + } + + expectThrowsForCode( + 'PERMISSION_DENIED', + containsMessage: + 'Apple macOS imposes security restrictions. If the app is running using sources other than Xcode or macOS terminal such as Android Studio or VS Code', + ); + expectThrowsForCode( + 'MACOS_INFO_PLIST_NOT_CONFIGURED', + containsMessage: + 'The Info.plist file was not configured to support saving images to the gallery on macOS.', + ); + }, + ); + + test( + 'rethrows the $PlatformException from _hostApi.saveImageToGallery if not handled', + () async { + // Currently, that's the expected behavior but it is subject to changes for improvements. + // See https://github.com/FlutterQuill/quill-native-bridge/issues/2 + + const errorCode = '404'; + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenThrow(PlatformException(code: errorCode)); + expect( + plugin.saveImageToGallery( + Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', fileExtension: 'png', albumName: null), + ), + throwsA(isA() + .having((e) => e.code, 'code', errorCode)), + ); + + when(mockHostApi.saveImageToGallery( + any, + name: anyNamed('name'), + albumName: anyNamed('albumName'), + )).thenAnswer((_) async {}); + await expectLater( + plugin.saveImageToGallery( + Uint8List.fromList([1, 0, 1]), + options: GalleryImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + albumName: null, + ), + ), + completes, + ); + }); + }); + + test( + 'saveImage delegates to _hostApi.saveImage', + () async { + await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + )); + verify(mockHostApi.saveImage( + any, + name: anyNamed('name'), + fileExtension: anyNamed('fileExtension'), + )).called(1); + }, + ); + + test( + 'saveImage always passes null to blob URL on non-web platforms', + () async { + final result = await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + )); + expect(result.blobUrl, isNull); + + final examplePath = 'path/to/file'; + when(mockHostApi.saveImage( + any, + name: anyNamed('name'), + fileExtension: anyNamed('fileExtension'), + )).thenAnswer((_) async => examplePath); + final result2 = await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + )); + expect(result2.blobUrl, isNull); + expect(result2.filePath, examplePath); + }, + ); + }); +} diff --git a/quill_native_bridge_macos/test/quill_native_bridge_macos_test.mocks.dart b/quill_native_bridge_macos/test/quill_native_bridge_macos_test.mocks.dart new file mode 100644 index 0000000..57d3967 --- /dev/null +++ b/quill_native_bridge_macos/test/quill_native_bridge_macos_test.mocks.dart @@ -0,0 +1,116 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in quill_native_bridge_macos/test/quill_native_bridge_macos_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:typed_data' as _i3; + +import 'package:mockito/mockito.dart' as _i1; + +import 'test_api.g.dart' as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [TestQuillNativeBridgeApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockTestQuillNativeBridgeApi extends _i1.Mock + implements _i2.TestQuillNativeBridgeApi { + MockTestQuillNativeBridgeApi() { + _i1.throwOnMissingStub(this); + } + + @override + void copyHtmlToClipboard(String? html) => super.noSuchMethod( + Invocation.method( + #copyHtmlToClipboard, + [html], + ), + returnValueForMissingStub: null, + ); + + @override + void copyImageToClipboard(_i3.Uint8List? imageBytes) => super.noSuchMethod( + Invocation.method( + #copyImageToClipboard, + [imageBytes], + ), + returnValueForMissingStub: null, + ); + + @override + List getClipboardFiles() => (super.noSuchMethod( + Invocation.method( + #getClipboardFiles, + [], + ), + returnValue: [], + ) as List); + + @override + void openGalleryApp() => super.noSuchMethod( + Invocation.method( + #openGalleryApp, + [], + ), + returnValueForMissingStub: null, + ); + + @override + bool supportsGallerySave() => (super.noSuchMethod( + Invocation.method( + #supportsGallerySave, + [], + ), + returnValue: false, + ) as bool); + + @override + _i4.Future saveImageToGallery( + _i3.Uint8List? imageBytes, { + required String? name, + required String? albumName, + }) => + (super.noSuchMethod( + Invocation.method( + #saveImageToGallery, + [imageBytes], + { + #name: name, + #albumName: albumName, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future saveImage( + _i3.Uint8List? imageBytes, { + required String? name, + required String? fileExtension, + }) => + (super.noSuchMethod( + Invocation.method( + #saveImage, + [imageBytes], + { + #name: name, + #fileExtension: fileExtension, + }, + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); +} diff --git a/quill_native_bridge_macos/test/test_api.g.dart b/quill_native_bridge_macos/test/test_api.g.dart new file mode 100644 index 0000000..496a603 --- /dev/null +++ b/quill_native_bridge_macos/test/test_api.g.dart @@ -0,0 +1,372 @@ +// Autogenerated from Pigeon (v22.6.2), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: avoid_relative_lib_imports +import 'dart:async'; +import 'dart:typed_data' show Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:quill_native_bridge_macos/src/messages.g.dart'; + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class TestQuillNativeBridgeApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + String? getClipboardHtml(); + + void copyHtmlToClipboard(String html); + + Uint8List? getClipboardImage(); + + void copyImageToClipboard(Uint8List imageBytes); + + Uint8List? getClipboardGif(); + + List getClipboardFiles(); + + void openGalleryApp(); + + /// Supports macOS 10.15 and later. + bool supportsGallerySave(); + + Future saveImageToGallery( + Uint8List imageBytes, { + required String name, + required String? albumName, + }); + + Future saveImage( + Uint8List imageBytes, { + required String name, + required String fileExtension, + }); + + static void setUp( + TestQuillNativeBridgeApi? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.getClipboardHtml$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final String? output = api.getClipboardHtml(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.copyHtmlToClipboard$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.copyHtmlToClipboard was null.'); + final List args = (message as List?)!; + final String? arg_html = (args[0] as String?); + assert(arg_html != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.copyHtmlToClipboard was null, expected non-null String.'); + try { + api.copyHtmlToClipboard(arg_html!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.getClipboardImage$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final Uint8List? output = api.getClipboardImage(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.copyImageToClipboard$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.copyImageToClipboard was null.'); + final List args = (message as List?)!; + final Uint8List? arg_imageBytes = (args[0] as Uint8List?); + assert(arg_imageBytes != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.copyImageToClipboard was null, expected non-null Uint8List.'); + try { + api.copyImageToClipboard(arg_imageBytes!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.getClipboardGif$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final Uint8List? output = api.getClipboardGif(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.getClipboardFiles$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final List output = api.getClipboardFiles(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.openGalleryApp$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + api.openGalleryApp(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.supportsGallerySave$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + try { + final bool output = api.supportsGallerySave(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImageToGallery$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImageToGallery was null.'); + final List args = (message as List?)!; + final Uint8List? arg_imageBytes = (args[0] as Uint8List?); + assert(arg_imageBytes != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImageToGallery was null, expected non-null Uint8List.'); + final String? arg_name = (args[1] as String?); + assert(arg_name != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImageToGallery was null, expected non-null String.'); + final String? arg_albumName = (args[2] as String?); + try { + await api.saveImageToGallery(arg_imageBytes!, + name: arg_name!, albumName: arg_albumName); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImage$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(pigeonVar_channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImage was null.'); + final List args = (message as List?)!; + final Uint8List? arg_imageBytes = (args[0] as Uint8List?); + assert(arg_imageBytes != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImage was null, expected non-null Uint8List.'); + final String? arg_name = (args[1] as String?); + assert(arg_name != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImage was null, expected non-null String.'); + final String? arg_fileExtension = (args[2] as String?); + assert(arg_fileExtension != null, + 'Argument for dev.flutter.pigeon.quill_native_bridge_macos.QuillNativeBridgeApi.saveImage was null, expected non-null String.'); + try { + final String? output = await api.saveImage(arg_imageBytes!, + name: arg_name!, fileExtension: arg_fileExtension!); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } +} diff --git a/quill_native_bridge_platform_interface/CHANGELOG.md b/quill_native_bridge_platform_interface/CHANGELOG.md index ea46498..c5df1d5 100644 --- a/quill_native_bridge_platform_interface/CHANGELOG.md +++ b/quill_native_bridge_platform_interface/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## 0.0.1 + +- Improves doc comments. +- Adds `saveImage` and `saveImageToGallery`. + ## 0.0.1-dev.5 - Removes the default method channel implementation (`MethodChannelQuillNativeBridge`) since it's no longer needed; platform packages have different implementations. diff --git a/quill_native_bridge_platform_interface/lib/quill_native_bridge_platform_interface.dart b/quill_native_bridge_platform_interface/lib/quill_native_bridge_platform_interface.dart index b7b16d2..2b3ab47 100644 --- a/quill_native_bridge_platform_interface/lib/quill_native_bridge_platform_interface.dart +++ b/quill_native_bridge_platform_interface/lib/quill_native_bridge_platform_interface.dart @@ -3,8 +3,12 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'src/placeholder_implementation.dart'; import 'src/platform_feature.dart'; +import 'src/types/image_save_options.dart'; +import 'src/types/image_save_result.dart'; export 'src/platform_feature.dart'; +export 'src/types/image_save_options.dart'; +export 'src/types/image_save_result.dart'; /// Platform implementations should extend this class rather than implement it /// as newly added methods are not considered to be breaking @@ -20,7 +24,7 @@ abstract class QuillNativeBridgePlatform extends PlatformInterface { /// Constructs a [QuillNativeBridgePlatform]. QuillNativeBridgePlatform() : super(token: _token); - /// Avoid using `const` when creating the `Object` for `_token` + // Avoid using `const` when creating the [Object] for [_token]. static final Object _token = Object(); static QuillNativeBridgePlatform _instance = PlaceholderImplementation(); @@ -40,48 +44,82 @@ abstract class QuillNativeBridgePlatform extends PlatformInterface { /// Checks if the specified [feature] is supported in the current implementation. /// - /// Will verify if this is supported in the platform itself: + /// Will verify if the platform supports this feature, the platform + /// implementation of the plugin, and the current running OS version. /// - /// - If [feature] is supported on **Android API 21** (as an example) and the - /// current Android API is `19` then will return `false` - /// - If [feature] is supported on the web if Clipboard API (as another example) + /// For example if [feature] is: + /// + /// - Supported on **Android API 21** (as an example) and the + /// current Android API is `19` then will return `false`. + /// + /// - Supported on the web if Clipboard API (as another example) /// available in the current browser, and the current browser doesn't support it, /// will return `false` too. For this specific example, you will need /// to fallback to **Clipboard events** on **Firefox** or browsers that doesn't /// support **Clipboard API**. /// - /// Always check the docs of the method you're calling to see if there - /// are special notes. + /// - Supported by the platform itself but the plugin currently implements it, + /// then return `false`. + /// + /// Always review the doc comment of a method before use for special notes. + /// + /// See also: [QuillNativeBridgeFeature] Future isSupported(QuillNativeBridgeFeature feature) => throw UnimplementedError('isSupported() has not been implemented.'); - /// Check if the app is running on [iOS Simulator](https://developer.apple.com/documentation/xcode/running-your-app-in-simulator-or-on-a-device). + /// Checks if the app is running on [iOS Simulator](https://developer.apple.com/documentation/xcode/running-your-app-in-simulator-or-on-a-device). Future isIOSSimulator() => throw UnimplementedError('isIOSSimulator() has not been implemented.'); - /// Return HTML from the system clipboard. + /// Returns HTML from the system clipboard. Future getClipboardHtml() => throw UnimplementedError('getClipboardHtml() has not been implemented.'); - /// Copy the [html] to the system clipboard to be pasted on other apps. + /// Copies an HTML to the system clipboard to be pasted on other apps. Future copyHtmlToClipboard(String html) => throw UnimplementedError( 'copyHtmlToClipboard() has not been implemented.'); - /// Copy the [imageBytes] to system clipboard to be pasted on other apps. + /// Copies an image to the system clipboard to be pasted on other apps. Future copyImageToClipboard(Uint8List imageBytes) => throw UnimplementedError( 'copyImageToClipboard() has not been implemented.', ); - /// Return the copied image from the system clipboard. + /// Returns the copied image from the system clipboard. Future getClipboardImage() => throw UnimplementedError('getClipboardImage() has not been implemented.'); - /// Return the copied gif from the system clipboard. + /// Returns the copied GIF from the system clipboard. Future getClipboardGif() => throw UnimplementedError('getClipboardGif() has not been implemented.'); - /// Return the file paths from the system clipboard. + /// Returns the file paths from the system clipboard. Future> getClipboardFiles() => throw UnimplementedError('getClipboardFiles() has not been implemented.'); + + /// Opens the system gallery app. + Future openGalleryApp() => throw UnimplementedError( + 'openGalleryApp() has not been implemented.', + ); + + /// Saves an image to the gallery app. + Future saveImageToGallery( + Uint8List imageBytes, { + required GalleryImageSaveOptions options, + }) => + throw UnimplementedError( + 'saveImageToGallery() has not been implemented.', + ); + + /// Saves an image to the device. + /// + /// Returns [ImageSaveResult] with `null` to [ImageSaveResult.filePath] + /// if the operation was canceled and always `null` on web platforms. + Future saveImage( + Uint8List imageBytes, { + required ImageSaveOptions options, + }) => + throw UnimplementedError( + 'saveImage() has not been implemented.', + ); } diff --git a/quill_native_bridge_platform_interface/lib/src/image_mime_utils.dart b/quill_native_bridge_platform_interface/lib/src/image_mime_utils.dart new file mode 100644 index 0000000..529970c --- /dev/null +++ b/quill_native_bridge_platform_interface/lib/src/image_mime_utils.dart @@ -0,0 +1,14 @@ +String getImageMimeType(String imageFileExtension) { + return switch (imageFileExtension.toLowerCase()) { + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'png' => 'image/png', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'webp' => 'image/webp', + 'svg' => 'image/svg+xml', + String() => throw ArgumentError( + 'Unsupported image file extension: $imageFileExtension.', + ), + }; +} diff --git a/quill_native_bridge_platform_interface/lib/src/platform_feature.dart b/quill_native_bridge_platform_interface/lib/src/platform_feature.dart index 6360db2..d197089 100644 --- a/quill_native_bridge_platform_interface/lib/src/platform_feature.dart +++ b/quill_native_bridge_platform_interface/lib/src/platform_feature.dart @@ -6,5 +6,8 @@ enum QuillNativeBridgeFeature { copyImageToClipboard, getClipboardImage, getClipboardGif, - getClipboardFiles; + getClipboardFiles, + openGalleryApp, + saveImageToGallery, + saveImage; } diff --git a/quill_native_bridge_platform_interface/lib/src/types/image_save_options.dart b/quill_native_bridge_platform_interface/lib/src/types/image_save_options.dart new file mode 100644 index 0000000..97e5ccb --- /dev/null +++ b/quill_native_bridge_platform_interface/lib/src/types/image_save_options.dart @@ -0,0 +1,55 @@ +import 'package:flutter/foundation.dart' show immutable; + +@immutable +class GalleryImageSaveOptions { + const GalleryImageSaveOptions({ + required this.name, + required this.fileExtension, + required this.albumName, + }); + + final String name; + final String fileExtension; + final String? albumName; + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + if (other is! GalleryImageSaveOptions) return false; + return other.name == name && + other.fileExtension == fileExtension && + other.albumName == albumName; + } + + @override + int get hashCode => Object.hash(name, fileExtension, albumName); + + @override + String toString() => + 'GalleryImageSaveOptions(name: $name, fileExtension: $fileExtension, albumName: $albumName)'; +} + +@immutable +class ImageSaveOptions { + const ImageSaveOptions({ + required this.name, + required this.fileExtension, + }); + + final String name; + final String fileExtension; + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + if (other is! ImageSaveOptions) return false; + return other.name == name && other.fileExtension == fileExtension; + } + + @override + int get hashCode => Object.hash(name, fileExtension); + + @override + String toString() => + 'ImageSaveOptions(name: $name, fileExtension: $fileExtension)'; +} diff --git a/quill_native_bridge_platform_interface/lib/src/types/image_save_result.dart b/quill_native_bridge_platform_interface/lib/src/types/image_save_result.dart new file mode 100644 index 0000000..1e9c69d --- /dev/null +++ b/quill_native_bridge_platform_interface/lib/src/types/image_save_result.dart @@ -0,0 +1,32 @@ +import 'package:flutter/foundation.dart'; + +@immutable +class ImageSaveResult { + const ImageSaveResult({ + required this.filePath, + required this.blobUrl, + }); + + factory ImageSaveResult.io({required String? filePath}) => + ImageSaveResult(filePath: filePath, blobUrl: null); + + factory ImageSaveResult.web({required String blobUrl}) => + ImageSaveResult(filePath: null, blobUrl: blobUrl); + + final String? filePath; + final String? blobUrl; + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + if (other is! ImageSaveResult) return false; + return other.filePath == filePath && other.blobUrl == blobUrl; + } + + @override + int get hashCode => Object.hash(filePath, blobUrl); + + @override + String toString() => + 'ImageSaveResult(filePath: $filePath, blobUrl: $blobUrl)'; +} diff --git a/quill_native_bridge_platform_interface/pubspec.yaml b/quill_native_bridge_platform_interface/pubspec.yaml index 5d7d9ca..18bc289 100644 --- a/quill_native_bridge_platform_interface/pubspec.yaml +++ b/quill_native_bridge_platform_interface/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge_platform_interface description: "A common platform interface for the quill_native_bridge plugin." -version: 0.0.1-dev.5 +version: 0.0.1 homepage: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_platform_interface repository: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_platform_interface issue_tracker: https://github.com/FlutterQuill/quill-native-bridge/issues diff --git a/quill_native_bridge_platform_interface/test/image_mime_utils_test.dart b/quill_native_bridge_platform_interface/test/image_mime_utils_test.dart new file mode 100644 index 0000000..6e1b7b0 --- /dev/null +++ b/quill_native_bridge_platform_interface/test/image_mime_utils_test.dart @@ -0,0 +1,53 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:quill_native_bridge_platform_interface/src/image_mime_utils.dart'; + +void main() { + group('getImageMimeType', () { + test('returns correct MIME type for jpg', () { + expect(getImageMimeType('jpg'), equals('image/jpeg')); + }); + + test('returns correct MIME type for jpeg', () { + expect(getImageMimeType('jpeg'), equals('image/jpeg')); + }); + + test('returns correct MIME type for png', () { + expect(getImageMimeType('png'), equals('image/png')); + }); + + test('returns correct MIME type for gif', () { + expect(getImageMimeType('gif'), equals('image/gif')); + }); + + test('returns correct MIME type for bmp', () { + expect(getImageMimeType('bmp'), equals('image/bmp')); + }); + + test('returns correct MIME type for webp', () { + expect(getImageMimeType('webp'), equals('image/webp')); + }); + + test('returns correct MIME type for svg', () { + expect(getImageMimeType('svg'), equals('image/svg+xml')); + }); + + test('throws ArgumentError for unsupported extension', () { + expect( + () => getImageMimeType('unsupported'), throwsA(isA())); + }); + + test('throws ArgumentError with correct message for unsupported extension', + () { + final unsupportedExtension = 'unsupported'; + + expect( + () => getImageMimeType(unsupportedExtension), + throwsA(isA().having( + (e) => e.message, + 'message', + 'Unsupported image file extension: $unsupportedExtension.', + )), + ); + }); + }); +} diff --git a/quill_native_bridge_platform_interface/test/quill_native_bridge_test.dart b/quill_native_bridge_platform_interface/test/quill_native_bridge_platform_interface.dart similarity index 59% rename from quill_native_bridge_platform_interface/test/quill_native_bridge_test.dart rename to quill_native_bridge_platform_interface/test/quill_native_bridge_platform_interface.dart index 2d4631b..b04b6a7 100644 --- a/quill_native_bridge_platform_interface/test/quill_native_bridge_test.dart +++ b/quill_native_bridge_platform_interface/test/quill_native_bridge_platform_interface.dart @@ -48,6 +48,42 @@ class MockQuillNativeBridgePlatform Future> getClipboardFiles() async { return ['/path/to/file.html', 'path/to/file.md']; } + + GalleryImageSaveOptions? galleryImageSaveOptions; + Uint8List? savedGalleryImageBytes; + + Uint8List? savedImageBytes; + ImageSaveOptions? imageSaveOptions; + + @override + Future saveImageToGallery( + Uint8List imageBytes, { + required GalleryImageSaveOptions options, + }) async { + savedGalleryImageBytes = imageBytes; + galleryImageSaveOptions = options; + } + + @override + Future saveImage( + Uint8List imageBytes, { + required ImageSaveOptions options, + }) async { + savedImageBytes = imageBytes; + imageSaveOptions = options; + return ImageSaveResult( + filePath: '/path/to/file', + blobUrl: + 'blob:http://localhost:64030/e58f63d4-2890-469c-9c8e-69e839da6a93', + ); + } + + var _galleryAppOpened = false; + + @override + Future openGalleryApp() async { + _galleryAppOpened = true; + } } void main() { @@ -117,4 +153,50 @@ void main() { ['/path/to/file.html', 'path/to/file.md'], ); }); + test( + 'saveImage', + () async { + final options = + ImageSaveOptions(name: 'image name', fileExtension: 'png'); + final result = await QuillNativeBridgePlatform.instance.saveImage( + Uint8List.fromList([9, 3, 5]), + options: options, + ); + expect( + result, + ImageSaveResult( + filePath: '/path/to/file', + blobUrl: + 'blob:http://localhost:64030/e58f63d4-2890-469c-9c8e-69e839da6a93', + ), + ); + expect(fakePlatform.savedImageBytes, [9, 3, 5]); + expect(fakePlatform.imageSaveOptions, options); + }, + ); + test( + 'saveImageToGallery', + () async { + final galleryImageSaveOptions = GalleryImageSaveOptions( + name: 'image name', + fileExtension: 'png', + albumName: 'example album', + ); + await QuillNativeBridgePlatform.instance.saveImageToGallery( + Uint8List.fromList([9, 3, 5]), + options: galleryImageSaveOptions, + ); + expect(fakePlatform.savedGalleryImageBytes, [9, 3, 5]); + expect(fakePlatform.galleryImageSaveOptions, galleryImageSaveOptions); + }, + ); + + test( + 'openGalleryApp', + () async { + await QuillNativeBridgePlatform.instance.openGalleryApp(); + + expect(fakePlatform._galleryAppOpened, true); + }, + ); } diff --git a/quill_native_bridge_web/CHANGELOG.md b/quill_native_bridge_web/CHANGELOG.md index 6c75ec0..73f750b 100644 --- a/quill_native_bridge_web/CHANGELOG.md +++ b/quill_native_bridge_web/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 0.0.1 + +- Adds support for saving images. + ## 0.0.1-dev.6 - Adds pub topics to package metadata. diff --git a/quill_native_bridge_web/lib/quill_native_bridge_web.dart b/quill_native_bridge_web/lib/quill_native_bridge_web.dart index 00edc63..780433b 100644 --- a/quill_native_bridge_web/lib/quill_native_bridge_web.dart +++ b/quill_native_bridge_web/lib/quill_native_bridge_web.dart @@ -7,6 +7,7 @@ import 'package:flutter/foundation.dart' show Uint8List, debugPrint; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; import 'package:web/web.dart'; +import 'package:quill_native_bridge_platform_interface/src/image_mime_utils.dart'; import 'src/clipboard_api_support_unsafe.dart'; import 'src/mime_types_constants.dart'; @@ -31,6 +32,11 @@ class QuillNativeBridgeWeb extends QuillNativeBridgePlatform { return false; case QuillNativeBridgeFeature.getClipboardFiles: return false; + case QuillNativeBridgeFeature.openGalleryApp: + case QuillNativeBridgeFeature.saveImageToGallery: + return false; + case QuillNativeBridgeFeature.saveImage: + return true; } // Without this default, adding a new item to the enum will be a breaking change. // ignore: dead_code @@ -130,4 +136,27 @@ class QuillNativeBridgeWeb extends QuillNativeBridgePlatform { 'Retrieving gif image from the clipboard is unsupported regardless of the browser.', ); } + + @override + Future saveImage( + Uint8List imageBytes, { + required ImageSaveOptions options, + }) async { + final blob = Blob( + [imageBytes.toJS].toJS, + BlobPropertyBag(type: getImageMimeType(options.fileExtension)), + ); + final url = URL.createObjectURL(blob); + + final link = document.createElement('a') as HTMLAnchorElement; + link.setAttribute('href', url); + link.setAttribute( + 'download', '${options.fileExtension}.${options.fileExtension}'); + + link.click(); + + URL.revokeObjectURL(url); + + return ImageSaveResult.web(blobUrl: url); + } } diff --git a/quill_native_bridge_web/pubspec.yaml b/quill_native_bridge_web/pubspec.yaml index bc7f46b..aca5195 100644 --- a/quill_native_bridge_web/pubspec.yaml +++ b/quill_native_bridge_web/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge_web description: "Web platform implementation of quill_native_bridge" -version: 0.0.1-dev.6 +version: 0.0.1 homepage: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_web repository: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_web issue_tracker: https://github.com/FlutterQuill/quill-native-bridge/issues?q=is%3Aissue+is%3Aopen+label%3A%22platform-web%22 @@ -17,7 +17,7 @@ dependencies: flutter_web_plugins: sdk: flutter web: ^1.0.0 - quill_native_bridge_platform_interface: ^0.0.1-dev.4 + quill_native_bridge_platform_interface: ^0.0.1 dev_dependencies: flutter_test: diff --git a/quill_native_bridge_windows/CHANGELOG.md b/quill_native_bridge_windows/CHANGELOG.md index 5edb929..85fc982 100644 --- a/quill_native_bridge_windows/CHANGELOG.md +++ b/quill_native_bridge_windows/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## 0.0.1 + +- Adds support for saving images. + ## 0.0.1-dev.4 - Improves dependencies constraints. diff --git a/quill_native_bridge_windows/lib/quill_native_bridge_windows.dart b/quill_native_bridge_windows/lib/quill_native_bridge_windows.dart index 0e4794f..03eb093 100644 --- a/quill_native_bridge_windows/lib/quill_native_bridge_windows.dart +++ b/quill_native_bridge_windows/lib/quill_native_bridge_windows.dart @@ -2,9 +2,13 @@ // Make sure to update pubspec.yaml to the new location. import 'dart:ffi'; +import 'dart:io'; import 'package:ffi/ffi.dart'; +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:flutter/foundation.dart'; import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; +import 'package:quill_native_bridge_windows/src/image_saver.dart'; import 'package:win32/win32.dart'; import 'src/clipboard_html_format.dart'; @@ -23,6 +27,7 @@ class QuillNativeBridgeWindows extends QuillNativeBridgePlatform { Future isSupported(QuillNativeBridgeFeature feature) async => { QuillNativeBridgeFeature.getClipboardHtml, QuillNativeBridgeFeature.copyHtmlToClipboard, + QuillNativeBridgeFeature.saveImage, }.contains(feature); // TODO: Cleanup this code here @@ -181,4 +186,47 @@ class QuillNativeBridgeWindows extends QuillNativeBridgePlatform { calloc.free(htmlPointer); } } + + @visibleForTesting + static ImageSaver imageSaver = ImageSaver(); + + @override + Future saveImage( + Uint8List imageBytes, { + required ImageSaveOptions options, + }) async { + final typeGroup = XTypeGroup( + label: 'Images', + // Only `extensions` is supported on Windows. See https://pub.dev/packages/file_selector#filtering-by-file-types + extensions: [options.fileExtension], + ); + + final saveLocation = await imageSaver.fileSelector.getSaveLocation( + options: SaveDialogOptions( + suggestedName: '${options.name}.${options.fileExtension}', + initialDirectory: imageSaver.picturesDirectoryPath, + ), + acceptedTypeGroups: [typeGroup], + ); + final imageFilePath = saveLocation?.path; + if (imageFilePath == null) { + return ImageSaveResult.io(filePath: null); + } + final imageFile = File(imageFilePath); + await imageFile.writeAsBytes(imageBytes); + + return ImageSaveResult.io(filePath: imageFile.path); + } + + @override + Future openGalleryApp() async { + final uriPtr = TEXT('ms-photos:'); + final openPtr = 'open'.toNativeUtf16(); + + ShellExecute( + NULL, openPtr, uriPtr, nullptr, nullptr, SHOW_WINDOW_CMD.SW_SHOWNORMAL); + + free(uriPtr); + free(openPtr); + } } diff --git a/quill_native_bridge_windows/lib/src/environment_provider.dart b/quill_native_bridge_windows/lib/src/environment_provider.dart new file mode 100644 index 0000000..4fa9c2c --- /dev/null +++ b/quill_native_bridge_windows/lib/src/environment_provider.dart @@ -0,0 +1,21 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; + +abstract class EnvironmentProvider { + Map get environment; + + static EnvironmentProvider _instance = DefaultEnvironmentProvider(); + + static EnvironmentProvider get instance => _instance; + + @visibleForTesting + static void set instance(value) => _instance = value; + + static void setToDefault() => _instance = DefaultEnvironmentProvider(); +} + +class DefaultEnvironmentProvider implements EnvironmentProvider { + @override + Map get environment => Platform.environment; +} diff --git a/quill_native_bridge_windows/lib/src/image_saver.dart b/quill_native_bridge_windows/lib/src/image_saver.dart new file mode 100644 index 0000000..ae4e083 --- /dev/null +++ b/quill_native_bridge_windows/lib/src/image_saver.dart @@ -0,0 +1,23 @@ +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:file_selector_windows/file_selector_windows.dart'; +import 'package:quill_native_bridge_windows/src/environment_provider.dart'; + +class ImageSaver { + /// The file selector that's used to prompt the user to choose a directory + /// for saving an image. + FileSelectorPlatform fileSelector = FileSelectorWindows(); + + static const String windowsUserHomeEnvKey = 'USERPROFILE'; + + static const String picturesDirectoryName = 'Pictures'; + + String? get userHome => + EnvironmentProvider.instance.environment[windowsUserHomeEnvKey]; + + String? get picturesDirectoryPath { + final userHome = this.userHome; + if (userHome == null) return null; + if (userHome.isEmpty) return null; + return '${userHome}\\${picturesDirectoryName}'; + } +} diff --git a/quill_native_bridge_windows/pubspec.yaml b/quill_native_bridge_windows/pubspec.yaml index 601c2cf..d4b3b89 100644 --- a/quill_native_bridge_windows/pubspec.yaml +++ b/quill_native_bridge_windows/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge_windows description: "Windows implementation of the quill_native_bridge plugin." -version: 0.0.1-dev.4 +version: 0.0.1 homepage: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_windows repository: https://github.com/FlutterQuill/quill-native-bridge/tree/main/quill_native_bridge_windows issue_tracker: https://github.com/FlutterQuill/quill-native-bridge/issues?q=is%3Aissue+is%3Aopen+label%3A%22platform-windows%22 @@ -14,14 +14,18 @@ environment: dependencies: flutter: sdk: flutter - quill_native_bridge_platform_interface: ^0.0.1-dev.4 + quill_native_bridge_platform_interface: ^0.0.1 win32: ^5.5.0 ffi: ^2.1.0 + file_selector_windows: ^0.9.1+5 + file_selector_platform_interface: ^2.4.0 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 + mockito: ^5.4.4 + build_runner: ^2.4.13 flutter: plugin: diff --git a/quill_native_bridge_windows/test/environment_provider_test.dart b/quill_native_bridge_windows/test/environment_provider_test.dart new file mode 100644 index 0000000..c965c25 --- /dev/null +++ b/quill_native_bridge_windows/test/environment_provider_test.dart @@ -0,0 +1,40 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:quill_native_bridge_windows/src/environment_provider.dart'; + +void main() { + test('defaults to $DefaultEnvironmentProvider', () { + expect(EnvironmentProvider.instance, isA()); + }); + test('should update the instance correctly', () { + expect( + EnvironmentProvider.instance, isNot(isA<_FakeEnvironmentProvider>())); + + EnvironmentProvider.instance = _FakeEnvironmentProvider(); + expect(EnvironmentProvider.instance, isA<_FakeEnvironmentProvider>()); + }); + + test( + 'environment getter from the instance delegates to the new provider instance', + () { + final fake = _FakeEnvironmentProvider(); + fake.testEnvironment.addAll({ + 'test': 'foo/bar', + }); + EnvironmentProvider.instance = fake; + expect(EnvironmentProvider.instance.environment, fake.environment); + }); + + test('setToDefault restore the default instance', () { + final fake = _FakeEnvironmentProvider(); + EnvironmentProvider.instance = fake; + + EnvironmentProvider.setToDefault(); + expect(EnvironmentProvider.instance, isA()); + }); +} + +class _FakeEnvironmentProvider implements DefaultEnvironmentProvider { + final Map testEnvironment = {}; + @override + Map get environment => testEnvironment; +} diff --git a/quill_native_bridge_windows/test/quill_native_bridge_windows_test.dart b/quill_native_bridge_windows/test/quill_native_bridge_windows_test.dart new file mode 100644 index 0000000..db037d6 --- /dev/null +++ b/quill_native_bridge_windows/test/quill_native_bridge_windows_test.dart @@ -0,0 +1,320 @@ +import 'dart:io'; + +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:file_selector_windows/file_selector_windows.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:quill_native_bridge_platform_interface/quill_native_bridge_platform_interface.dart'; +import 'package:quill_native_bridge_windows/quill_native_bridge_windows.dart'; +import 'package:quill_native_bridge_windows/src/environment_provider.dart'; +import 'package:quill_native_bridge_windows/src/image_saver.dart'; + +@GenerateMocks([FileSelectorPlatform, EnvironmentProvider]) +import 'quill_native_bridge_windows_test.mocks.dart'; + +const _fakeWindowsUserHomeDir = 'C:\\Users\\foo-bar'; + +void main() { + late QuillNativeBridgeWindows plugin; + + setUp(() { + plugin = QuillNativeBridgeWindows(); + }); + + test('registered instance', () { + QuillNativeBridgeWindows.registerWith(); + expect(QuillNativeBridgePlatform.instance, isA()); + }); + + test('defaults image saver instance to $ImageSaver', () { + expect(QuillNativeBridgeWindows.imageSaver, isA()); + }); + + group('$ImageSaver', () { + // A file that always exists during tests + late File imageTestFile; + late MockEnvironmentProvider mockEnvironmentProvider; + late MockFileSelectorPlatform mockFileSelectorPlatform; + late ImageSaver imageSaver; + + setUp(() async { + mockFileSelectorPlatform = MockFileSelectorPlatform(); + + imageSaver = ImageSaver(); + imageSaver.fileSelector = mockFileSelectorPlatform; + + QuillNativeBridgeWindows.imageSaver = imageSaver; + + mockEnvironmentProvider = MockEnvironmentProvider(); + EnvironmentProvider.instance = mockEnvironmentProvider; + + imageTestFile = File( + '${Directory.systemTemp.path}/tempImageTest_${DateTime.now().millisecondsSinceEpoch}.png'); + await imageTestFile.create(); + + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => null); + when(mockEnvironmentProvider.environment).thenReturn({}); + }); + + tearDown(() async { + await imageTestFile.delete(); + }); + + test( + 'The Windows user home environment key should be correct', + () { + expect(ImageSaver.windowsUserHomeEnvKey, equals('USERPROFILE')); + }, + ); + + test('The pictures directory name should be correct', () { + expect(ImageSaver.picturesDirectoryName, equals('Pictures')); + }); + + test( + 'saveImage should return null for the file path if user cancels the save dialog', + () async { + final result = (await plugin.saveImage( + Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ), + )) + .filePath; + expect(result, isNull); + }, + ); + + test( + 'file selector instance internally defaults to $FileSelectorWindows', + () { + expect(ImageSaver().fileSelector, isA()); + }, + ); + + test( + 'userHome delegates to Platform.environment with the correct key', + () { + when(mockEnvironmentProvider.environment).thenReturn( + {ImageSaver.windowsUserHomeEnvKey: _fakeWindowsUserHomeDir}); + expect(imageSaver.userHome, equals(_fakeWindowsUserHomeDir)); + + verify(mockEnvironmentProvider + .environment[ImageSaver.windowsUserHomeEnvKey]) + .called(1); + + when(mockEnvironmentProvider.environment) + .thenReturn({ImageSaver.windowsUserHomeEnvKey: ''}); + expect(imageSaver.userHome, equals('')); + + verify(mockEnvironmentProvider + .environment[ImageSaver.windowsUserHomeEnvKey]) + .called(1); + }, + ); + + test( + 'picturesDirectoryPath returns null when userHome is empty or null', + () { + when(mockEnvironmentProvider.environment) + .thenReturn({ImageSaver.windowsUserHomeEnvKey: ''}); + expect(imageSaver.picturesDirectoryPath, isNull); + verify(imageSaver.userHome).called(1); + + when(mockEnvironmentProvider.environment) + .thenReturn({ImageSaver.windowsUserHomeEnvKey: null}); + expect(imageSaver.picturesDirectoryPath, isNull); + verify(imageSaver.userHome).called(1); + }, + ); + + test( + 'picturesDirectoryPath depends on userHome', + () { + when(mockEnvironmentProvider.environment) + .thenReturn({ImageSaver.windowsUserHomeEnvKey: ''}); + imageSaver.picturesDirectoryPath; + verify(mockEnvironmentProvider + .environment[ImageSaver.windowsUserHomeEnvKey]); + }, + ); + + test( + 'picturesDirectoryPath correctly joins user home with pictures directory', + () { + when(mockEnvironmentProvider.environment).thenReturn( + {ImageSaver.windowsUserHomeEnvKey: _fakeWindowsUserHomeDir}); + expect( + imageSaver.picturesDirectoryPath, + equals( + '${_fakeWindowsUserHomeDir}\\${ImageSaver.picturesDirectoryName}'), + ); + }, + ); + + test( + 'saveImage should return file path if save is successful', + () async { + final saveLocation = FileSaveLocation(imageTestFile.path); + + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => saveLocation); + + final filePath = (await plugin.saveImage( + Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ), + )) + .filePath; + + expect(filePath, equals(saveLocation.path)); + }, + ); + test( + 'saveImage passes the arguments correctly to fileSelector.getSaveLocation', + () async { + final imageBytes = Uint8List.fromList([1, 0, 1]); + final options = ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'jpg', + ); + + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer( + (invocation) async => FileSaveLocation(imageTestFile.path)); + + await plugin.saveImage( + imageBytes, + options: options, + ); + + final capturedOptions = verify(mockFileSelectorPlatform.getSaveLocation( + options: captureAnyNamed('options'), + acceptedTypeGroups: captureAnyNamed('acceptedTypeGroups'), + )).captured; + + SaveDialogOptions? passedOptions = + capturedOptions[0] as SaveDialogOptions; + List passedAcceptedTypeGroups = + capturedOptions[1] as List; + + expect(passedOptions.suggestedName, + '${options.name}.${options.fileExtension}'); + expect( + passedOptions.initialDirectory, imageSaver.picturesDirectoryPath); + expect(passedAcceptedTypeGroups.map((e) => e.toJSON()), [ + XTypeGroup( + label: 'Images', + extensions: [options.fileExtension], + ).toJSON() + ]); + }, + ); + + test('saveImage calls fileSelector.getSaveLocation only once', () async { + await plugin.saveImage( + Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ), + ); + verify(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).called(1); + }); + + test( + 'saveImage returns null for the file path when $FileSaveLocation from fileSelector.getSaveLocation is null', + () async { + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => null); + + final imageFilePath = (await plugin.saveImage( + Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ), + )) + .filePath; + + expect(imageFilePath, isNull); + }, + ); + + test( + 'saveImage writes the bytes to the file on success', + () async { + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => FileSaveLocation(imageTestFile.path)); + + final imageBytes = Uint8List.fromList([1, 0, 1]); + + expect(imageTestFile.existsSync(), isTrue, + reason: 'The $setUp should create the test file'); + + final filePath = (await plugin.saveImage( + imageBytes, + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + ), + )) + .filePath; + if (filePath == null) { + fail('Expected the operation to succeed.'); + } + + expect(imageTestFile.readAsBytesSync(), imageBytes); + expect(File(filePath).readAsBytesSync(), imageBytes); + }, + ); + + test( + 'saveImage always passes null to blob URL on non-web platforms', + () async { + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('acceptedTypeGroups'), + )).thenAnswer((_) async => null); + final result = await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + )); + expect(result.blobUrl, isNull); + + when(mockFileSelectorPlatform.getSaveLocation( + acceptedTypeGroups: anyNamed('acceptedTypeGroups'), + options: anyNamed('options'), + )).thenAnswer((_) async => FileSaveLocation(imageTestFile.path)); + + final result2 = await plugin.saveImage(Uint8List.fromList([1, 0, 1]), + options: ImageSaveOptions( + name: 'ExampleImage', + fileExtension: 'png', + )); + expect(result2.blobUrl, isNull); + expect(result2.filePath, imageTestFile.path); + }, + ); + }); +} diff --git a/quill_native_bridge_windows/test/quill_native_bridge_windows_test.mocks.dart b/quill_native_bridge_windows/test/quill_native_bridge_windows_test.mocks.dart new file mode 100644 index 0000000..04ccb13 --- /dev/null +++ b/quill_native_bridge_windows/test/quill_native_bridge_windows_test.mocks.dart @@ -0,0 +1,161 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in quill_native_bridge_windows/test/quill_native_bridge_windows_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:quill_native_bridge_windows/src/environment_provider.dart' + as _i4; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [FileSelectorPlatform]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockFileSelectorPlatform extends _i1.Mock + implements _i2.FileSelectorPlatform { + MockFileSelectorPlatform() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Future<_i2.XFile?> openFile({ + List<_i2.XTypeGroup>? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #openFile, + [], + { + #acceptedTypeGroups: acceptedTypeGroups, + #initialDirectory: initialDirectory, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future<_i2.XFile?>.value(), + ) as _i3.Future<_i2.XFile?>); + + @override + _i3.Future> openFiles({ + List<_i2.XTypeGroup>? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #openFiles, + [], + { + #acceptedTypeGroups: acceptedTypeGroups, + #initialDirectory: initialDirectory, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future>.value(<_i2.XFile>[]), + ) as _i3.Future>); + + @override + _i3.Future getSavePath({ + List<_i2.XTypeGroup>? acceptedTypeGroups, + String? initialDirectory, + String? suggestedName, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #getSavePath, + [], + { + #acceptedTypeGroups: acceptedTypeGroups, + #initialDirectory: initialDirectory, + #suggestedName: suggestedName, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future<_i2.FileSaveLocation?> getSaveLocation({ + List<_i2.XTypeGroup>? acceptedTypeGroups, + _i2.SaveDialogOptions? options = const _i2.SaveDialogOptions(), + }) => + (super.noSuchMethod( + Invocation.method( + #getSaveLocation, + [], + { + #acceptedTypeGroups: acceptedTypeGroups, + #options: options, + }, + ), + returnValue: _i3.Future<_i2.FileSaveLocation?>.value(), + ) as _i3.Future<_i2.FileSaveLocation?>); + + @override + _i3.Future getDirectoryPath({ + String? initialDirectory, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #getDirectoryPath, + [], + { + #initialDirectory: initialDirectory, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future> getDirectoryPaths({ + String? initialDirectory, + String? confirmButtonText, + }) => + (super.noSuchMethod( + Invocation.method( + #getDirectoryPaths, + [], + { + #initialDirectory: initialDirectory, + #confirmButtonText: confirmButtonText, + }, + ), + returnValue: _i3.Future>.value([]), + ) as _i3.Future>); +} + +/// A class which mocks [EnvironmentProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockEnvironmentProvider extends _i1.Mock + implements _i4.EnvironmentProvider { + MockEnvironmentProvider() { + _i1.throwOnMissingStub(this); + } + + @override + Map get environment => (super.noSuchMethod( + Invocation.getter(#environment), + returnValue: {}, + ) as Map); +}