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();
});
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());
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 editorState = appFlowyEditor.editorState;
@ -38,7 +39,8 @@ void main() {
await tester.tap(find.text('Summarize'));
await tester.pumpAndSettle();
await tester.tap(find.byType(FlowyRichTextButton, skipOffstage: false).first);
await tester
.tap(find.byType(FlowyRichTextButton, skipOffstage: false).first);
await tester.pumpAndSettle();
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 editorState = appFlowyEditor.editorState;
@ -69,7 +72,8 @@ void main() {
await tester.tap(find.text('Summarize'));
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();
expect(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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