Skip to content

Commit

Permalink
Improving flutter quill extensions (#1564)
Browse files Browse the repository at this point in the history
* organizations for flutter quill extensions
  • Loading branch information
EchoEllet authored Dec 5, 2023
1 parent 7ccd61e commit 039e319
Show file tree
Hide file tree
Showing 99 changed files with 1,441 additions and 625 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,7 @@ pubspec.lock
# For local development
pubspec_overrides.yaml

old_example
old_example

# A directory where you put all of your local things that you don't want to push
.flutter-quill
4 changes: 2 additions & 2 deletions example/lib/presentation/quill/quill_editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import 'package:desktop_drop/desktop_drop.dart' show DropTarget;
import 'package:flutter/material.dart';
import 'package:flutter_quill/extensions.dart' show isAndroid, isIOS, isWeb;
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
import 'package:flutter_quill_extensions/presentation/embeds/widgets/image.dart'
import 'package:flutter_quill_extensions/embeds/widgets/image.dart'
show getImageProviderByImageSource, imageFileExtensions;
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
import 'package:path/path.dart' as path;

import '../extensions/scaffold_messenger.dart';
Expand Down
18 changes: 9 additions & 9 deletions example/lib/presentation/quill/samples/quill_images_sample.dart

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions flutter_quill_extensions/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

All notable changes to this project will be documented in this file.

## 0.8.0-dev
* **Breaking Change**: Completly change the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library
from `flutter_quill_extensions.dart` then there is nothing you need to do, but if you are using any other import then you need to re-imports
embed, this won't affect how quill js work
* Improvemenets to the image embed
* Add support for `margin` for web
* Add untranslated strings to the `quill_en.arb`

## 0.7.2
* Fix a bug when opening the link dialog for both video and image buttons
* Update `README.md`
Expand Down
25 changes: 14 additions & 11 deletions flutter_quill_extensions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ to support embedding widgets like images, formulas, videos, and more.
- [Platform Specific Configurations](#platform-specific-configurations)
- [Usage](#usage)
- [Embed Blocks](#embed-blocks)
- [Custom Size Image for Mobile](#custom-size-image-for-mobile)
- [Custom Size Image for other platforms](#custom-size-image-for-other-platforms)
- [Element properties](#element-properties)
- [Custom Element properties](#custom-element-properties)
- [Drag and drop feature](#drag-and-drop-feature)
- [Features](#features)
- [Contributing](#contributing)
Expand Down Expand Up @@ -130,37 +130,40 @@ As of version [flutter_quill](https://pub.dev/packages/flutter_quill) 6.0, embed

The instructions for using the embed blocks are in the [Usage](#usage) section

### Custom Size Image for Mobile
### Element properties

Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follows:
Currently the library has limitied 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":"mobileWidth: 50; mobileHeight: 50; mobileMargin: 10; mobileAlignment: topLeft"
"attributes": {
"style":"width: 50px; height: 50px; margin: 10px;"
}
}
```

### Custom Size Image for other platforms
### Custom Element properties

Doesn't apply to official Quill JS

Define `width`, `height`, `margin`, `alignment` as follows:
Define flutterAlignment` as follows:

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


This works for all platforms except Web

### 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:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_quill/extensions.dart' as base;
import 'package:flutter_quill/flutter_quill.dart'
show BlockEmbed, EmbedBuilder, QuillController;
show BlockEmbed, Embed, EmbedBuilder, QuillController;

class QuillEditorFormulaEmbedBuilder extends EmbedBuilder {
const QuillEditorFormulaEmbedBuilder();
Expand All @@ -15,7 +14,7 @@ class QuillEditorFormulaEmbedBuilder extends EmbedBuilder {
Widget build(
BuildContext context,
QuillController controller,
base.Embed node,
Embed node,
bool readOnly,
bool inline,
TextStyle textStyle,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';

import '../../models/config/toolbar/buttons/formula.dart';
import '../../../models/config/toolbar/buttons/formula.dart';

class QuillToolbarFormulaButton extends StatelessWidget {
const QuillToolbarFormulaButton({
Expand Down
86 changes: 86 additions & 0 deletions flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart' hide OptionalSize;
import 'package:flutter_quill/translations.dart';

import '../../../models/config/editor/image/image.dart';
import '../../../models/config/shared_configurations.dart';
import '../../../utils/element_utils/element_utils.dart';
import '../../widgets/image.dart';
import 'image_menu.dart';

class QuillEditorImageEmbedBuilder extends EmbedBuilder {
QuillEditorImageEmbedBuilder({
required this.configurations,
});
final QuillEditorImageEmbedConfigurations configurations;

@override
String get key => BlockEmbed.imageType;

@override
bool get expanded => false;

@override
Widget build(
BuildContext context,
QuillController controller,
Embed node,
bool readOnly,
bool inline,
TextStyle textStyle,
) {
assert(!kIsWeb, 'Please provide image EmbedBuilder for Web');

final imageSource = standardizeImageUrl(node.value.data);
final ((imageSize), margin, alignment) = getElementAttributes(node);

final width = imageSize.width;
final height = imageSize.height;

final image = getImageWidgetByImageSource(
imageSource,
imageProviderBuilder: configurations.imageProviderBuilder,
imageErrorWidgetBuilder: configurations.imageErrorWidgetBuilder,
alignment: alignment,
height: height,
width: width,
assetsPrefix: QuillSharedExtensionsConfigurations.get(context: context)
.assetsPrefix,
);

final imageSaverService =
QuillSharedExtensionsConfigurations.get(context: context)
.imageSaverService;
return GestureDetector(
onTap: configurations.onImageClicked ??
() => showDialog(
context: context,
builder: (_) => QuillProvider.value(
value: context.requireQuillProvider,
child: FlutterQuillLocalizationsWidget(
child: ImageOptionsMenu(
controller: controller,
configurations: configurations,
imageSource: imageSource,
imageSize: imageSize,
isReadOnly: readOnly,
imageSaverService: imageSaverService,
),
),
),
),
child: Builder(
builder: (context) {
if (margin != null) {
return Padding(
padding: EdgeInsets.all(margin),
child: image,
);
}
return image;
},
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import 'package:flutter/widgets.dart' show BuildContext;
import 'package:flutter_quill/flutter_quill.dart';
import 'package:meta/meta.dart' show immutable;

import '../../../logic/extensions/controller.dart';
import '../../../logic/services/image_picker/s_image_picker.dart';
import '../../../extensions/controller.dart';
import '../../../services/image_picker/s_image_picker.dart';

/// When request picking an image, for example when the image button toolbar
/// clicked, it should be null in case the user didn't choose any image or
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import 'package:flutter/cupertino.dart' show showCupertinoModalPopup;
import 'package:flutter/material.dart';
import 'package:flutter_quill/extensions.dart' show isMobile;
import 'package:flutter_quill/flutter_quill.dart'
show
FlutterQuillLocalizationsWidget,
ImageUrl,
QuillController,
QuillProvider,
Expand All @@ -12,10 +10,11 @@ import 'package:flutter_quill/flutter_quill.dart'
getEmbedNode;
import 'package:flutter_quill/translations.dart';

import '../../../../logic/models/config/shared_configurations.dart';
import '../../../../logic/services/image_saver/s_image_saver.dart';
import '../../../../logic/utils/string.dart';
import '../../../models/config/editor/image/image.dart';
import '../../../models/config/shared_configurations.dart';
import '../../../services/image_saver/s_image_saver.dart';
import '../../../utils/element_utils/element_utils.dart';
import '../../../utils/string.dart';
import '../../../utils/utils.dart';
import '../../widgets/image.dart' show ImageTapWrapper, getImageStyleString;
import '../../widgets/image_resizer.dart' show ImageResizer;
Expand All @@ -34,7 +33,7 @@ class ImageOptionsMenu extends StatelessWidget {
final QuillController controller;
final QuillEditorImageEmbedConfigurations configurations;
final String imageSource;
final OptionalSize imageSize;
final ElementSize imageSize;
final bool isReadOnly;
final ImageSaverService imageSaverService;

Expand Down Expand Up @@ -70,7 +69,6 @@ class ImageOptionsMenu extends StatelessWidget {
getImageStyleString(controller),
width: width,
height: height,
isMobile: isMobile(supportWeb: false),
);
controller
..skipRequestKeyboard = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import 'package:flutter_quill/flutter_quill.dart';
import 'package:universal_html/html.dart' as html;

import '../../../models/config/editor/image/image_web.dart';
import '../../../utils/dart_ui/dart_ui_fake.dart'
if (dart.library.html) '../../../utils/dart_ui/dart_ui_real.dart' as ui;
import '../../../utils/element_utils/element_web_utils.dart';
import '../../../utils/utils.dart';
import '../../../utils/web_utils.dart';
import '../shims/dart_ui_fake.dart'
if (dart.library.html) '../shims/dart_ui_real.dart' as ui;

class QuillEditorWebImageEmbedBuilder extends EmbedBuilder {
const QuillEditorWebImageEmbedBuilder({
Expand Down Expand Up @@ -43,7 +43,7 @@ class QuillEditorWebImageEmbedBuilder extends EmbedBuilder {
// if not then it will add the data:image/png;base64, at the first
if (isImageBase64(imageSource)) {
// Sometimes the image base 64 for some reasons
// doesn't displayed with the
// doesn't displayed with the 'data:image/png;base64'
if (!(imageSource.startsWith('data:image/') &&
imageSource.contains('base64'))) {
imageSource = 'data:image/png;base64, $imageSource';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill/translations.dart';

import '../../../../logic/models/config/shared_configurations.dart';
import '../../../../logic/services/image_picker/image_picker.dart';
import '../../../models/config/shared_configurations.dart';
import '../../../models/config/toolbar/buttons/image.dart';
import '../../embed_types/image.dart';
import '../utils/image_video_utils.dart';
import '../../../services/image_picker/image_picker.dart';
import '../../others/image_video_utils.dart';
import '../editor/image_embed_types.dart';
import 'select_image_source.dart';

class QuillToolbarImageButton extends StatelessWidget {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_quill/extensions.dart' show isDesktop;
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill/translations.dart';

import '../../embed_types/image.dart';
import '../editor/image_embed_types.dart';

class SelectImageSourceDialog extends StatelessWidget {
const SelectImageSourceDialog({super.key});
Expand All @@ -14,28 +16,27 @@ class SelectImageSourceDialog extends StatelessWidget {
child: SingleChildScrollView(
child: Column(
children: [
// TODO: Needs to be translated
ListTile(
title: const Text('Gallery'),
subtitle: const Text(
'Pick a photo from your gallery',
title: Text(context.loc.gallery),
subtitle: Text(
context.loc.pickAPhotoFromYourGallery,
),
leading: const Icon(Icons.photo_sharp),
onTap: () => Navigator.of(context).pop(InsertImageSource.gallery),
),
ListTile(
title: const Text('Camera'),
subtitle: const Text(
'Take a photo using your phone camera',
title: Text(context.loc.camera),
subtitle: Text(
context.loc.takeAPhotoUsingYourCamera,
),
leading: const Icon(Icons.camera),
enabled: !isDesktop(supportWeb: false),
onTap: () => Navigator.of(context).pop(InsertImageSource.camera),
),
ListTile(
title: const Text('Link'),
subtitle: const Text(
'Paste a photo using a link',
title: Text(context.loc.link),
subtitle: Text(
context.loc.pasteAPhotoUsingALink,
),
leading: const Icon(Icons.link),
onTap: () => Navigator.of(context).pop(InsertImageSource.link),
Expand All @@ -54,7 +55,12 @@ Future<InsertImageSource?> showSelectImageSourceDialog({
showDragHandle: true,
context: context,
constraints: const BoxConstraints(maxWidth: 640),
builder: (_) => const SelectImageSourceDialog(),
builder: (_) => QuillProvider.value(
value: context.requireQuillProvider,
child: const FlutterQuillLocalizationsWidget(
child: SelectImageSourceDialog(),
),
),
);
return imageSource;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import 'package:flutter_quill/flutter_quill.dart'
QuillToolbarIconButton;
import 'package:flutter_quill/translations.dart';

import '../../../../logic/models/config/shared_configurations.dart';
import '../../../../logic/services/image_picker/image_options.dart';
import '../../../models/config/shared_configurations.dart';
import '../../../models/config/toolbar/buttons/camera.dart';
import '../../embed_types/camera.dart';
import '../../../services/image_picker/image_options.dart';
import 'camera_types.dart';
import 'select_camera_action.dart';

class QuillToolbarCameraButton extends StatelessWidget {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:flutter/widgets.dart' show BuildContext;
import 'package:meta/meta.dart' show immutable;

import 'image.dart';
import 'video.dart';
import '../../image/editor/image_embed_types.dart';
import '../../video/video.dart';

enum CameraAction {
video,
Expand Down
Loading

0 comments on commit 039e319

Please sign in to comment.