Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(flutter_quill_extensions): improve image save #2403

Merged
merged 23 commits into from
Dec 13, 2024

Conversation

EchoEllet
Copy link
Collaborator

@EchoEllet EchoEllet commented Dec 2, 2024

Description

Fix broken image save functionality in flutter_quill_extensions, improve the default behavior, support web and desktop platforms (platforms that don't have gallery app), add unit tests, support Swift package manager, remove extra dependencies.

The current behavior of image save functionality is broken on non-mobile platforms, and the way that the extensions package handles the errors and results (error and success messages) is confusing. The goal of this package is to implement an opinioned solution for loading images and videos but it seems most users avoid this package, I plan on replacing it with new packages (quill_image and quill_video, see #2276), and that will be later.

This PR addresses:

  • Added web and Linux support. The gal_linux implementation was confusing due to the way it was handled. It's not officially supported and was implemented by myself. There is no way to implement it correctly without some changes to the gal platform interface.
  • Added support for Swift package manager for iOS and macOS (Support for Swift Package Manager #2394).
  • Updated desktop image saving behavior. Saving to the gallery isn't common and can be confusing. The desktop should open a system save dialog instead. quill_native_bridge implements both saveImageToGallery and saveImage.
  • Replaced gal and gal_linux with quill_native_bridge. It supports:
    • saveImageToGallery: Saves to system gallery (Android, iOS, macOS). Not supported on web/Linux; Windows support is possible but not useful; It's not common behavior for Windows users and saving images using the system file save dialog will integrate with the Windows photos app in both cases.
    • saveImage: Prompts for a save location on the desktop and downloads image on the web.
    • openGalleryApp: Opens the system gallery app. Not supported on web/Linux.
  • Improved success/error messages for all platforms; fixed broken open functionality on the desktop.
  • Added unit tests to improve code coverage.
  • Removed the following dependencies from flutter_quill_extensions:
    • path Added back since it's needed once again and there is no reason to re-implement it.
    • http: Not needed anymore (legacy code).
    • cross_file Not needed anymore (legacy code).
  • Improved mocking support of QuillNativeBridge (workaround is not needed anymore) for unit tests by converting instance methods to static methods (similar to ImagePicker from image_picker and other Flutter plugins).

Added prefersGallerySave to ImageOptionsMenu which determines if it should prefer saving the image to the system gallery (when supported) instead of using the system file save dialog, currently only macOS is applicable since that's the only platform that supports both saveImage and saveImageToGallery. If Windows or Linux were supported, they would be applicable too.

Part of FlutterQuill/quill-native-bridge#9. Tests were added there too though native unit tests are still missing (will be fixed soon).

Soon, will replace flutter_keyboard_visibility_temp_fork (related #2290).

Related Issues

Demostration

This feature is platform-specific, expand each section for more details with videos:

Android

Saving using saveImageToGallery (backed by Android MediaStore) on Android API 29 and later:

AndroidApi29.mov

The system gallery handles name conflicts.

Saving using saveImageToGallery (backed by java.io.File and MediaScannerConnection) on Android API 28 and earlier (requires to write to external storage runtime permission):

AndroidApi28.mov

On Android API 28 and earlier, the quill_native_bridge creates a unique image file name to avoid platform errors.

iOS

Saving using saveImageToGallery (backed by iOS PHPhotoLibrary, requires runtime permission):

iOSPHPotoLibrary.mov

The system gallery handles name conflicts.

macOS

Saving using saveImage (backed by macOS NSSavePanel):

MacOSNSPanel.mov

The system save dialog confirms overwrite if the file already exists.

Saving using saveImageToGallery (backed by macOS PHPhotoLibrary, requires runtime permission):

macOSPHPotoLibrary.mov

The system gallery handles name conflicts.

Note

During development only, permission is always denied when running the app using sources other than Xcode or macOS terminal (such as Android Studio or VS Code). This is a known issue and the quill_native_bridge log to the debug console in debug-builds. See flutter/flutter#134191 (comment)

Web

Saving using saveImage:

Web.mov

It creates Blob object URL, creates a element, sets the href and download attributes, clicks the a element programmatically to download the image file, and then revokes the blob object URL.

The browser handles name conflicts.
Whether the browser will ask the user where they want to save the image will depend on the user's preferences in the settings.

Linux

Saving using saveImage (backed by file_selector_linux):

Linux.mp4

Depending on the Linux desktop environment, the system save dialog might not confirm name conflicts.

Windows

Saving using saveImage (backed by file_selector_windows):

Windows.mp4

The system save dialog confirms overwrite if the file already exists.

Messages

The messages have been improved and changed in an optioned way so most users don't need to override the default. It no longer shows Saved using the network or Saved using the local storage.

  • The unknown error message: An unexpected error occurred while saving the image. Please try again.

  • The permission denied message: Couldn’t save the image due to missing permission

  • The success snack bar message will depend on how the image is saved (platform-specific):

    • Web: Always Image downloaded successfully. with no action button.
    • Mobile or macOS (in case of saving to the gallery): Image saved to your gallery. with action labeled Open Gallery.
    • Desktop: Image saved successfully. with action labeled Open File Location on Windows and Linux or Open File
      on macOS.

Type of Change

  • Feature: New functionality without breaking existing features.
  • 🛠️ Bug fix: Resolves an issue without altering current behavior.
  • 🧹 Refactor: Code reorganization, no behavior change.
  • Breaking: Alters existing functionality and requires updates.
  • 🧪 Tests: New or modified tests
  • 📝 Documentation: Updates or additions to documentation.
  • 🗑️ Chore: Routine tasks, or maintenance.
  • Build configuration change: Build/configuration changes.

@EchoEllet EchoEllet added enhancement New feature or request moderate Issues that are important for improving functionality or user experience. labels Dec 2, 2024
pubspec.yaml Show resolved Hide resolved
Copy link
Collaborator Author

@EchoEllet EchoEllet left a comment

Choose a reason for hiding this comment

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

Ready for review, most of the changes are new keys added to quill_en.arb, tests, or changes to the macOS and iOS example app for Swift package manager integration.

@EchoEllet EchoEllet marked this pull request as ready for review December 3, 2024 13:59
@EchoEllet EchoEllet merged commit a86f9bc into master Dec 13, 2024
3 checks passed
@EchoEllet EchoEllet deleted the feat/improve-image-save branch December 13, 2024 12:40
@EchoEllet
Copy link
Collaborator Author

Merged as I wasn’t sure if more time was needed for review, and we have other issues to focus on as well.
Flutter 3.27.0 is now stable and supports Swift package manager.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request moderate Issues that are important for improving functionality or user experience.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for Swift Package Manager Saving image file should say where it has been saved on desktop
2 participants