Skip to content

Commit 82d4bf7

Browse files
authored
Embed refactor (singerdmx#933)
* Moved all embed code to seperate folder * Consolidated embed builders * Moved embed toolbar items out * Moved embed code to separate package * Updated imports * Removed I from interface names * Refactored embed button implementation * Update readme
1 parent 4b46df2 commit 82d4bf7

38 files changed

+828
-570
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
# [6.0.0] BREAKING CHANGE
2+
* Removed embed (image, video & forumla) blocks from the package to reduce app size.
3+
4+
These blocks have been moved to the package `flutter_quill_extensions`, migrate by filling the `embedBuilders` and `embedButtons` parameters as follows:
5+
6+
```
7+
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
8+
9+
QuillEditor.basic(
10+
controller: controller,
11+
embedBuilders: FlutterQuillEmbeds.builders,
12+
);
13+
14+
QuillToolbar.basic(
15+
controller: controller,
16+
embedButtons: FlutterQuillEmbeds.buttons(),
17+
);
18+
```
19+
20+
121
# [5.4.2]
222
* Upgrade i18n_extension.
323

README.md

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,31 @@ QuillToolbar.basic(
153153
]
154154
```
155155

156+
157+
## Embed Blocks
158+
159+
As of version 6.0, embed blocks are not provided by default as part of this package. Instead, this packet provides an interface to all the user to provide there own implementations for embed blocks. Implementations for image, video and forumal embed blocks is proved in a separate package `flutter_quill_extensions`.
160+
161+
Provide a list of embed
162+
163+
### Using the embed blocks from `flutter_quill_extensions`
164+
165+
```
166+
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
167+
168+
QuillEditor.basic(
169+
controller: controller,
170+
embedBuilders: FlutterQuillEmbeds.builders,
171+
);
172+
173+
QuillToolbar.basic(
174+
controller: controller,
175+
embedButtons: FlutterQuillEmbeds.buttons(),
176+
);
177+
```
178+
179+
180+
156181
### Custom Size Image for Mobile
157182

158183
Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follows:
@@ -171,7 +196,7 @@ Define `mobileWidth`, `mobileHeight`, `mobileMargin`, `mobileAlignment` as follo
171196

172197
Sometimes you want to add some custom content inside your text, custom widgets inside of them. An example is adding notes to the text, or anything custom that you want to add in your text editor.
173198

174-
The only thing that you need is to add a `CustomBlockEmbed` and map it into the `customElementsEmbedBuilder`, to transform the data inside of the Custom Block into a widget!
199+
The only thing that you need is to add a `CustomBlockEmbed` and provider a builder for it to the `embedBuilders` parameter, to transform the data inside of the Custom Block into a widget!
175200

176201
Here is an example:
177202

@@ -194,35 +219,40 @@ After that, we need to map this "notes" type into a widget. In that case, I used
194219
Don't forget to add this method to the `QuillEditor` after that!
195220

196221
```dart
197-
Widget customElementsEmbedBuilder(
198-
BuildContext context,
199-
QuillController controller,
200-
CustomBlockEmbed block,
201-
bool readOnly,
202-
void Function(GlobalKey videoContainerKey)? onVideoInit,
203-
) {
204-
switch (block.type) {
205-
case 'notes':
206-
final notes = NotesBlockEmbed(block.data).document;
207-
208-
return Material(
209-
color: Colors.transparent,
210-
child: ListTile(
211-
title: Text(
212-
notes.toPlainText().replaceAll('\n', ' '),
213-
maxLines: 3,
214-
overflow: TextOverflow.ellipsis,
215-
),
216-
leading: const Icon(Icons.notes),
217-
onTap: () => _addEditNote(context, document: notes),
218-
shape: RoundedRectangleBorder(
219-
borderRadius: BorderRadius.circular(10),
220-
side: const BorderSide(color: Colors.grey),
221-
),
222+
class NotesEmbedBuilder implements EmbedBuilder {
223+
NotesEmbedBuilder({required this.addEditNote});
224+
225+
Future<void> Function(BuildContext context, {Document? document}) addEditNote;
226+
227+
@override
228+
String get key => 'notes';
229+
230+
@override
231+
Widget build(
232+
BuildContext context,
233+
QuillController controller,
234+
Embed node,
235+
bool readOnly,
236+
void Function(GlobalKey<State<StatefulWidget>> videoContainerKey)?
237+
onVideoInit) {
238+
final notes = NotesBlockEmbed(node.value.data).document;
239+
240+
return Material(
241+
color: Colors.transparent,
242+
child: ListTile(
243+
title: Text(
244+
notes.toPlainText().replaceAll('\n', ' '),
245+
maxLines: 3,
246+
overflow: TextOverflow.ellipsis,
247+
),
248+
leading: const Icon(Icons.notes),
249+
onTap: () => addEditNote(context, document: notes),
250+
shape: RoundedRectangleBorder(
251+
borderRadius: BorderRadius.circular(10),
252+
side: const BorderSide(color: Colors.grey),
222253
),
223-
);
224-
default:
225-
return const SizedBox();
254+
),
255+
);
226256
}
227257
}
228258
```

example/lib/pages/home_page.dart

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
88
import 'package:flutter/material.dart';
99
import 'package:flutter/services.dart';
1010
import 'package:flutter_quill/flutter_quill.dart' hide Text;
11+
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
1112
import 'package:path/path.dart';
1213
import 'package:path_provider/path_provider.dart';
1314
import 'package:tuple/tuple.dart';
@@ -119,7 +120,10 @@ class _HomePageState extends State<HomePage> {
119120
null),
120121
sizeSmall: const TextStyle(fontSize: 9),
121122
),
122-
customElementsEmbedBuilder: customElementsEmbedBuilder,
123+
embedBuilders: [
124+
...FlutterQuillEmbeds.builders,
125+
NotesEmbedBuilder(addEditNote: _addEditNote)
126+
],
123127
);
124128
if (kIsWeb) {
125129
quillEditor = QuillEditor(
@@ -145,34 +149,40 @@ class _HomePageState extends State<HomePage> {
145149
null),
146150
sizeSmall: const TextStyle(fontSize: 9),
147151
),
148-
embedBuilder: defaultEmbedBuilderWeb);
152+
embedBuilders: defaultEmbedBuildersWeb);
149153
}
150154
var toolbar = QuillToolbar.basic(
151155
controller: _controller!,
152-
// provide a callback to enable picking images from device.
153-
// if omit, "image" button only allows adding images from url.
154-
// same goes for videos.
155-
onImagePickCallback: _onImagePickCallback,
156-
onVideoPickCallback: _onVideoPickCallback,
157-
// uncomment to provide a custom "pick from" dialog.
158-
// mediaPickSettingSelector: _selectMediaPickSetting,
159-
// uncomment to provide a custom "pick from" dialog.
160-
// cameraPickSettingSelector: _selectCameraPickSetting,
156+
embedButtons: FlutterQuillEmbeds.buttons(
157+
// provide a callback to enable picking images from device.
158+
// if omit, "image" button only allows adding images from url.
159+
// same goes for videos.
160+
onImagePickCallback: _onImagePickCallback,
161+
onVideoPickCallback: _onVideoPickCallback,
162+
// uncomment to provide a custom "pick from" dialog.
163+
// mediaPickSettingSelector: _selectMediaPickSetting,
164+
// uncomment to provide a custom "pick from" dialog.
165+
// cameraPickSettingSelector: _selectCameraPickSetting,
166+
),
161167
showAlignmentButtons: true,
162168
);
163169
if (kIsWeb) {
164170
toolbar = QuillToolbar.basic(
165171
controller: _controller!,
166-
onImagePickCallback: _onImagePickCallback,
167-
webImagePickImpl: _webImagePickImpl,
172+
embedButtons: FlutterQuillEmbeds.buttons(
173+
onImagePickCallback: _onImagePickCallback,
174+
webImagePickImpl: _webImagePickImpl,
175+
),
168176
showAlignmentButtons: true,
169177
);
170178
}
171179
if (_isDesktop()) {
172180
toolbar = QuillToolbar.basic(
173181
controller: _controller!,
174-
onImagePickCallback: _onImagePickCallback,
175-
filePickImpl: openFileSystemPickerForDesktop,
182+
embedButtons: FlutterQuillEmbeds.buttons(
183+
onImagePickCallback: _onImagePickCallback,
184+
filePickImpl: openFileSystemPickerForDesktop,
185+
),
176186
showAlignmentButtons: true,
177187
);
178188
}
@@ -386,37 +396,42 @@ class _HomePageState extends State<HomePage> {
386396
controller.replaceText(index, length, block, null);
387397
}
388398
}
399+
}
389400

390-
Widget customElementsEmbedBuilder(
391-
BuildContext context,
392-
QuillController controller,
393-
CustomBlockEmbed block,
394-
bool readOnly,
395-
void Function(GlobalKey videoContainerKey)? onVideoInit,
396-
) {
397-
switch (block.type) {
398-
case 'notes':
399-
final notes = NotesBlockEmbed(block.data).document;
400-
401-
return Material(
402-
color: Colors.transparent,
403-
child: ListTile(
404-
title: Text(
405-
notes.toPlainText().replaceAll('\n', ' '),
406-
maxLines: 3,
407-
overflow: TextOverflow.ellipsis,
408-
),
409-
leading: const Icon(Icons.notes),
410-
onTap: () => _addEditNote(context, document: notes),
411-
shape: RoundedRectangleBorder(
412-
borderRadius: BorderRadius.circular(10),
413-
side: const BorderSide(color: Colors.grey),
414-
),
415-
),
416-
);
417-
default:
418-
return const SizedBox();
419-
}
401+
class NotesEmbedBuilder implements EmbedBuilder {
402+
NotesEmbedBuilder({required this.addEditNote});
403+
404+
Future<void> Function(BuildContext context, {Document? document}) addEditNote;
405+
406+
@override
407+
String get key => 'notes';
408+
409+
@override
410+
Widget build(
411+
BuildContext context,
412+
QuillController controller,
413+
Embed node,
414+
bool readOnly,
415+
void Function(GlobalKey<State<StatefulWidget>> videoContainerKey)?
416+
onVideoInit) {
417+
final notes = NotesBlockEmbed(node.value.data).document;
418+
419+
return Material(
420+
color: Colors.transparent,
421+
child: ListTile(
422+
title: Text(
423+
notes.toPlainText().replaceAll('\n', ' '),
424+
maxLines: 3,
425+
overflow: TextOverflow.ellipsis,
426+
),
427+
leading: const Icon(Icons.notes),
428+
onTap: () => addEditNote(context, document: notes),
429+
shape: RoundedRectangleBorder(
430+
borderRadius: BorderRadius.circular(10),
431+
side: const BorderSide(color: Colors.grey),
432+
),
433+
),
434+
);
420435
}
421436
}
422437

example/lib/pages/read_only_page.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/foundation.dart';
22
import 'package:flutter/material.dart';
33
import 'package:flutter_quill/flutter_quill.dart' hide Text;
4+
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
45

56
import '../universal_ui/universal_ui.dart';
67
import '../widgets/demo_scaffold.dart';
@@ -38,6 +39,7 @@ class _ReadOnlyPageState extends State<ReadOnlyPage> {
3839
readOnly: !_edit,
3940
expands: false,
4041
padding: EdgeInsets.zero,
42+
embedBuilders: FlutterQuillEmbeds.builders,
4143
);
4244
if (kIsWeb) {
4345
quillEditor = QuillEditor(
@@ -49,7 +51,7 @@ class _ReadOnlyPageState extends State<ReadOnlyPage> {
4951
readOnly: !_edit,
5052
expands: false,
5153
padding: EdgeInsets.zero,
52-
embedBuilder: defaultEmbedBuilderWeb);
54+
embedBuilders: defaultEmbedBuildersWeb);
5355
}
5456
return Padding(
5557
padding: const EdgeInsets.all(8),

0 commit comments

Comments
 (0)