chore: bump version 1.1.0 (#284)

This commit is contained in:
Lucas.Xu 2023-07-04 14:07:23 +08:00 • committed by GitHub
commit bb3771af63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 100 additions and 129 deletions

View file

@ -1,3 +1,20 @@
## 1.1.0
* feat: support IME by @LucasXu0 in ([#253](https://github.com/AppFlowy-IO/appflowy-editor/pull/253))
* feat: support text and background color in mobile toolbar by @hyj1204 in ([#233](https://github.com/AppFlowy-IO/appflowy-editor/pull/233))
* feat: support broadcast the transaction before applying it by @LucasXu0 in ([#226](https://github.com/AppFlowy-IO/appflowy-editor/pull/226))
* feat: support customizing text attribute key and rendering by @LucasXu0 in ([#244](https://github.com/AppFlowy-IO/appflowy-editor/pull/244))
* feat: support customizing the block icon widget by @LucasXu0 in ([#274](https://github.com/AppFlowy-IO/appflowy-editor/pull/274))
* feat: support uploading images from local files by @Mukund-Tandon in ([#232](https://github.com/AppFlowy-IO/appflowy-editor/pull/232))
* feat: add underline syntax parser by @vedant-pandey in ([#256](https://github.com/AppFlowy-IO/appflowy-editor/pull/256))
* feat: migrate the delta encoder by @LucasXu0 in ([#277](https://github.com/AppFlowy-IO/appflowy-editor/pull/277))
* feat: support divider toolbar item in mobile by @hyj1204 in ([#281](https://github.com/AppFlowy-IO/appflowy-editor/pull/281))
* feat: customized color options by @hyj1204 in ([#270](https://github.com/AppFlowy-IO/appflowy-editor/pull/270))
* feat: support exiting link menu by ESC by @vincenzoursano in ([#124](https://github.com/AppFlowy-IO/appflowy-editor/pull/124))
* fix: focus node doesn't work on mobile by @LucasXu0 in ([#227](https://github.com/AppFlowy-IO/appflowy-editor/pull/227))
* fix: the cursor is inaccuracy when the text contains special emoji by @LucasXu0 in ([#238](https://github.com/AppFlowy-IO/appflowy-editor/pull/238))
* fix: extend attribute keys shouldn't be sliced by @LucasXu0 in ([#248](https://github.com/AppFlowy-IO/appflowy-editor/pull/248))
* fix: keep keyboard appearance as same brightness as system theme by @hyj1204 in ([#264](https://github.com/AppFlowy-IO/appflowy-editor/pull/264))
## 1.0.4
* feat: support mobile drag selection by @LucasXu0 in ([#209](https://github.com/AppFlowy-IO/appflowy-editor/pull/209))
* feat: support customizing number of the numbered list by @LucasXu0 in ([#219](https://github.com/AppFlowy-IO/appflowy-editor/pull/219))

View file

@ -33,12 +33,13 @@ and the Flutter guide for
## Key Features
* Build rich, intuitive editors
* Design and modify an ever expanding list of customizable features including
* components (such as form input controls, numbered lists, and rich text widgets)
* Design and modify an ever-expanding list of customizable features including
* block components (such as form input controls, numbered lists, and rich text widgets)
* shortcut events
* themes
* menu options (**coming soon!**)
* [Test-coverage](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/testing.md) and ongoing maintenance by AppFlowy's core team and community of more than 1,000 builders
* selection menu
* toolbar menu
* [Test Coverage](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/testing.md) and ongoing maintenance by AppFlowy's core team and community of more than 1,000 builders
## Getting Started
@ -54,8 +55,8 @@ flutter pub get
Start by creating a new empty AppFlowyEditor object.
```dart
final editorState = EditorState.empty(); // an empty state
final editor = AppFlowyEditor(
final editorState = EditorState.blank(withInitialText: true); // with an empty paragraph
final editor = AppFlowyEditor.standard(
editorState: editorState,
);
```
@ -63,9 +64,9 @@ final editor = AppFlowyEditor(
You can also create an editor from a JSON object in order to configure your initial state. Or you can [create an editor from Markdown or Quill Delta](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/importing.md).
```dart
final json = ...;
final editorState = EditorState(Document.fromJson(data));
final editor = AppFlowyEditor(
final json = jsonDecode('YOUR INPUT JSON STRING');
final editorState = EditorState(document: Document.fromJson(json));
final editor = AppFlowyEditor.standard(
editorState: editorState,
);
```
@ -89,15 +90,15 @@ flutter run
## Customizing Your Editor
### Customizing Components
### Customizing Block Components
Please refer to our documentation on customizing AppFlowy for a detailed discussion about [customizing components](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/customizing.md#customize-a-component).
Below are some examples of component customizations:
* [Checkbox Text](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/render/rich_text/checkbox_text.dart) demonstrates how to extend new styles based on existing rich text components
* [Image](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/example/lib/plugin/network_image_node_widget.dart) demonstrates how to extend a new node and render it
* See further examples of [rich-text plugins](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/render/rich_text)
* [Todo List Block Component](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/editor/block_component/todo_list_block_component/todo_list_block_component.dart) demonstrates how to extend new styles based on existing rich text components
* [Divider Block Component](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/editor/block_component/divider_block_component/divider_block_component.dart) demonstrates how to extend a new block component and render it
* See further examples of [Rich-Text Plugins](https://github.com/AppFlowy-IO/appflowy-editor/tree/main/lib/src/editor/block_component)
### Customizing Shortcut Events
@ -105,9 +106,8 @@ Please refer to our documentation on customizing AppFlowy for a detailed discuss
Below are some examples of shortcut event customizations:
* [BIUS](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/service/internal_key_event_handlers/format_style_handler.dart) demonstrates how to make text bold/italic/underline/strikethrough through shortcut keys
* [Paste HTML](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart) gives you an idea on how to handle pasted styles through shortcut keys
* Need more examples? Check out [Internal key event handlers](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/service/internal_key_event_handlers)
* [BIUS](https://github.com/AppFlowy-IO/appflowy-editor/tree/main/lib/src/editor/editor_component/service/shortcuts/character_shortcut_events/format_single_character) demonstrates how to make text bold/italic/underline/strikethrough through shortcut keys
* Need more examples? Check out [shortcuts](https://github.com/AppFlowy-IO/appflowy-editor/tree/main/lib/src/editor/editor_component/service/shortcuts)
## Glossary
Please refer to the API documentation.

View file

@ -1,7 +1,5 @@
# Customizing Editor Features
Note: `AppFlowyEditor` has since been depreciated and `AppFlowyEditor.standard` or `AppFlowyEditor.custom` should be used instead. To recreate the examples below, you would use `AppFlowyEditor.custom`.
## Customizing a Shortcut Event
We will use a simple example to illustrate how to quickly add a shortcut event.
@ -11,137 +9,90 @@ In this example, text that starts and ends with an underscore ( \_ ) character w
Let's start with a blank document:
```dart
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
class UnderScoreToItalic extends StatelessWidget {
const UnderScoreToItalic({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.topCenter,
child: AppFlowyEditor(
editorState: EditorState.empty(),
shortcutEvents: const [],
customBuilders: const {},
),
),
return AppFlowyEditor.custom(
editorState: EditorState.blank(withInitialText: true),
blockComponentBuilders: standardBlockComponentBuilderMap,
characterShortcutEvents: const [],
);
}
}
```
At this point, nothing magic will happen after typing `_xxx_`.
![Before](./images/customize_a_shortcut_event_before.gif)
To implement our shortcut event we will create a `ShortcutEvent` instance to handle an underscore input.
To implement our shortcut event we will create a `CharacterShortcutEvent` instance to handle an underscore input.
We need to define `key` and `command` in a ShortCutEvent object to customize hotkeys. We recommend using the description of your event as a key. For example, if the underscore `_` is defined to make text italic, the key can be 'Underscore to italic'.
We need to define `key` and `character` in a `CharacterShortcutEvent` object to customize hotkeys. We recommend using the description of your event as a key. For example, if the underscore `_` is defined to make text italic, the key can be 'Underscore to italic'.
> The command, made up of a single keyword such as `underscore` or a combination of keywords using the `+` sign in between to concatenate, is a condition that triggers a user-defined function. To see which keywords are available to define a command, please refer to [key_mapping.dart](../lib/src/service/shortcut_event/key_mapping.dart).
> If more than one commands trigger the same handler, then we use ',' to split them. For example, using CTRL and A or CMD and A to 'select all', we describe it as `cmd+a,ctrl+a`(case-insensitive).
```dart
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
ShortcutEvent underscoreToItalicEvent = ShortcutEvent(
// ...
CharacterShortcutEvent underscoreToItalicEvent = CharacterShortcutEvent(
key: 'Underscore to italic',
command: 'shift+underscore',
handler: _underscoreToItalicHandler,
);
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
};
```
Then, we need to determine if the currently selected node is a `TextNode` and if the selection is collapsed.
If so, we will continue.
```dart
// ...
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
// Obtain the selection and selected nodes of the current document through the 'selectionService'
// to determine whether the selection is collapsed and whether the selected node is a text node.
final selectionService = editorState.service.selectionService;
final selection = selectionService.currentSelection.value;
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
if (selection == null || !selection.isSingle || textNodes.length != 1) {
return KeyEventResult.ignored;
}
```
Now, we deal with handling the underscore.
Look for the position of the previous underscore and
1. if one is _not_ found, return without doing anything.
2. if one is found, the text enclosed within the two underscores will be formatted to display in italics.
```dart
// ...
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
// ...
final textNode = textNodes.first;
final text = textNode.toRawString();
// Determine if an 'underscore' already exists in the text node and only once.
final firstUnderscore = text.indexOf('_');
final lastUnderscore = text.lastIndexOf('_');
if (firstUnderscore == -1 ||
firstUnderscore != lastUnderscore ||
firstUnderscore == selection.start.offset - 1) {
return KeyEventResult.ignored;
}
// Delete the previous 'underscore',
// update the style of the text surrounded by the two underscores to 'italic',
// and update the cursor position.
final transaction = editorState.transaction
..deleteText(textNode, firstUnderscore, 1)
..formatText(
textNode,
firstUnderscore,
selection.end.offset - firstUnderscore - 1,
{
BuiltInAttributeKey.italic: true,
},
)
..afterSelection = Selection.collapsed(
Position(
path: textNode.path,
offset: selection.end.offset - 1,
character: '_',
handler: (editorState) async => handleFormatByWrappingWithSingleCharacter(
editorState: editorState,
character: '_',
formatStyle: FormatStyleByWrappingWithSingleChar.italic,
),
);
editorState.apply(transaction);
return KeyEventResult.handled;
};
```
Now our 'underscore handler' function is done and the only task left is to inject it into the AppFlowyEditor.
```dart
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
class UnderScoreToItalic extends StatelessWidget {
const UnderScoreToItalic({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.topCenter,
child: AppFlowyEditor(
editorState: EditorState.empty(),
customBuilders: const {},
shortcutEvents: [
underscoreToItalic,
return AppFlowyEditor.custom(
editorState: EditorState.blank(withInitialText: true),
blockComponentBuilders: standardBlockComponentBuilderMap,
characterShortcutEvents: [
underScoreToItalicEvent,
],
),
),
);
}
}
CharacterShortcutEvent underScoreToItalicEvent = CharacterShortcutEvent(
key: 'Underscore to italic',
character: '_',
handler: (editorState) async => handleFormatByWrappingWithSingleCharacter(
editorState: editorState,
character: '_',
formatStyle: FormatStyleByWrappingWithSingleChar.italic,
),
);
```
![After](./images/customize_a_shortcut_event_after.gif)
Check out the [complete code](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart) file of this example.
Check out the [complete code](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/example/lib/samples/underscore_to_italic.dart) file of this example.
## Customizing a Component
> ⚠️ Notes: The content below is outdated.
We will use a simple example to show how to quickly add a custom component.
In this example we will render an image from the network.

View file

@ -78,7 +78,7 @@ bool handleFormatByWrappingWithSingleCharacter({
// if the text is already formatted, we should remove the format.
final sliced = delta.slice(
headCharIndex + 1,
selection.end.offset - headCharIndex - 1,
selection.end.offset,
);
final result = sliced.everyAttributes((element) => element[style] == true);

View file

@ -1,6 +1,6 @@
name: appflowy_editor
description: A highly customizable rich-text editor for Flutter. The AppFlowy Editor project for AppFlowy and beyond.
version: 1.0.4
version: 1.1.0
homepage: https://github.com/AppFlowy-IO/appflowy-editor
platforms:

View file

@ -5,7 +5,7 @@ import '../../../../new/infra/testable_editor.dart';
import '../test_helpers/mobile_app_with_toolbar_widget.dart';
void main() {
group('dividerMobileToolbarItem\n', () {
group('dividerMobileToolbarItem', () {
testWidgets(
'If the user tries to insert a divider while some text is selected, no action should be taken',
(WidgetTester tester) async {

View file

@ -150,9 +150,12 @@ void main() async {
expect(result, true);
final after = editorState.getNodeAtPath([0])!;
expect(after.delta!.toPlainText(), '$text1$text2');
expect(after.delta!.toList()[0].attributes, null);
expect(after.delta!.toList()[1].attributes, {'italic': true});
final afterDelta = after.delta!;
expect(afterDelta.toPlainText(), '$text1$text2');
final deltaList = afterDelta.toList();
expect(deltaList.length, 2);
expect(deltaList[0].attributes, null);
expect(deltaList[1].attributes, {'italic': true});
});
// Before