fix: unable to cancel the inline math equation format (#2974)

* fix: unable to cancel the inline math equation format

* fix: bold font style used in the document is not suitable

* chore: add flutter clean before executing the release task

* fix: integration test
This commit is contained in:
Lucas.Xu 2023-07-11 18:49:29 +07:00 committed by GitHub
parent 409e3bf1e3
commit b9976b072e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 136 additions and 39 deletions

View File

@ -61,5 +61,61 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
}); });
testWidgets('remove the inline math equation format', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
// create a new document
await tester.createNewPageWithName(
ViewLayoutPB.Document,
LocaleKeys.document_plugins_createInlineMathEquation.tr(),
);
// tap the first line of the document
await tester.editor.tapLineOfEditorAt(0);
// insert a inline page
const formula = 'E = MC ^ 2';
await tester.ime.insertText(formula);
await tester.editor.updateSelection(
Selection.single(path: [0], startOffset: 0, endOffset: formula.length),
);
// tap the inline math equation button
var inlineMathEquationButton = find.byTooltip(
LocaleKeys.document_plugins_createInlineMathEquation.tr(),
);
await tester.tapButton(inlineMathEquationButton);
// expect to see the math equation block
var inlineMathEquation = find.byType(InlineMathEquation);
expect(inlineMathEquation, findsOneWidget);
// highlight the math equation block
await tester.editor.updateSelection(
Selection.single(path: [0], startOffset: 0, endOffset: 1),
);
// expect to the see the inline math equation button is highlighted
inlineMathEquationButton = find.byWidgetPredicate(
(widget) =>
widget is IconItemWidget &&
widget.tooltip ==
LocaleKeys.document_plugins_createInlineMathEquation.tr(),
);
expect(
tester.widget<IconItemWidget>(inlineMathEquationButton).isHighlight,
isTrue,
);
// cancel the format
await tester.tapButton(inlineMathEquationButton);
// expect to see the math equation block is removed
inlineMathEquation = find.byType(InlineMathEquation);
expect(inlineMathEquation, findsNothing);
tester.expectToSeeText(formula);
});
}); });
} }

View File

@ -17,7 +17,8 @@ void main() {
setUpAll(() async => await service.setUpAll()); setUpAll(() async => await service.setUpAll());
setUp(() async => await service.setUp()); setUp(() async => await service.setUp());
testWidgets('testing selection on open-ai smart menu replace', (tester) async { testWidgets('testing selection on open-ai smart menu replace',
(tester) async {
final appFlowyEditor = await setUpOpenAITesting(tester); final appFlowyEditor = await setUpOpenAITesting(tester);
final editorState = appFlowyEditor.editorState; final editorState = appFlowyEditor.editorState;
@ -38,7 +39,8 @@ void main() {
await tester.tap(find.text('Summarize')); await tester.tap(find.text('Summarize'));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await tester.tap(find.byType(FlowyRichTextButton, skipOffstage: false).first); await tester
.tap(find.byType(FlowyRichTextButton, skipOffstage: false).first);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect( expect(
@ -49,7 +51,8 @@ void main() {
), ),
); );
}); });
testWidgets('testing selection on open-ai smart menu insert', (tester) async { testWidgets('testing selection on open-ai smart menu insert',
(tester) async {
final appFlowyEditor = await setUpOpenAITesting(tester); final appFlowyEditor = await setUpOpenAITesting(tester);
final editorState = appFlowyEditor.editorState; final editorState = appFlowyEditor.editorState;
@ -69,7 +72,8 @@ void main() {
await tester.tap(find.text('Summarize')); await tester.tap(find.text('Summarize'));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await tester.tap(find.byType(FlowyRichTextButton, skipOffstage: false).at(1)); await tester
.tap(find.byType(FlowyRichTextButton, skipOffstage: false).at(1));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect( expect(

View File

@ -32,7 +32,7 @@ class EditorOperations {
/// Tap the line of editor at [index] /// Tap the line of editor at [index]
Future<void> tapLineOfEditorAt(int index) async { Future<void> tapLineOfEditorAt(int index) async {
final textBlocks = find.byType(FlowyRichText); final textBlocks = find.byType(AppFlowyRichText);
index = index.clamp(0, textBlocks.evaluate().length - 1); index = index.clamp(0, textBlocks.evaluate().length - 1);
await tester.tapAt(tester.getTopRight(textBlocks.at(index))); await tester.tapAt(tester.getTopRight(textBlocks.at(index)));
await tester.pumpAndSettle(); await tester.pumpAndSettle();

View File

@ -126,7 +126,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
final (bool autoFocus, Selection? selection) = final (bool autoFocus, Selection? selection) =
_computeAutoFocusParameters(); _computeAutoFocusParameters();
final editor = AppFlowyEditor.custom( final editor = AppFlowyEditor(
editorState: widget.editorState, editorState: widget.editorState,
editable: true, editable: true,
shrinkWrap: widget.shrinkWrap, shrinkWrap: widget.shrinkWrap,

View File

@ -105,7 +105,7 @@ class CalloutBlockComponentWidget extends BlockComponentStatefulWidget {
class _CalloutBlockComponentWidgetState class _CalloutBlockComponentWidgetState
extends State<CalloutBlockComponentWidget> extends State<CalloutBlockComponentWidget>
with SelectableMixin, DefaultSelectable, BlockComponentConfigurable { with SelectableMixin, DefaultSelectableMixin, BlockComponentConfigurable {
// the key used to forward focus to the richtext child // the key used to forward focus to the richtext child
@override @override
final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text'); final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text');
@ -192,7 +192,7 @@ class _CalloutBlockComponentWidgetState
Widget buildCalloutBlockComponent(BuildContext context) { Widget buildCalloutBlockComponent(BuildContext context) {
return Padding( return Padding(
padding: padding, padding: padding,
child: FlowyRichText( child: AppFlowyRichText(
key: forwardKey, key: forwardKey,
node: widget.node, node: widget.node,
editorState: editorState, editorState: editorState,

View File

@ -96,7 +96,7 @@ class CodeBlockComponentWidget extends BlockComponentStatefulWidget {
} }
class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget> class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
with SelectableMixin, DefaultSelectable, BlockComponentConfigurable { with SelectableMixin, DefaultSelectableMixin, BlockComponentConfigurable {
// the key used to forward focus to the richtext child // the key used to forward focus to the richtext child
@override @override
final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text'); final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text');
@ -216,7 +216,7 @@ class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
final codeTextSpans = _convert(codeNodes); final codeTextSpans = _convert(codeNodes);
return Padding( return Padding(
padding: widget.padding, padding: widget.padding,
child: FlowyRichText( child: AppFlowyRichText(
key: forwardKey, key: forwardKey,
node: widget.node, node: widget.node,
editorState: editorState, editorState: editorState,

View File

@ -21,7 +21,7 @@ final ToolbarItem inlineMathEquationItem = ToolbarItem(
iconBuilder: (_) => svgWidget( iconBuilder: (_) => svgWidget(
'editor/math', 'editor/math',
size: const Size.square(16), size: const Size.square(16),
color: Colors.white, color: isHighlight ? Colors.lightBlue : Colors.white,
), ),
isHighlight: isHighlight, isHighlight: isHighlight,
tooltip: LocaleKeys.document_plugins_createInlineMathEquation.tr(), tooltip: LocaleKeys.document_plugins_createInlineMathEquation.tr(),
@ -31,12 +31,33 @@ final ToolbarItem inlineMathEquationItem = ToolbarItem(
return; return;
} }
final node = editorState.getNodeAtPath(selection.start.path); final node = editorState.getNodeAtPath(selection.start.path);
if (node == null) { final delta = node?.delta;
if (node == null || delta == null) {
return; return;
} }
final text = editorState.getTextInSelection(selection).join();
final transaction = editorState.transaction final transaction = editorState.transaction;
..replaceText( if (isHighlight) {
final formula = delta
.slice(selection.startIndex, selection.endIndex)
.whereType<TextInsert>()
.firstOrNull
?.attributes?[InlineMathEquationKeys.formula];
assert(formula != null);
if (formula == null) {
return;
}
// clear the format
transaction.replaceText(
node,
selection.startIndex,
selection.length,
formula,
attributes: {},
);
} else {
final text = editorState.getTextInSelection(selection).join();
transaction.replaceText(
node, node,
selection.startIndex, selection.startIndex,
selection.length, selection.length,
@ -45,6 +66,7 @@ final ToolbarItem inlineMathEquationItem = ToolbarItem(
InlineMathEquationKeys.formula: text, InlineMathEquationKeys.formula: text,
}, },
); );
}
await editorState.apply(transaction); await editorState.apply(transaction);
}, },
); );

View File

@ -32,7 +32,7 @@ class MentionPageBlock extends StatefulWidget {
class _MentionPageBlockState extends State<MentionPageBlock> { class _MentionPageBlockState extends State<MentionPageBlock> {
late final EditorState editorState; late final EditorState editorState;
late final Future<ViewPB?> viewPBFuture; late Future<ViewPB?> viewPBFuture;
ViewListener? viewListener; ViewListener? viewListener;
@override @override
@ -45,6 +45,7 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
..start( ..start(
onViewUpdated: (p0) { onViewUpdated: (p0) {
pageMemorizer[p0.id] = p0; pageMemorizer[p0.id] = p0;
viewPBFuture = fetchView(widget.pageId);
editorState.reload(); editorState.reload();
}, },
); );
@ -111,11 +112,10 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
} }
Future<ViewPB?> fetchView(String pageId) async { Future<ViewPB?> fetchView(String pageId) async {
final views = await ViewBackendService().fetchViews((_, __) => true); final view = await ViewBackendService.getView(pageId).then(
final flattenViews = views.expand((e) => [e.$1, ...e.$2]).toList(); (value) => value.swap().toOption().toNullable(),
final view = flattenViews.firstWhereOrNull(
(element) => element.id == pageId,
); );
if (view == null) { if (view == null) {
// try to fetch from trash // try to fetch from trash
final trashViews = await TrashService().readTrash(); final trashViews = await TrashService().readTrash();
@ -129,6 +129,7 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
..name = trash.name; ..name = trash.name;
} }
} }
return view; return view;
} }

View File

@ -141,13 +141,13 @@ class EditorMigration {
} }
const backgroundColor = 'backgroundColor'; const backgroundColor = 'backgroundColor';
if (attributes.containsKey(backgroundColor)) { if (attributes.containsKey(backgroundColor)) {
attributes[FlowyRichTextKeys.highlightColor] = attributes[AppFlowyRichTextKeys.highlightColor] =
attributes[backgroundColor]; attributes[backgroundColor];
attributes.remove(backgroundColor); attributes.remove(backgroundColor);
} }
const color = 'color'; const color = 'color';
if (attributes.containsKey(color)) { if (attributes.containsKey(color)) {
attributes[FlowyRichTextKeys.textColor] = attributes[color]; attributes[AppFlowyRichTextKeys.textColor] = attributes[color];
attributes.remove(color); attributes.remove(color);
} }
return attributes; return attributes;

View File

@ -157,7 +157,7 @@ class _SmartEditBlockComponentWidgetState
var width = double.infinity; var width = double.infinity;
final editorSize = editorState.renderBox?.size; final editorSize = editorState.renderBox?.size;
final padding = editorState.editorStyle.padding; final padding = editorState.editorStyle.padding;
if (editorSize != null && padding != null) { if (editorSize != null) {
width = editorSize.width - padding.left - padding.right; width = editorSize.width - padding.left - padding.right;
} }
return width; return width;

View File

@ -84,7 +84,7 @@ class _ToggleListBlockComponentWidgetState
extends State<ToggleListBlockComponentWidget> extends State<ToggleListBlockComponentWidget>
with with
SelectableMixin, SelectableMixin,
DefaultSelectable, DefaultSelectableMixin,
BlockComponentConfigurable, BlockComponentConfigurable,
BackgroundColorMixin { BackgroundColorMixin {
// the key used to forward focus to the richtext child // the key used to forward focus to the richtext child
@ -141,7 +141,7 @@ class _ToggleListBlockComponentWidgetState
width: 4.0, width: 4.0,
), ),
Expanded( Expanded(
child: FlowyRichText( child: AppFlowyRichText(
key: forwardKey, key: forwardKey,
node: widget.node, node: widget.node,
editorState: editorState, editorState: editorState,

View File

@ -40,15 +40,18 @@ class EditorStyleCustomizer {
color: theme.colorScheme.onBackground, color: theme.colorScheme.onBackground,
height: 1.5, height: 1.5,
), ),
bold: baseTextStyle(fontFamily).copyWith( bold: baseTextStyle(fontFamily, fontWeight: FontWeight.bold).copyWith(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
italic: baseTextStyle(fontFamily).copyWith(fontStyle: FontStyle.italic), italic: baseTextStyle(fontFamily).copyWith(
underline: baseTextStyle(fontFamily) fontStyle: FontStyle.italic,
.copyWith(decoration: TextDecoration.underline), ),
strikethrough: underline: baseTextStyle(fontFamily).copyWith(
baseTextStyle(fontFamily) decoration: TextDecoration.underline,
.copyWith(decoration: TextDecoration.lineThrough), ),
strikethrough: baseTextStyle(fontFamily).copyWith(
decoration: TextDecoration.lineThrough,
),
href: baseTextStyle(fontFamily).copyWith( href: baseTextStyle(fontFamily).copyWith(
color: theme.colorScheme.primary, color: theme.colorScheme.primary,
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
@ -87,8 +90,7 @@ class EditorStyleCustomizer {
italic: baseTextStyle(fontFamily).copyWith(fontStyle: FontStyle.italic), italic: baseTextStyle(fontFamily).copyWith(fontStyle: FontStyle.italic),
underline: baseTextStyle(fontFamily) underline: baseTextStyle(fontFamily)
.copyWith(decoration: TextDecoration.underline), .copyWith(decoration: TextDecoration.underline),
strikethrough: strikethrough: baseTextStyle(fontFamily)
baseTextStyle(fontFamily)
.copyWith(decoration: TextDecoration.lineThrough), .copyWith(decoration: TextDecoration.lineThrough),
href: baseTextStyle(fontFamily).copyWith( href: baseTextStyle(fontFamily).copyWith(
color: theme.colorScheme.primary, color: theme.colorScheme.primary,
@ -163,10 +165,14 @@ class EditorStyleCustomizer {
); );
} }
TextStyle baseTextStyle(String fontFamily) { TextStyle baseTextStyle(
String fontFamily, {
FontWeight? fontWeight,
}) {
try { try {
return GoogleFonts.getFont( return GoogleFonts.getFont(
fontFamily, fontFamily,
fontWeight: fontWeight,
); );
} on Exception { } on Exception {
return GoogleFonts.getFont('Poppins'); return GoogleFonts.getFont('Poppins');
@ -174,6 +180,7 @@ class EditorStyleCustomizer {
} }
InlineSpan customizeAttributeDecorator( InlineSpan customizeAttributeDecorator(
BuildContext context,
Node node, Node node,
int index, int index,
TextInsert text, TextInsert text,

View File

@ -53,8 +53,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: c5b5e64 ref: "35394cd"
resolved-ref: c5b5e641fe11ae634f02db112e71f40a119e9c44 resolved-ref: "35394cd4f45f3f98afbec8d23d12fe0bf3cd3f6d"
url: "https://github.com/AppFlowy-IO/appflowy-editor.git" url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
source: git source: git
version: "1.1.0" version: "1.1.0"

View File

@ -46,7 +46,7 @@ dependencies:
appflowy_editor: appflowy_editor:
git: git:
url: https://github.com/AppFlowy-IO/appflowy-editor.git url: https://github.com/AppFlowy-IO/appflowy-editor.git
ref: c5b5e64 ref: 35394cd
appflowy_popover: appflowy_popover:
path: packages/appflowy_popover path: packages/appflowy_popover

View File

@ -184,6 +184,10 @@ script_runner = "@duckscript"
script_runner = "@shell" script_runner = "@shell"
script = [ script = [
""" """
cd appflowy_flutter
flutter clean
flutter pub get
cd ../
sh scripts/code_generation/generate.sh sh scripts/code_generation/generate.sh
""" """
] ]
@ -192,11 +196,14 @@ script = [
script_runner = "@duckscript" script_runner = "@duckscript"
script = [ script = [
""" """
cd ./appflowy_flutter/
exec cmd.exe /c flutter clean
exec cmd.exe /c flutter pub get
cd ../
exec scripts/code_generation/generate.cmd exec scripts/code_generation/generate.cmd
""", """,
] ]
[tasks.dry_code_generation] [tasks.dry_code_generation]
script_runner = "@shell" script_runner = "@shell"
script = [ script = [