|
|
|
|
# Flutter Quill Extensions
|
|
|
|
|
|
|
|
|
|
An extensions for [flutter_quill](https://pub.dev/packages/flutter_quill)
|
|
|
|
|
to support embedding widgets like images, formulas, videos, and more.
|
|
|
|
|
|
|
|
|
|
Check [Flutter Quill](https://github.com/singerdmx/flutter-quill) for details of use.
|
|
|
|
|
|
|
|
|
|
## 📚 Table of Contents
|
|
|
|
|
|
|
|
|
|
- [Flutter Quill Extensions](#flutter-quill-extensions)
|
|
|
|
|
- [📚 Table of Contents](#-table-of-contents)
|
|
|
|
|
- [📝 About](#-about)
|
|
|
|
|
- [📦 Installation](#-installation)
|
|
|
|
|
- [🛠 Platform Specific Configurations](#-platform-specific-configurations)
|
|
|
|
|
- [🚀 Usage](#-usage)
|
|
|
|
|
- [⚙️ Configurations](#️-configurations)
|
|
|
|
|
- [📦 Embed Blocks](#-embed-blocks)
|
|
|
|
|
- [🔍 Element properties](#-element-properties)
|
|
|
|
|
- [🔧 Custom Element properties](#-custom-element-properties)
|
|
|
|
|
- [🖼️ Image Assets](#️-image-assets)
|
|
|
|
|
- [🎯 Drag and drop feature](#-drag-and-drop-feature)
|
|
|
|
|
- [💡 Features](#-features)
|
|
|
|
|
- [🤝 Contributing](#-contributing)
|
|
|
|
|
- [🌟 Acknowledgments](#-acknowledgments)
|
|
|
|
|
|
|
|
|
|
## 📝 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 <br>
|
|
|
|
|
|
|
|
|
|
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](https://github.com/singerdmx/flutter-quill) package first and follow
|
|
|
|
|
its usage instructions.
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
dependencies:
|
|
|
|
|
flutter_quill_extensions: ^<latest-version-here>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
<p align="center">OR</p>
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
dependencies:
|
|
|
|
|
flutter_quill_extensions:
|
|
|
|
|
git: https://github.com/singerdmx/flutter-quill.git
|
|
|
|
|
path: flutter_quill_extensions
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 🛠 Platform Specific Configurations
|
|
|
|
|
|
|
|
|
|
The package uses the following plugins:
|
|
|
|
|
|
|
|
|
|
1. [`gal`](https://github.com/natsuk4ze/) plugin to save images.
|
|
|
|
|
For this to work, you need to add the appropriate configurations
|
|
|
|
|
See <https://github.com/natsuk4ze/gal#-get-started> to add the needed lines.
|
|
|
|
|
2. [`image_picker`](https://pub.dev/packages/image_picker) plugin for picking images so please make sure to follow the
|
|
|
|
|
instructions
|
|
|
|
|
3. [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter) plugin which
|
|
|
|
|
uses [`flutter_inappwebview`](https://pub.dev/packages/flutter_inappwebview) which has a requirement on web, please
|
|
|
|
|
follow this [link](https://pub.dev/packages/flutter_inappwebview#installation) to set up the support for web
|
|
|
|
|
4. [`image_picker`](https://pub.dev/packages/image_picker) which also
|
|
|
|
|
requires some configurations, follow this [link](https://pub.dev/packages/image_picker#installation).
|
|
|
|
|
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](https://pub.dev/packages/image_picker#windows-macos-and-linux)
|
|
|
|
|
5. [`super_clipboard`](https://pub.dev/packages/super_clipboard) which needs some setup on Android only, it's used to
|
|
|
|
|
support copying images and pasting them into editor then you must set up it, open the page in pub.dev and read
|
|
|
|
|
the `README.md` or click on this [link](https://pub.dev/packages/super_clipboard#android-support) to get the
|
|
|
|
|
instructions.
|
|
|
|
|
|
|
|
|
|
The minSdkVersion is `23` as `super_clipboard` requires it
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> For loading the image from the internet <br> <br>
|
|
|
|
|
> **Android**: you need to add permissions in `AndroidManifest.xml`, Follow
|
|
|
|
|
> this [Android Guide](https://developer.android.com/training/basics/network-ops/connecting)
|
|
|
|
|
> or [Flutter Networking](https://docs.flutter.dev/data-and-backend/networking#android) for more info, the internet
|
|
|
|
|
> permission is included by default only for debugging, 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 [Android Cleartext / Plaintext HTTP](https://developer.android.com/privacy-and-security/risks/cleartext) page for
|
|
|
|
|
> more info. <br> <br>
|
|
|
|
|
> **macOS**: you need to include a key in your `Info.plist`, follow
|
|
|
|
|
> this [link](https://docs.flutter.dev/data-and-backend/networking#macos) to add the required configurations
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
## 🚀 Usage
|
|
|
|
|
|
|
|
|
|
Start using the package in 3 steps:
|
|
|
|
|
|
|
|
|
|
1. Be sure to follow the [Installation](#installation) section.
|
|
|
|
|
2. This package already include `super_clipboard` and will be used internally in this package, to use it
|
|
|
|
|
in `flutter_quill`, call this function before using any of the widgets or functionalities
|
|
|
|
|
|
|
|
|
|
```dart
|
|
|
|
|
FlutterQuillExtensions.useSuperClipboardPlugin();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`super_clipboard` is comprehensive plugin that provides many clipboard features for reading and writing of rich text,
|
|
|
|
|
images and other formats.
|
|
|
|
|
|
|
|
|
|
Executing this function will allow `flutter_quill` to use modern rich text features to paste HTML and Markdown,
|
|
|
|
|
support for Gif files, and other formats.
|
|
|
|
|
|
|
|
|
|
3. Set the `embedBuilders` and `embedToolbar` params in configurations of `QuillEditor` and `QuillToolbar` with the
|
|
|
|
|
values provided by this repository.
|
|
|
|
|
|
|
|
|
|
**Quill Toolbar**:
|
|
|
|
|
```dart
|
|
|
|
|
QuillToolbar(
|
|
|
|
|
configurations: QuillToolbarConfigurations(
|
|
|
|
|
embedButtons: FlutterQuillEmbeds.toolbarButtons(),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Quill Editor**
|
|
|
|
|
```dart
|
|
|
|
|
Expanded(
|
|
|
|
|
child: QuillEditor.basic(
|
|
|
|
|
configurations: QuillEditorConfigurations(
|
|
|
|
|
embedBuilders: kIsWeb ? FlutterQuillEmbeds.editorWebBuilders() : FlutterQuillEmbeds.editorBuilders(),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## ⚙️ Configurations
|
|
|
|
|
|
|
|
|
|
### 📦 Embed Blocks
|
|
|
|
|
|
|
|
|
|
As of version [flutter_quill](https://pub.dev/packages/flutter_quill) `6.0.x`, 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](#usage) section
|
|
|
|
|
|
|
|
|
|
### 🔍 Element properties
|
|
|
|
|
|
|
|
|
|
Currently, the library has limited support for the image and video properties,
|
|
|
|
|
and it supports only `width`, `height`, `margin`
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"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:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"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:
|
|
|
|
|
|
|
|
|
|
```dart
|
|
|
|
|
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 its 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](https://pub.dev/packages/desktop_drop), it was originally developed for desktop.
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
flutter pub add desktop_drop
|
|
|
|
|
```
|
|
|
|
|
and import it with
|
|
|
|
|
```dart
|
|
|
|
|
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`
|
|
|
|
|
|
|
|
|
|
```dart
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
```dart
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
```markdown
|
|
|
|
|
## Features
|
|
|
|
|
|
|
|
|
|
— Easy to use and customizable
|
|
|
|
|
|
|
|
|
|
- Rich text, images and other formats
|
|
|
|
|
- Useful utilities and widgets
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 🤝 Contributing
|
|
|
|
|
|
|
|
|
|
We welcome contributions!
|
|
|
|
|
|
|
|
|
|
Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](../CONTRIBUTING.md) for more
|
|
|
|
|
details.
|
|
|
|
|
|
|
|
|
|
## 🌟 Acknowledgments
|
|
|
|
|
|
|
|
|
|
- Thanks to the [Flutter Team](https://flutter.dev/)
|
|
|
|
|
- Thanks to the welcoming community, the volunteers who helped along the journey, developers, contributors
|
|
|
|
|
and contributors who put time and effort into everything including making all the libraries, tools, and the
|
|
|
|
|
information we rely on
|
|
|
|
|
|
|
|
|
|
We are incredibly grateful to many individuals and organizations who have played a
|
|
|
|
|
role in the project. This includes the welcoming community, dedicated volunteers, talented developers and
|
|
|
|
|
contributors, and the creators of the open-source tools we rely on.
|