Skip to content

Commit 1657e45

Browse files
committed
feat: Adding migraiton guide. #3
1 parent f96e0d2 commit 1657e45

File tree

1 file changed

+375
-1
lines changed

1 file changed

+375
-1
lines changed

Diff for: _visual-editor/README.md

+375-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,375 @@
1-
# migraiton to visual studio
1+
# Migrating `flutter-quill` to `visual-editor`
2+
3+
> [!WARNING]
4+
>
5+
> At the time of writing,
6+
> `visual-editor` is still in development and **does not offer all the features `flutter-quill` offers**.
7+
> There are a few bugs that are noticeable (more specifically, text selection)
8+
> that do not work properly on mobile devices.
9+
>
10+
> We will make a migration to a **fork of `visual-editor`** - https://github.com/LuchoTurtle/visual-editor.
11+
> This is because the PR that was opened to `visual-editor` has need yet been merged
12+
> (https://github.com/visual-space/visual-editor/pull/237).
13+
> Once it is merged and this document has yet to be updated,
14+
> [please open an issue](https://github.com/dwyl/flutter-wysiwyg-editor-tutorial/issues/).
15+
16+
17+
[`visual-editor`](https://github.com/visual-space/visual-editor) is a fork of `flutter-quill` that,
18+
unlike the latter,
19+
is actively maintained.
20+
They've done a complete refactor of `flutter-quill`,
21+
documented the code and made it easier to contribute to.
22+
Because it offers some new features that can be easily integrated into your app,
23+
we've created this small migration guide so you can leverage this library
24+
from the app you've just implemented with `flutter-quill`.
25+
26+
> [!NOTE]
27+
>
28+
> `visual-editor` provides a migration guide.
29+
> Check it in https://github.com/visual-space/visual-editor.
30+
31+
32+
# 0. Pre-requisites
33+
34+
This guide builds upon the app that was created in
35+
[`README.md`](../README.md).
36+
Make sure you have completed the tutorial first
37+
and head back here so the code is in the same state.
38+
39+
40+
# 1. Install dependencies
41+
42+
Head over to `pubspec.yaml`
43+
and change the `dependencies` section to the following.
44+
45+
```yaml
46+
dependencies:
47+
flutter:
48+
sdk: flutter
49+
50+
file_picker: ^5.3.3
51+
universal_io: ^2.2.2
52+
responsive_framework: ^1.1.0
53+
universal_html: ^2.2.3
54+
path: ^1.8.3
55+
path_provider: ^2.1.0
56+
http: ^1.1.0
57+
mime: ^1.0.4
58+
http_parser: ^4.0.2
59+
60+
visual_editor:
61+
git:
62+
url: https://github.com/LuchoTurtle/visual-editor.git
63+
ref: update_dependencies#236
64+
```
65+
66+
- we've removed `flutter_quill` and `flutter_quill_extensions`.
67+
- we've upgraded `http` to version `1.1.0`.
68+
- we've installed `visual_editor` through the aforementioned fork.
69+
Normally you'll follow the guidelines in [`visual_editor`](https://github.com/visual-space/visual-editor#getting-started).
70+
71+
72+
# 2. Delete `web_embeds`
73+
74+
With `visual-editor`, we do not need to use separate web embeds
75+
to make it work on the web.
76+
So you can safely delete 🗑️
77+
`mobile_platform_registry.dart`,
78+
`web_embeds.dart`
79+
and `web_platform_registry.dart`,
80+
as they no longer will be needed.
81+
82+
83+
# 3. Update import, rename classes and delete unnecessary code
84+
85+
The classes from `visual_editor`,
86+
although similar to `flutter-quill`,
87+
have different constructors and some will differ,
88+
so renaming classes won't work sometimes.
89+
90+
But let's do that first!
91+
We'll deal with each issue along the way.
92+
Let's start with replacing the imports.
93+
Change the imports like so:
94+
95+
`import 'package:flutter_quill/flutter_quill.dart';` -> `import 'package:visual_editor/visual-editor.dart';`
96+
97+
Add `import 'package:visual_editor/document/models/attributes/attributes.model.dart';`, as well.
98+
We are going to need it.
99+
100+
You can now delete any `flutter_quill` and `flutter_quill_extensions` import.
101+
You can also delete `import 'web_embeds/web_embeds.dart';`,
102+
since it no longer exists.
103+
104+
Now, it's time to rename some classes!
105+
Follow the next steps.
106+
107+
`QuillEditor` -> `VisualEditor`
108+
`QuillController` -> `EditorController`
109+
`QuillToolbar` -> `EditorToolbar`
110+
`DefaultTextBlockStyle` -> `TextBlockStyleM`
111+
`DefaultStyles` -> `EditorStylesM`
112+
`Document` -> `DeltaDocM`
113+
114+
Awesome!
115+
116+
The last thing we need to do is
117+
deleting our `_SelectionType` methods and classes.
118+
We have used these to handle the triple click selection behaviour
119+
on tap up.
120+
We don't need this any more.
121+
122+
Therefore:
123+
- delete the `_SelectionType` enum.
124+
- delete `_SelectionType _selectionType = _SelectionType.none;` field from `HomePageState`.
125+
- delete the `_onTripleClickSelection()` function inside `HomePageState`.
126+
127+
Great job! 🥳
128+
129+
We are now ready to
130+
change how our `visual-editor` classes are constructed!
131+
132+
133+
# 4. Update `visual-editor` classes invocations
134+
135+
**From now on, we'll only be working inside the `HomePageState` class.**
136+
137+
Let's start by changing our `_initializeText` function.
138+
`EditorController` now only receives one argument,
139+
which is the `document`.
140+
Change it to look like so:
141+
142+
```dart
143+
Future<void> _initializeText() async {
144+
final doc = DeltaDocM();
145+
setState(() {
146+
_controller = EditorController(
147+
document: doc,
148+
);
149+
});
150+
}
151+
```
152+
153+
154+
## 4.1 `VisualEditor`
155+
156+
Let's move to the `VisualEditor`.
157+
We previously used `QuillEditor`,
158+
where we had a myriad of parameters we set.
159+
These parameters *are now more organised*,
160+
and will be changed like so.
161+
162+
```dart
163+
Widget quillEditor = VisualEditor(
164+
controller: _controller!,
165+
scrollController: ScrollController(),
166+
focusNode: _focusNode,
167+
config: EditorConfigM(
168+
scrollable: true,
169+
autoFocus: false,
170+
readOnly: false,
171+
placeholder: 'Write what\'s on your mind.',
172+
enableInteractiveSelection: true,
173+
expands: false,
174+
padding: EdgeInsets.zero,
175+
customStyles: const EditorStylesM(
176+
h1: TextBlockStyleM(
177+
TextStyle(
178+
fontSize: 32,
179+
color: Colors.black,
180+
height: 1.15,
181+
fontWeight: FontWeight.w300,
182+
),
183+
VerticalSpacing(top: 16, bottom: 0),
184+
VerticalSpacing(top: 0, bottom: 0),
185+
VerticalSpacing(top: 16, bottom: 0),
186+
null,
187+
),
188+
sizeSmall: TextStyle(fontSize: 9),
189+
),
190+
),
191+
);
192+
```
193+
194+
As you can see, most of the configuration
195+
is now done under the `config` parameter,
196+
which receives an `EditorConfigM`.
197+
198+
- `enableSelectionToolbar` becomes `enableInteractiveSelection`.
199+
- we define the `customStyles` with the `EditorStyleM` class.
200+
In this case, we are defining the `h1` field with `TextBlockStyleM` class,
201+
which has also changed.
202+
- `TextBlockStyleM` has an additional parameter, where you will need to define 4 arguments, instead of 3.
203+
The added argument pertains to `lastLineSpacing`, the spacing at the end of the text block.
204+
We've just added a `VerticalSpacing(top: 16, bottom: 0)`
205+
- we can't set the `subscript` and `superscript` fields in `EditorStylesM` (previously `DefaultStyles`),
206+
as they're not yet available.
207+
- we've also removed the `onTapUp` callback field,
208+
as we no longer need it.
209+
210+
In the same file,
211+
we've re-defined `quillEditor` if it was in a web platform.
212+
Let's update that as well.
213+
It now becomes the following:
214+
215+
```dart
216+
// Alternatively, the web editor version is shown (with the web embeds)
217+
if (widget.platformService.isWebPlatform()) {
218+
quillEditor = VisualEditor(
219+
controller: _controller!,
220+
scrollController: ScrollController(),
221+
focusNode: _focusNode,
222+
config: EditorConfigM(
223+
scrollable: true,
224+
enableInteractiveSelection: false,
225+
autoFocus: false,
226+
readOnly: false,
227+
placeholder: 'Add content',
228+
expands: false,
229+
padding: EdgeInsets.zero,
230+
customStyles: const EditorStylesM(
231+
h1: TextBlockStyleM(
232+
TextStyle(
233+
fontSize: 32,
234+
color: Colors.black,
235+
height: 1.15,
236+
fontWeight: FontWeight.w300,
237+
),
238+
VerticalSpacing(top: 16, bottom: 0),
239+
VerticalSpacing(top: 0, bottom: 0),
240+
VerticalSpacing(top: 16, bottom: 0),
241+
null,
242+
),
243+
sizeSmall: TextStyle(fontSize: 9),
244+
),
245+
),
246+
);
247+
}
248+
```
249+
250+
## 4.2 `EditorToolbar`
251+
252+
`QuillToolbar` now becomes `EditorToolbar`.
253+
With `flutter-quill`,
254+
we used `FlutterQuillEmbeds.buttons` and appended these custom embed buttons
255+
this to the toolbar's children.
256+
257+
**This is not the case in `visual-editor`.**
258+
259+
You will simply list the buttons in the `customButton` field
260+
and add the necessary callbacks (like `webImagePickImpl` or `onImagePickCallback`, for example) to the relevant buttons.
261+
You can also use the `children` field to enforce a custom order,
262+
feeding the list straight to `EditorToolbar`'s constructor.
263+
However, in this case, it's almost pointless to use this field as it does not provide much functionality on top of the customs buttons set.
264+
265+
Let's add our buttons to the toolbar, then!
266+
Locate the `toolbar` variable,
267+
and change it.
268+
269+
```dart
270+
// Toolbar definitions
271+
const toolbarIconSize = 18.0;
272+
const toolbarButtonSpacing = 2.5;
273+
274+
// Instantiating the toolbar
275+
final toolbar = EditorToolbar(
276+
children: [
277+
HistoryButton(
278+
buttonsSpacing: toolbarButtonSpacing,
279+
icon: Icons.undo_outlined,
280+
iconSize: toolbarIconSize,
281+
controller: _controller!,
282+
isUndo: true,
283+
),
284+
HistoryButton(
285+
buttonsSpacing: toolbarButtonSpacing,
286+
icon: Icons.redo_outlined,
287+
iconSize: toolbarIconSize,
288+
controller: _controller!,
289+
isUndo: false,
290+
),
291+
ToggleStyleButton(
292+
buttonsSpacing: toolbarButtonSpacing,
293+
attribute: AttributesM.bold,
294+
icon: Icons.format_bold,
295+
iconSize: toolbarIconSize,
296+
controller: _controller!,
297+
),
298+
ToggleStyleButton(
299+
buttonsSpacing: toolbarButtonSpacing,
300+
attribute: AttributesM.italic,
301+
icon: Icons.format_italic,
302+
iconSize: toolbarIconSize,
303+
controller: _controller!,
304+
),
305+
ToggleStyleButton(
306+
buttonsSpacing: toolbarButtonSpacing,
307+
attribute: AttributesM.underline,
308+
icon: Icons.format_underline,
309+
iconSize: toolbarIconSize,
310+
controller: _controller!,
311+
),
312+
ToggleStyleButton(
313+
buttonsSpacing: toolbarButtonSpacing,
314+
attribute: AttributesM.strikeThrough,
315+
icon: Icons.format_strikethrough,
316+
iconSize: toolbarIconSize,
317+
controller: _controller!,
318+
),
319+
320+
// Our embed buttons
321+
ImageButton(
322+
icon: Icons.image,
323+
iconSize: toolbarIconSize,
324+
buttonsSpacing: toolbarButtonSpacing,
325+
controller: _controller!,
326+
onImagePickCallback: _onImagePickCallback,
327+
webImagePickImpl: _webImagePickImpl,
328+
mediaPickSettingSelector: (context) {
329+
return Future.value(MediaPickSettingE.Gallery);
330+
},
331+
),
332+
],
333+
);
334+
```
335+
336+
Here's a list of relevant changes we've made:
337+
338+
- removed `FlutterQuillEmbeds.buttons` - we don't need to use `FlutterQuillEmbeds` to create embed buttons any more.
339+
We simply create them normally in the children field.
340+
- removed the `afterButtonPressed` field from `EditorToolbar` constructor.
341+
- added `buttonsSpacing` field to all buttons, as it's required.
342+
- `Attribute` is now renamed to `AttributesM`
343+
(which is why we imported it in the beginning of this guide).
344+
- `MediaPickSetting` is now renamed to `MediaPickSettingE`.
345+
346+
347+
Each button we add needs to have the `buttonsSpacing` field defined.
348+
But now can simply define our array of buttons,
349+
display them in the order we like,
350+
and not have to worry about web embeds or anything like that!
351+
All the necessary callbacks (like `onImagePickCallback`)
352+
are related to relevant buttons (`CameraButton`, for example).
353+
So we don't add this behaviour to the definition of the `toolbar`,
354+
but **to the adequate button**.
355+
Much simpler, right?
356+
357+
358+
# 5. Changing tests
359+
360+
Let's fix the compiling errors on our tests.
361+
Luckily, it's simple.
362+
Just change the imports like we've done at the beginning of this guide,
363+
and replace `QuillEditor` with `VisualEditor`
364+
(and other necessary classes).
365+
366+
The method `tester.quillEnterText()` no longer exists,
367+
so you can safely delete it.
368+
369+
370+
# 6. You're done! 🎉
371+
372+
Congratulations, you've successfully migrated
373+
the app from `flutter-quill` to `visual-editor`!
374+
375+
Give yourself a pat on the back! 👏

0 commit comments

Comments
 (0)