Flutter Quill Extensions

An extensions for flutter_quill to support embedding widgets like images, formulas, videos, and more.

Check Flutter Quill for details of use.

Table of Contents

About

Flutter Quill is a rich editor text. It'd allow you to customize a lot of things, it has custom embed builders that allow you to render custom widgets in the editor
this is an extension to extend its functionalities by adding more features like images, videos, and more

Installation

Before starting using this package, please make sure to install flutter_quill package first and follow its usage instructions.

dependencies:
  flutter_quill_extensions: ^<latest-version-here>

OR

dependencies:
  flutter_quill_extensions:
    git: https://github.com/singerdmx/flutter-quill.git
    path: flutter_quill_extensions

Platform Specific Configurations

  1. We are using the gal plugin to save images. For this to work, you need to add the appropriate configurations See github.com/natsuk4ze/gal#-get-started to add the needed lines.

  2. We also use image_picker plugin for picking images so please make sure to follow the instructions

  3. We are using youtube_player_flutter plugin which uses flutter_inappwebview which has requirement on web, please follow this link in order to setup the support for web

  4. For loading the image from the internet, we need the internet permission

    1. For Android, you need to add some permissions in AndroidManifest.xml, Please follow this link for more info, the internet permission is included by default only for debugging so you need to follow this link to add it in the release version too. you should allow loading images and videos only for the https protocol but if you want http too then you need to configure your Android application to accept http in the release mode, follow this link for more info.
    2. For macOS, you also need to include a key in your Info.plist, please follow this link to add the required configurations

The extension package also uses image_picker which also requires some configurations, follow this link. It's needed for Android, iOS, and macOS, we must inform you that you can't pick photos using the camera on a desktop so make sure to handle that if you plan on adding support for the desktop, this may change in the future, and for more info follow this link

Usage

Before starting to use this package you must follow the setup

Set the embedBuilders and embedToolbar params in configurations of QuillEditor and QuillToolbar with the values provided by this repository.

Quill Toolbar:

QuillToolbar(
  configurations: QuillToolbarConfigurations(
    embedButtons: FlutterQuillEmbeds.toolbarButtons(),
  ),
),

Quill Editor

Expanded(
  child: QuillEditor.basic(
    configurations: QuillEditorConfigurations(
      embedBuilders: kIsWeb ? FlutterQuillEmbeds.editorWebBuilders() : FlutterQuillEmbeds.editorBuilders(),
    ),
  ),
)

Embed Blocks

As of version flutter_quill 6.0, embed blocks are not provided by default as part of Flutter quill. Instead, it provides an interface for all the users to provide their implementations for embed blocks. Implementations for image, video, and formula embed blocks are proved in this package

The instructions for using the embed blocks are in the Usage section

Element properties

Currently the library has limitied support for the image and video properties and it supports only width, height, margin

{
      "insert": {
         "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png"
      },
      "attributes": {
         "style":"width: 50px; height: 50px; margin: 10px;"
      }
}

Custom Element properties

Doesn't apply to official Quill JS

Define flutterAlignment` as follows:

{
      "insert": {
         "image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png"
      },
      "attributes":{
         "style":"flutterAlignment: topLeft"
      }
}

This works for all platforms except Web

Image Assets

If you want to use image assets in the Quill Editor, you need to make sure your assets folder is assets otherwise:

QuillEditor.basic(
  configurations: const QuillEditorConfigurations(
    // ...
    sharedConfigurations: QuillSharedConfigurations(
      extraConfigurations: {
        QuillSharedExtensionsConfigurations.key:
            QuillSharedExtensionsConfigurations(
          assetsPrefix: 'your-assets-folder-name', // Defaults to `assets`
        ),
      },
    ),
  ),
);

This info is needed by the package to check if it asset image to use the AssetImage provider

Drag and drop feature

Currently, the drag-and-drop feature is not officially supported, but you can achieve this very easily in the following steps:

  1. Drag and drop require native code, you can use any Flutter plugin you like, if you want a suggestion we recommend desktop_drop, it was originally developed for desktop but it has support for the web as well as Android (that is not the case for iOS)

  2. Add the dependency in your pubspec.yaml using the following command:

    flutter pub add desktop_drop
    

    and import it with

    import 'package:desktop_drop/desktop_drop.dart';
    
  3. in the configurations of QuillEditor, use the builder to wrap the editor with DropTarget which comes from desktop_drop

    import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
       
    QuillEditor.basic(
          configurations: QuillEditorConfigurations(
            padding: const EdgeInsets.all(16),
             builder: (context, rawEditor) {
                return DropTarget(
                  onDragDone: _onDragDone,
                  child: rawEditor,
                );
              },
            embedBuilders: kIsWeb
                ? FlutterQuillEmbeds.editorWebBuilders()
                : FlutterQuillEmbeds.editorBuilders(),
          ),
    )
    
  4. Implement the _onDragDone, it depends on your use case but this is just a simple example

const List<String> imageFileExtensions = [
  '.jpeg',
  '.png',
  '.jpg',
  '.gif',
  '.webp',
  '.tif',
  '.heic'
];
OnDragDoneCallback get _onDragDone {
    return (details) {
      final scaffoldMessenger = ScaffoldMessenger.of(context);
      final file = details.files.first;
      final isSupported =
          imageFileExtensions.any((ext) => file.name.endsWith(ext));
      if (!isSupported) {
        scaffoldMessenger.showSnackBar(
          SnackBar(
            content: Text(
              'Only images are supported right now: ${file.mimeType}, ${file.name}, ${file.path}, $imageFileExtensions',
            ),
          ),
        );
        return;
      }
      // To get this extension function please import flutter_quill_extensions
      _controller.insertImageBlock(
        imageSource: file.path,
      );
      scaffoldMessenger.showSnackBar(
        const SnackBar(
          content: Text('Image is inserted.'),
        ),
      );
    };
  }

Features

## Features

— Easy to use and customizable
- Has the option to use a custom image provider for the images
- Useful utilities and widgets
- Handle different errors

Please notice that the saving image functionality is not supported on Linux yet.

Contributing

We welcome contributions!

Please follow these guidelines when contributing to our project. See CONTRIBUTING.md for more details.

Acknowledgments

Libraries

extensions/attribute
embeds/others/camera_button/camera_button
models/config/camera/camera_configurations
embeds/others/camera_button/camera_types
extensions/controller_ext
utils/dart_ui/dart_ui_fake
utils/dart_ui/dart_ui_real
utils/element_utils/element_shared_utils
utils/element_utils/element_utils
utils/element_utils/element_web_utils
embeds/embed_types
services/image_saver/exceptions
flutter_quill_embeds
flutter_quill_extensions
embeds/formula/toolbar/formula_button
models/config/formula/formula_configurations
embeds/formula/editor/formula_embed
services/image_saver/packages/gal
embeds/widgets/image
embeds/image/toolbar/image_button
models/config/image/editor/image_configurations
models/config/image/toolbar/image_configurations
embeds/image/editor/image_embed
embeds/image/editor/image_embed_types
embeds/image/editor/image_menu
services/image_picker/image_options
services/image_picker/image_picker
services/image_picker/packages/image_picker
embeds/widgets/image_resizer
services/image_saver/image_saver
embeds/others/image_video_utils
models/config/image/editor/image_web_configurations
embeds/image/editor/image_web_embed
embeds/others/media_button/media_button
models/config/media/media_button_configurations
utils/patterns
utils/quill_image_utils
services/image_picker/s_image_picker
services/image_saver/s_image_saver
embeds/others/camera_button/select_camera_action
embeds/image/toolbar/select_image_source
embeds/video/toolbar/select_video_source
models/config/shared_configurations
utils/string
embeds/unknown/editor/unknown_embed
utils/utils
embeds/video/video
embeds/widgets/video_app
embeds/video/toolbar/video_button
models/config/video/editor/video_configurations
models/config/video/toolbar/video_configurations
embeds/video/editor/video_embed
models/config/video/editor/video_web_configurations
embeds/video/editor/video_web_embed
embeds/widgets/youtube_video_app