feat: integrate divider, code block, and math equation into appflowy

This commit is contained in:
Lucas.Xu 2022-12-01 19:26:00 +08:00
parent 4fa2d6dc2e
commit c6c164d347
5 changed files with 68 additions and 18 deletions

View File

@ -1,8 +1,8 @@
import 'package:app_flowy/plugins/document/editor_styles.dart'; import 'package:app_flowy/plugins/document/editor_styles.dart';
import 'package:app_flowy/plugins/document/presentation/plugins/horizontal_rule_node_widget.dart';
import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/plugins/document/presentation/banner.dart'; import 'package:app_flowy/plugins/document/presentation/banner.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_infra_ui/widget/error_page.dart';
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -101,10 +101,28 @@ class _DocumentPageState extends State<DocumentPage> {
editorState: editorState, editorState: editorState,
autoFocus: editorState.document.isEmpty, autoFocus: editorState.document.isEmpty,
customBuilders: { customBuilders: {
'horizontal_rule': HorizontalRuleWidgetBuilder(), // Divider
kDividerType: DividerWidgetBuilder(),
// Math Equation
kMathEquationType: MathEquationNodeWidgetBuidler(),
// Code Block
kCodeBlockType: CodeBlockNodeWidgetBuilder(),
}, },
shortcutEvents: [ shortcutEvents: [
insertHorizontalRule, // Divider
insertDividerEvent,
// Code Block
enterInCodeBlock,
ignoreKeysInCodeBlock,
pasteInCodeBlock,
],
selectionMenuItems: [
// Divider
dividerMenuItem,
// Math Equation
mathEquationMenuItem,
// Code Block
codeBlockMenuItem,
], ],
themeData: theme.copyWith(extensions: [ themeData: theme.copyWith(extensions: [
...theme.extensions.values, ...theme.extensions.values,

View File

@ -43,6 +43,7 @@ class __CodeBlockNodeWidgeState extends State<_CodeBlockNodeWidge>
with SelectableMixin, DefaultSelectable { with SelectableMixin, DefaultSelectable {
final _richTextKey = GlobalKey(debugLabel: kCodeBlockType); final _richTextKey = GlobalKey(debugLabel: kCodeBlockType);
final _padding = const EdgeInsets.only(left: 20, top: 30, bottom: 30); final _padding = const EdgeInsets.only(left: 20, top: 30, bottom: 30);
bool _isHover = false;
String? get _language => String? get _language =>
widget.textNode.attributes[kCodeBlockAttrLanguage] as String?; widget.textNode.attributes[kCodeBlockAttrLanguage] as String?;
String? _detectLanguage; String? _detectLanguage;
@ -59,17 +60,24 @@ class __CodeBlockNodeWidgeState extends State<_CodeBlockNodeWidge>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return InkWell(
children: [ onHover: (value) {
_buildCodeBlock(context), setState(() {
_buildSwitchCodeButton(context), _isHover = value;
_buildDeleteButton(context), });
], },
onTap: () {},
child: Stack(
children: [
_buildCodeBlock(context),
_buildSwitchCodeButton(context),
if (_isHover) _buildDeleteButton(context),
],
),
); );
} }
Widget _buildCodeBlock(BuildContext context) { Widget _buildCodeBlock(BuildContext context) {
final plainText = widget.textNode.toPlainText();
final result = highlight.highlight.parse( final result = highlight.highlight.parse(
widget.textNode.toPlainText(), widget.textNode.toPlainText(),
language: _language, language: _language,

View File

@ -168,9 +168,9 @@ class _MathEquationNodeWidgetState extends State<_MathEquationNodeWidget> {
if (key is! RawKeyDownEvent) return; if (key is! RawKeyDownEvent) return;
if (key.logicalKey == LogicalKeyboardKey.enter && if (key.logicalKey == LogicalKeyboardKey.enter &&
!key.isShiftPressed) { !key.isShiftPressed) {
_updateMathEquation(controller.text); _updateMathEquation(controller.text, context);
} else if (key.logicalKey == LogicalKeyboardKey.escape) { } else if (key.logicalKey == LogicalKeyboardKey.escape) {
_dismiss(); _dismiss(context);
} }
}, },
child: TextField( child: TextField(
@ -185,11 +185,11 @@ class _MathEquationNodeWidgetState extends State<_MathEquationNodeWidget> {
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => _dismiss(), onPressed: () => _dismiss(context),
child: const Text('Cancel'), child: const Text('Cancel'),
), ),
TextButton( TextButton(
onPressed: () => _updateMathEquation(controller.text), onPressed: () => _updateMathEquation(controller.text, context),
child: const Text('Done'), child: const Text('Done'),
), ),
], ],
@ -198,9 +198,9 @@ class _MathEquationNodeWidgetState extends State<_MathEquationNodeWidget> {
); );
} }
void _updateMathEquation(String mathEquation) { void _updateMathEquation(String mathEquation, BuildContext context) {
_dismiss();
if (mathEquation == _mathEquation) { if (mathEquation == _mathEquation) {
_dismiss(context);
return; return;
} }
final transaction = widget.editorState.transaction; final transaction = widget.editorState.transaction;
@ -211,9 +211,10 @@ class _MathEquationNodeWidgetState extends State<_MathEquationNodeWidget> {
}, },
); );
widget.editorState.apply(transaction); widget.editorState.apply(transaction);
_dismiss(context);
} }
void _dismiss() { void _dismiss(BuildContext context) {
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
} }

View File

@ -36,6 +36,13 @@ packages:
relative: true relative: true
source: path source: path
version: "0.0.7" version: "0.0.7"
appflowy_editor_plugins:
dependency: "direct main"
description:
path: "packages/appflowy_editor_plugins"
relative: true
source: path
version: "0.0.1"
appflowy_popover: appflowy_popover:
dependency: "direct main" dependency: "direct main"
description: description:
@ -471,6 +478,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_math_fork:
dependency: transitive
description:
name: flutter_math_fork
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3+1"
flutter_plugin_android_lifecycle: flutter_plugin_android_lifecycle:
dependency: transitive dependency: transitive
description: description:
@ -556,6 +570,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
highlight:
dependency: transitive
description:
name: highlight
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.0"
hotkey_manager: hotkey_manager:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1402,5 +1423,5 @@ packages:
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=2.17.0 <3.0.0" dart: ">=2.17.6 <3.0.0"
flutter: ">=3.0.0" flutter: ">=3.0.0"

View File

@ -91,6 +91,8 @@ dependencies:
google_fonts: ^3.0.1 google_fonts: ^3.0.1
file_picker: <=5.0.0 file_picker: <=5.0.0
percent_indicator: ^4.0.1 percent_indicator: ^4.0.1
appflowy_editor_plugins:
path: packages/appflowy_editor_plugins
dev_dependencies: dev_dependencies:
flutter_lints: ^2.0.1 flutter_lints: ^2.0.1