From 8b1d5490788b01d3fb53577224b0ff12d312cbbc Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 14 Jun 2023 11:23:46 -0500 Subject: [PATCH 01/21] refactor: move shared code out of desktop --- .../desktop/items/color/color_menu.dart | 110 +----------------- lib/src/editor/toolbar/toolbar.dart | 2 +- .../editor/toolbar/util/color_generators.dart | 76 ++++++++++++ lib/src/editor/toolbar/util/format_color.dart | 15 +++ lib/src/editor/toolbar/util/util.dart | 1 + 5 files changed, 97 insertions(+), 107 deletions(-) create mode 100644 lib/src/editor/toolbar/util/color_generators.dart create mode 100644 lib/src/editor/toolbar/util/format_color.dart create mode 100644 lib/src/editor/toolbar/util/util.dart diff --git a/lib/src/editor/toolbar/desktop/items/color/color_menu.dart b/lib/src/editor/toolbar/desktop/items/color/color_menu.dart index e35a953d2..a1dd310c0 100644 --- a/lib/src/editor/toolbar/desktop/items/color/color_menu.dart +++ b/lib/src/editor/toolbar/desktop/items/color/color_menu.dart @@ -44,15 +44,15 @@ void showColorMenu( editorState: editorState, selectedColorHex: currentColorHex, colorOptions: isTextColor - ? _generateTextColorOptions(editorState) - : _generateHighlightColorOptions(editorState), + ? generateTextColorOptions() + : generateHighlightColorOptions(), onSubmittedColorHex: (color) { isTextColor - ? _formatFontColor( + ? formatFontColor( editorState, color, ) - : _formatHighlightColor( + : formatHighlightColor( editorState, color, ); @@ -64,105 +64,3 @@ void showColorMenu( ).build(); Overlay.of(context).insert(overlay!); } - -void _formatHighlightColor(EditorState editorState, String color) { - // if the color is empty, remove the highlight color format - editorState.formatDelta( - editorState.selection, - { - FlowyRichTextKeys.highlightColor: color.isEmpty ? null : color, - }, - ); -} - -void _formatFontColor(EditorState editorState, String color) { - // if the color is empty, remove the color format - editorState.formatDelta( - editorState.selection, - { - FlowyRichTextKeys.textColor: color.isEmpty ? null : color, - }, - ); -} - -List _generateTextColorOptions(EditorState editorState) { - return [ - ColorOption( - colorHex: '', - name: AppFlowyEditorLocalizations.current.fontColorDefault, - ), - ColorOption( - colorHex: Colors.grey.toHex(), - name: AppFlowyEditorLocalizations.current.fontColorGray, - ), - ColorOption( - colorHex: Colors.brown.toHex(), - name: AppFlowyEditorLocalizations.current.fontColorBrown, - ), - ColorOption( - colorHex: Colors.yellow.toHex(), - name: AppFlowyEditorLocalizations.current.fontColorYellow, - ), - ColorOption( - colorHex: Colors.green.toHex(), - name: AppFlowyEditorLocalizations.current.fontColorGreen, - ), - ColorOption( - colorHex: Colors.blue.toHex(), - name: AppFlowyEditorLocalizations.current.fontColorBlue, - ), - ColorOption( - colorHex: Colors.purple.toHex(), - name: AppFlowyEditorLocalizations.current.fontColorPurple, - ), - ColorOption( - colorHex: Colors.pink.toHex(), - name: AppFlowyEditorLocalizations.current.fontColorPink, - ), - ColorOption( - colorHex: Colors.red.toHex(), - name: AppFlowyEditorLocalizations.current.fontColorRed, - ), - ]; -} - -List _generateHighlightColorOptions(EditorState editorState) { - return [ - ColorOption( - colorHex: '', - name: AppFlowyEditorLocalizations.current.backgroundColorDefault, - ), - ColorOption( - colorHex: Colors.grey.withOpacity(0.3).toHex(), - name: AppFlowyEditorLocalizations.current.backgroundColorGray, - ), - ColorOption( - colorHex: Colors.brown.withOpacity(0.3).toHex(), - name: AppFlowyEditorLocalizations.current.backgroundColorBrown, - ), - ColorOption( - colorHex: Colors.yellow.withOpacity(0.3).toHex(), - name: AppFlowyEditorLocalizations.current.backgroundColorYellow, - ), - ColorOption( - colorHex: Colors.green.withOpacity(0.3).toHex(), - name: AppFlowyEditorLocalizations.current.backgroundColorGreen, - ), - ColorOption( - colorHex: Colors.blue.withOpacity(0.3).toHex(), - name: AppFlowyEditorLocalizations.current.backgroundColorBlue, - ), - ColorOption( - colorHex: Colors.purple.withOpacity(0.3).toHex(), - name: AppFlowyEditorLocalizations.current.backgroundColorPurple, - ), - ColorOption( - colorHex: Colors.pink.withOpacity(0.3).toHex(), - name: AppFlowyEditorLocalizations.current.backgroundColorPink, - ), - ColorOption( - colorHex: Colors.red.withOpacity(0.3).toHex(), - name: AppFlowyEditorLocalizations.current.backgroundColorRed, - ), - ]; -} diff --git a/lib/src/editor/toolbar/toolbar.dart b/lib/src/editor/toolbar/toolbar.dart index 05e01223b..fcaf5315d 100644 --- a/lib/src/editor/toolbar/toolbar.dart +++ b/lib/src/editor/toolbar/toolbar.dart @@ -1,3 +1,3 @@ export 'desktop/desktop.dart'; - export 'mobile/mobile.dart'; +export 'util/util.dart'; diff --git a/lib/src/editor/toolbar/util/color_generators.dart b/lib/src/editor/toolbar/util/color_generators.dart new file mode 100644 index 000000000..cd2066db1 --- /dev/null +++ b/lib/src/editor/toolbar/util/color_generators.dart @@ -0,0 +1,76 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; + +List generateTextColorOptions() { + return [ + ColorOption( + colorHex: Colors.grey.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorGray, + ), + ColorOption( + colorHex: Colors.brown.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorBrown, + ), + ColorOption( + colorHex: Colors.yellow.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorYellow, + ), + ColorOption( + colorHex: Colors.green.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorGreen, + ), + ColorOption( + colorHex: Colors.blue.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorBlue, + ), + ColorOption( + colorHex: Colors.purple.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorPurple, + ), + ColorOption( + colorHex: Colors.pink.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorPink, + ), + ColorOption( + colorHex: Colors.red.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorRed, + ), + ]; +} + +List generateHighlightColorOptions() { + return [ + ColorOption( + colorHex: Colors.grey.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations.current.backgroundColorGray, + ), + ColorOption( + colorHex: Colors.brown.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations.current.backgroundColorBrown, + ), + ColorOption( + colorHex: Colors.yellow.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations.current.backgroundColorYellow, + ), + ColorOption( + colorHex: Colors.green.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations.current.backgroundColorGreen, + ), + ColorOption( + colorHex: Colors.blue.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations.current.backgroundColorBlue, + ), + ColorOption( + colorHex: Colors.purple.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations.current.backgroundColorPurple, + ), + ColorOption( + colorHex: Colors.pink.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations.current.backgroundColorPink, + ), + ColorOption( + colorHex: Colors.red.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations.current.backgroundColorRed, + ), + ]; +} diff --git a/lib/src/editor/toolbar/util/format_color.dart b/lib/src/editor/toolbar/util/format_color.dart new file mode 100644 index 000000000..f368076fc --- /dev/null +++ b/lib/src/editor/toolbar/util/format_color.dart @@ -0,0 +1,15 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; + +void formatHighlightColor(EditorState editorState, String color) { + editorState.formatDelta( + editorState.selection, + {FlowyRichTextKeys.highlightColor: color}, + ); +} + +void formatFontColor(EditorState editorState, String color) { + editorState.formatDelta( + editorState.selection, + {FlowyRichTextKeys.textColor: color}, + ); +} diff --git a/lib/src/editor/toolbar/util/util.dart b/lib/src/editor/toolbar/util/util.dart new file mode 100644 index 000000000..3e026f979 --- /dev/null +++ b/lib/src/editor/toolbar/util/util.dart @@ -0,0 +1 @@ +export 'color_generators.dart'; From 9a317c682e9e7cdec019ad35ded607f48147d034 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 14 Jun 2023 11:56:06 -0500 Subject: [PATCH 02/21] refactor: fix double exist error and extract color option --- .../toolbar/desktop/items/color/color_menu.dart | 4 +++- .../toolbar/desktop/items/color/color_picker.dart | 11 ----------- lib/src/editor/toolbar/util/color_option.dart | 10 ++++++++++ lib/src/editor/toolbar/util/util.dart | 4 ++++ 4 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 lib/src/editor/toolbar/util/color_option.dart diff --git a/lib/src/editor/toolbar/desktop/items/color/color_menu.dart b/lib/src/editor/toolbar/desktop/items/color/color_menu.dart index a1dd310c0..468f89d45 100644 --- a/lib/src/editor/toolbar/desktop/items/color/color_menu.dart +++ b/lib/src/editor/toolbar/desktop/items/color/color_menu.dart @@ -1,4 +1,6 @@ -import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:appflowy_editor/appflowy_editor.dart' + hide formatFontColor, formatHighlightColor; +import 'package:appflowy_editor/src/editor/toolbar/util/format_color.dart'; import 'package:flutter/material.dart'; void showColorMenu( diff --git a/lib/src/editor/toolbar/desktop/items/color/color_picker.dart b/lib/src/editor/toolbar/desktop/items/color/color_picker.dart index 95c29cd26..ce70428cf 100644 --- a/lib/src/editor/toolbar/desktop/items/color/color_picker.dart +++ b/lib/src/editor/toolbar/desktop/items/color/color_picker.dart @@ -2,17 +2,6 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/src/editor/toolbar/desktop/items/utils/overlay_util.dart'; import 'package:flutter/material.dart'; -class ColorOption { - const ColorOption({ - required this.colorHex, - required this.name, - }); - - // 0xFF000000 - final String colorHex; - final String name; -} - class ColorPicker extends StatefulWidget { const ColorPicker({ super.key, diff --git a/lib/src/editor/toolbar/util/color_option.dart b/lib/src/editor/toolbar/util/color_option.dart new file mode 100644 index 000000000..31bd537f0 --- /dev/null +++ b/lib/src/editor/toolbar/util/color_option.dart @@ -0,0 +1,10 @@ +class ColorOption { + const ColorOption({ + required this.colorHex, + required this.name, + }); + + // 0xFF000000 + final String colorHex; + final String name; +} diff --git a/lib/src/editor/toolbar/util/util.dart b/lib/src/editor/toolbar/util/util.dart index 3e026f979..5a6320252 100644 --- a/lib/src/editor/toolbar/util/util.dart +++ b/lib/src/editor/toolbar/util/util.dart @@ -1 +1,5 @@ export 'color_generators.dart'; +export 'color_option.dart'; +// formatHighlightColor & formatFontColor +// also exist in package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart +// export 'format_color.dart'; From 31ea64a5b6fa702f360bb772121b9487a43c961b Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 14 Jun 2023 11:57:07 -0500 Subject: [PATCH 03/21] feat: update color icon --- assets/mobile/toolbar_icons/{text_color.svg => color.svg} | 0 assets/mobile/toolbar_icons/highlight_color.svg | 3 --- lib/src/infra/mobile/af_mobile_icon.dart | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) rename assets/mobile/toolbar_icons/{text_color.svg => color.svg} (100%) delete mode 100644 assets/mobile/toolbar_icons/highlight_color.svg diff --git a/assets/mobile/toolbar_icons/text_color.svg b/assets/mobile/toolbar_icons/color.svg similarity index 100% rename from assets/mobile/toolbar_icons/text_color.svg rename to assets/mobile/toolbar_icons/color.svg diff --git a/assets/mobile/toolbar_icons/highlight_color.svg b/assets/mobile/toolbar_icons/highlight_color.svg deleted file mode 100644 index 3be683d8e..000000000 --- a/assets/mobile/toolbar_icons/highlight_color.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/lib/src/infra/mobile/af_mobile_icon.dart b/lib/src/infra/mobile/af_mobile_icon.dart index 53729a03a..63315fc33 100644 --- a/lib/src/infra/mobile/af_mobile_icon.dart +++ b/lib/src/infra/mobile/af_mobile_icon.dart @@ -8,8 +8,7 @@ enum AFMobileIcons { underline('toolbar_icons/underline'), strikethrough('toolbar_icons/strikethrough'), code('toolbar_icons/code'), - textColor('toolbar_icons/text_color'), - highlightColor('toolbar_icons/highlight_color'), + color('toolbar_icons/color'), link('toolbar_icons/link'), heading('toolbar_icons/heading'), h1('toolbar_icons/h1'), From 2912bffebe3756cebc0c8fee13589aed4695971c Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 14 Jun 2023 17:16:06 -0500 Subject: [PATCH 04/21] refactor: refactor MobileToolbarItemMenuBtn to be more flexiable --- .../toolbar_items/heading_mobile_toolbar_item.dart | 2 +- .../mobile/toolbar_items/list_mobile_toolbar_item.dart | 2 +- .../text_decoration_mobile_toolbar_item.dart | 2 +- .../mobile/utils/mobile_toolbar_item_menu_btn.dart | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart index e8d04b413..7a78e4f3d 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart @@ -55,7 +55,7 @@ class _HeadingMenuState extends State<_HeadingMenu> { return MobileToolbarItemMenuBtn( icon: AFMobileIcon(afMobileIcons: currentHeading.icon), - label: currentHeading.label, + label: Text(currentHeading.label), isSelected: isSelected, onPressed: () { setState(() { diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/list_mobile_toolbar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/list_mobile_toolbar_item.dart index a9e9f3355..f913accdd 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/list_mobile_toolbar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/list_mobile_toolbar_item.dart @@ -45,7 +45,7 @@ class _ListMenuState extends State<_ListMenu> { return MobileToolbarItemMenuBtn( icon: AFMobileIcon(afMobileIcons: currentList.icon), - label: currentList.label, + label: Text(currentList.label), isSelected: isSelected, onPressed: () { setState(() { diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item.dart index d080ecf8d..d65110481 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item.dart @@ -60,7 +60,7 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> { icon: AFMobileIcon( afMobileIcons: currentDecoration.icon, ), - label: currentDecoration.label, + label: Text(currentDecoration.label), isSelected: isSelected, onPressed: () { if (widget.selection.isCollapsed) { diff --git a/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart b/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart index 32d23f4a4..25f49c8c5 100644 --- a/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart +++ b/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart @@ -5,14 +5,14 @@ class MobileToolbarItemMenuBtn extends StatelessWidget { const MobileToolbarItemMenuBtn({ super.key, required this.onPressed, - required this.icon, + this.icon, required this.label, required this.isSelected, }); final Function() onPressed; - final Widget icon; - final String label; + final Widget? icon; + final Widget label; final bool isSelected; @override @@ -20,8 +20,8 @@ class MobileToolbarItemMenuBtn extends StatelessWidget { final style = MobileToolbarStyle.of(context); return OutlinedButton.icon( onPressed: onPressed, - icon: icon, - label: Text(label), + icon: icon ?? const SizedBox.shrink(), + label: label, style: ButtonStyle( alignment: Alignment.centerLeft, foregroundColor: MaterialStateProperty.all(style.foregroundColor), From 2d1ee41f9175ebc1a4f83829df08c03ecb18bc17 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Tue, 20 Jun 2023 17:55:14 -0500 Subject: [PATCH 05/21] feat: add textAndBackgroundColorMobileToolbarItem --- example/lib/pages/simple_editor.dart | 1 + .../editor/toolbar/mobile/mobile_toolbar.dart | 21 +++++ .../toolbar/mobile/mobile_toolbar_style.dart | 29 ++++++- .../background_color_options_widgets.dart | 85 +++++++++++++++++++ .../mobile/toolbar_items/color/color.dart | 3 + ...xt_and_background_color_tool_bar_item.dart | 75 ++++++++++++++++ .../color/text_color_options_widgets.dart | 82 ++++++++++++++++++ .../color/utils/clear_color_button.dart | 59 +++++++++++++ .../color/utils/color_button.dart | 51 +++++++++++ .../color/utils/color_grid_delegate.dart | 76 +++++++++++++++++ .../toolbar_items/color/utils/utils.dart | 3 + .../mobile/toolbar_items/toolbar_items.dart | 1 + .../utils/mobile_toolbar_item_menu_btn.dart | 20 +++-- 13 files changed, 494 insertions(+), 12 deletions(-) create mode 100644 lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart create mode 100644 lib/src/editor/toolbar/mobile/toolbar_items/color/color.dart create mode 100644 lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart create mode 100644 lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart create mode 100644 lib/src/editor/toolbar/mobile/toolbar_items/color/utils/clear_color_button.dart create mode 100644 lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_button.dart create mode 100644 lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart create mode 100644 lib/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart diff --git a/example/lib/pages/simple_editor.dart b/example/lib/pages/simple_editor.dart index dc5c93b2a..bc41c6543 100644 --- a/example/lib/pages/simple_editor.dart +++ b/example/lib/pages/simple_editor.dart @@ -69,6 +69,7 @@ class SimpleEditor extends StatelessWidget { editorState: editorState, toolbarItems: [ textDecorationMobileToolbarItem, + textAndBackgroundColorMobileToolbarItem, headingMobileToolbarItem, todoListMobileToolbarItem, listMobileToolbarItem, diff --git a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart index d9bcfcaa6..a6ddfef07 100644 --- a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart +++ b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart @@ -9,10 +9,17 @@ class MobileToolbar extends StatelessWidget { // default MobileToolbarStyle parameters this.backgroundColor = Colors.white, this.foregroundColor = const Color(0xff676666), + this.clearDiagonalLineColor = const Color(0xffB3261E), this.itemHighlightColor = const Color(0xff1F71AC), this.itemOutlineColor = const Color(0xFFE3E3E3), + this.tabbarSelectedBackgroundColor = const Color(0x23808080), + this.tabbarSelectedForegroundColor = Colors.black, this.toolbarHeight = 50.0, this.borderRadius = 6.0, + this.buttonHeight = 40, + this.buttonSpacing = 8, + this.buttonBorderWidth = 1, + this.buttonSelectedBorderWidth = 2, }); final EditorState editorState; @@ -20,10 +27,17 @@ class MobileToolbar extends StatelessWidget { // MobileToolbarStyle parameters final Color backgroundColor; final Color foregroundColor; + final Color clearDiagonalLineColor; final Color itemHighlightColor; final Color itemOutlineColor; + final Color tabbarSelectedBackgroundColor; + final Color tabbarSelectedForegroundColor; final double toolbarHeight; final double borderRadius; + final double buttonHeight; + final double buttonSpacing; + final double buttonBorderWidth; + final double buttonSelectedBorderWidth; @override Widget build(BuildContext context) { @@ -36,10 +50,17 @@ class MobileToolbar extends StatelessWidget { return MobileToolbarStyle( backgroundColor: backgroundColor, foregroundColor: foregroundColor, + clearDiagonalLineColor: clearDiagonalLineColor, itemHighlightColor: itemHighlightColor, itemOutlineColor: itemOutlineColor, + tabbarSelectedBackgroundColor: tabbarSelectedBackgroundColor, + tabbarSelectedForegroundColor: tabbarSelectedForegroundColor, toolbarHeight: toolbarHeight, borderRadius: borderRadius, + buttonHeight: buttonHeight, + buttonSpacing: buttonSpacing, + buttonBorderWidth: buttonBorderWidth, + buttonSelectedBorderWidth: buttonSelectedBorderWidth, child: MobileToolbarWidget( // Use selection as key to force rebuild toolbar widget when selection changed. key: ValueKey(selection), diff --git a/lib/src/editor/toolbar/mobile/mobile_toolbar_style.dart b/lib/src/editor/toolbar/mobile/mobile_toolbar_style.dart index 6805f547e..2a1b2f00e 100644 --- a/lib/src/editor/toolbar/mobile/mobile_toolbar_style.dart +++ b/lib/src/editor/toolbar/mobile/mobile_toolbar_style.dart @@ -10,21 +10,35 @@ import 'package:flutter/material.dart'; class MobileToolbarStyle extends InheritedWidget { final Color backgroundColor; final Color foregroundColor; + final Color clearDiagonalLineColor; final Color itemHighlightColor; final Color itemOutlineColor; + final Color tabbarSelectedBackgroundColor; + final Color tabbarSelectedForegroundColor; final double toolbarHeight; final double borderRadius; + final double buttonHeight; + final double buttonSpacing; + final double buttonBorderWidth; + final double buttonSelectedBorderWidth; const MobileToolbarStyle({ - super.key, + Key? key, required this.backgroundColor, required this.foregroundColor, + required this.clearDiagonalLineColor, required this.itemHighlightColor, required this.itemOutlineColor, + required this.tabbarSelectedBackgroundColor, + required this.tabbarSelectedForegroundColor, required this.toolbarHeight, required this.borderRadius, + required this.buttonHeight, + required this.buttonSpacing, + required this.buttonBorderWidth, + required this.buttonSelectedBorderWidth, required Widget child, - }) : super(child: child); + }) : super(key: key, child: child); static MobileToolbarStyle of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType()!; @@ -36,9 +50,18 @@ class MobileToolbarStyle extends InheritedWidget { // It should return true if the new widget's values are different from the old widget's values. return backgroundColor != oldWidget.backgroundColor || foregroundColor != oldWidget.foregroundColor || + clearDiagonalLineColor != oldWidget.clearDiagonalLineColor || itemHighlightColor != oldWidget.itemHighlightColor || itemOutlineColor != oldWidget.itemOutlineColor || + tabbarSelectedBackgroundColor != + oldWidget.tabbarSelectedBackgroundColor || + tabbarSelectedForegroundColor != + oldWidget.tabbarSelectedForegroundColor || toolbarHeight != oldWidget.toolbarHeight || - borderRadius != oldWidget.borderRadius; + borderRadius != oldWidget.borderRadius || + buttonHeight != oldWidget.buttonHeight || + buttonSpacing != oldWidget.buttonSpacing || + buttonBorderWidth != oldWidget.buttonBorderWidth || + buttonSelectedBorderWidth != oldWidget.buttonSelectedBorderWidth; } } diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart new file mode 100644 index 000000000..4af36802d --- /dev/null +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart @@ -0,0 +1,85 @@ +import 'package:appflowy_editor/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart'; +import 'package:appflowy_editor/src/editor/toolbar/util/format_color.dart'; +import 'package:flutter/material.dart'; +import 'package:appflowy_editor/appflowy_editor.dart' hide formatHighlightColor; + +class BackgroundColorOptionsWidgets extends StatefulWidget { + const BackgroundColorOptionsWidgets( + this.editorState, + this.selection, { + Key? key, + }) : super(key: key); + + final Selection selection; + final EditorState editorState; + + @override + State createState() => + _BackgroundColorOptionsWidgetsState(); +} + +class _BackgroundColorOptionsWidgetsState + extends State { + @override + Widget build(BuildContext context) { + final style = MobileToolbarStyle.of(context); + + final selection = widget.selection; + final nodes = widget.editorState.getNodesInSelection(selection); + final hasTextColor = nodes.allSatisfyInSelection(selection, (delta) { + return delta.everyAttributes( + (attributes) => attributes[FlowyRichTextKeys.highlightColor] != null, + ); + }); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GridView( + shrinkWrap: true, + gridDelegate: buildColorGridDelegate(style), + children: [ + ClearColorButton( + onPressed: () { + if (hasTextColor) { + setState(() { + widget.editorState.formatDelta( + selection, + {FlowyRichTextKeys.highlightColor: null}, + ); + }); + } + }, + isSelected: !hasTextColor, + ), + ...generateHighlightColorOptions().map((e) { + final isSelected = + nodes.allSatisfyInSelection(selection, (delta) { + return delta.everyAttributes( + (attributes) => + attributes[FlowyRichTextKeys.highlightColor] == + e.colorHex, + ); + }); + return ColorButton( + isBackgroundColor: true, + colorOption: e, + onPressed: () { + if (!isSelected) { + setState(() { + formatHighlightColor( + widget.editorState, + e.colorHex, + ); + }); + } + }, + isSelected: isSelected, + ); + }).toList() + ], + ), + ], + ); + } +} diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/color.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/color.dart new file mode 100644 index 000000000..a8ea24c77 --- /dev/null +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/color.dart @@ -0,0 +1,3 @@ +export 'text_and_background_color_tool_bar_item.dart'; +export 'text_color_options_widgets.dart'; +export 'background_color_options_widgets.dart'; diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart new file mode 100644 index 000000000..85eae06c1 --- /dev/null +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart @@ -0,0 +1,75 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; +import 'color.dart'; + +final textAndBackgroundColorMobileToolbarItem = MobileToolbarItem.withMenu( + itemIcon: const AFMobileIcon(afMobileIcons: AFMobileIcons.color), + itemMenuBuilder: (editorState, selection, _) { + return _TextAndBackgroundColorMenu(editorState, selection); + }, +); + +class _TextAndBackgroundColorMenu extends StatefulWidget { + const _TextAndBackgroundColorMenu( + this.editorState, + this.selection, { + Key? key, + }) : super(key: key); + + final EditorState editorState; + final Selection selection; + + @override + State<_TextAndBackgroundColorMenu> createState() => + _TextAndBackgroundColorMenuState(); +} + +class _TextAndBackgroundColorMenuState + extends State<_TextAndBackgroundColorMenu> { + @override + Widget build(BuildContext context) { + final style = MobileToolbarStyle.of(context); + List myTabs = [ + const Tab( + text: 'Text Color', + ), + const Tab(text: 'Background Color'), + ]; + + return DefaultTabController( + length: myTabs.length, + child: Column( + children: [ + SizedBox( + height: style.buttonHeight, + child: TabBar( + tabs: myTabs, + labelColor: style.tabbarSelectedForegroundColor, + indicator: BoxDecoration( + borderRadius: BorderRadius.circular(style.borderRadius), + color: style.tabbarSelectedBackgroundColor, + ), + ), + ), + Container( + // 3 lines of buttons + height: 3 * style.buttonHeight + 4 * style.buttonSpacing, + padding: EdgeInsets.all(style.buttonSpacing), + child: TabBarView( + children: [ + TextColorOptionsWidgets( + widget.editorState, + widget.selection, + ), + BackgroundColorOptionsWidgets( + widget.editorState, + widget.selection, + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart new file mode 100644 index 000000000..36bcb2a0f --- /dev/null +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart @@ -0,0 +1,82 @@ +import 'package:appflowy_editor/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart'; +import 'package:appflowy_editor/src/editor/toolbar/util/format_color.dart'; +import 'package:flutter/material.dart'; +import 'package:appflowy_editor/appflowy_editor.dart' hide formatFontColor; + +class TextColorOptionsWidgets extends StatefulWidget { + const TextColorOptionsWidgets( + this.editorState, + this.selection, { + Key? key, + }) : super(key: key); + + final Selection selection; + final EditorState editorState; + + @override + State createState() => + _TextColorOptionsWidgetsState(); +} + +class _TextColorOptionsWidgetsState extends State { + @override + Widget build(BuildContext context) { + final style = MobileToolbarStyle.of(context); + + final selection = widget.selection; + final nodes = widget.editorState.getNodesInSelection(selection); + final hasTextColor = nodes.allSatisfyInSelection(selection, (delta) { + return delta.everyAttributes( + (attributes) => attributes[FlowyRichTextKeys.textColor] != null, + ); + }); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GridView( + shrinkWrap: true, + gridDelegate: buildColorGridDelegate(style), + children: [ + ClearColorButton( + onPressed: () { + if (hasTextColor) { + setState(() { + widget.editorState.formatDelta( + selection, + {FlowyRichTextKeys.textColor: null}, + ); + }); + } + }, + isSelected: !hasTextColor, + ), + ...generateTextColorOptions().map((e) { + final isSelected = + nodes.allSatisfyInSelection(selection, (delta) { + return delta.everyAttributes( + (attributes) => + attributes[FlowyRichTextKeys.textColor] == e.colorHex, + ); + }); + return ColorButton( + colorOption: e, + onPressed: () { + if (!isSelected) { + setState(() { + formatFontColor( + widget.editorState, + e.colorHex, + ); + }); + } + }, + isSelected: isSelected, + ); + }).toList() + ], + ), + ], + ); + } +} diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/clear_color_button.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/clear_color_button.dart new file mode 100644 index 000000000..14af5677c --- /dev/null +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/clear_color_button.dart @@ -0,0 +1,59 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; + +class ClearColorButton extends StatelessWidget { + const ClearColorButton({ + super.key, + required this.onPressed, + required this.isSelected, + }); + final void Function() onPressed; + final bool isSelected; + + @override + Widget build(BuildContext context) { + final style = MobileToolbarStyle.of(context); + + return InkWell( + onTap: onPressed, + child: Container( + height: style.buttonHeight, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(style.borderRadius), + border: isSelected + ? Border.all( + color: style.itemHighlightColor, + width: style.buttonSelectedBorderWidth, + ) + : Border.all( + color: style.itemOutlineColor, + width: style.buttonBorderWidth, + ), + ), + child: CustomPaint( + painter: _DiagonalLinePainter(style.clearDiagonalLineColor), + ), + ), + ); + } +} + +class _DiagonalLinePainter extends CustomPainter { + _DiagonalLinePainter(this.diagonalLineColor); + final Color diagonalLineColor; + @override + void paint(Canvas canvas, Size size) { + final paint = Paint() + ..color = diagonalLineColor + ..strokeWidth = 2.0; + + canvas.drawLine( + Offset(0, size.height), + Offset(size.width, 0), + paint, + ); + } + + @override + bool shouldRepaint(_DiagonalLinePainter oldDelegate) => false; +} diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_button.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_button.dart new file mode 100644 index 000000000..4d4a1ce89 --- /dev/null +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_button.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; + +class ColorButton extends StatelessWidget { + const ColorButton({ + Key? key, + required this.colorOption, + required this.isSelected, + required this.onPressed, + this.isBackgroundColor = false, + }) : super(key: key); + + final ColorOption colorOption; + final bool isBackgroundColor; + final bool isSelected; + final void Function() onPressed; + + @override + Widget build(BuildContext context) { + final style = MobileToolbarStyle.of(context); + return InkWell( + onTap: onPressed, + child: Container( + height: style.buttonHeight, + decoration: BoxDecoration( + color: isBackgroundColor + ? colorOption.colorHex.toColor() + : Colors.transparent, + borderRadius: BorderRadius.circular(style.borderRadius), + border: isSelected + ? Border.all( + color: style.itemHighlightColor, + width: style.buttonSelectedBorderWidth, + ) + : Border.all( + color: style.itemOutlineColor, + width: style.buttonBorderWidth, + ), + ), + child: isBackgroundColor + ? null + : Center( + child: Text( + colorOption.name, + style: TextStyle(color: colorOption.colorHex.toColor()), + ), + ), + ), + ); + } +} diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart new file mode 100644 index 000000000..47dfb04c1 --- /dev/null +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart @@ -0,0 +1,76 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/rendering.dart'; + +SliverGridDelegate buildColorGridDelegate(MobileToolbarStyle style) { + return SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight( + crossAxisCount: 3, + mainAxisSpacing: style.buttonSpacing, + crossAxisSpacing: style.buttonSpacing, + height: style.buttonHeight, + ); +} + +class SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight + extends SliverGridDelegate { + /// Creates a delegate that makes grid layouts with a fixed number of tiles in + /// the cross axis. + /// + /// All of the arguments must not be null. The `mainAxisSpacing` and + /// `crossAxisSpacing` arguments must not be negative. The `crossAxisCount` + /// and `childAspectRatio` arguments must be greater than zero. + const SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight({ + required this.crossAxisCount, + this.mainAxisSpacing = 0.0, + this.crossAxisSpacing = 0.0, + this.height = 56.0, + }) : assert(crossAxisCount > 0), + assert(mainAxisSpacing >= 0), + assert(crossAxisSpacing >= 0), + assert(height > 0); + + /// The number of children in the cross axis. + final int crossAxisCount; + + /// The number of logical pixels between each child along the main axis. + final double mainAxisSpacing; + + /// The number of logical pixels between each child along the cross axis. + final double crossAxisSpacing; + + /// The height of the crossAxis. + final double height; + + bool _debugAssertIsValid() { + assert(crossAxisCount > 0); + assert(mainAxisSpacing >= 0.0); + assert(crossAxisSpacing >= 0.0); + assert(height > 0.0); + return true; + } + + @override + SliverGridLayout getLayout(SliverConstraints constraints) { + assert(_debugAssertIsValid()); + final double usableCrossAxisExtent = + constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1); + final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount; + final double childMainAxisExtent = height; + return SliverGridRegularTileLayout( + crossAxisCount: crossAxisCount, + mainAxisStride: childMainAxisExtent + mainAxisSpacing, + crossAxisStride: childCrossAxisExtent + crossAxisSpacing, + childMainAxisExtent: childMainAxisExtent, + childCrossAxisExtent: childCrossAxisExtent, + reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection), + ); + } + + @override + bool shouldRelayout( + SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight oldDelegate) { + return oldDelegate.crossAxisCount != crossAxisCount || + oldDelegate.mainAxisSpacing != mainAxisSpacing || + oldDelegate.crossAxisSpacing != crossAxisSpacing || + oldDelegate.height != height; + } +} diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart new file mode 100644 index 000000000..59abed721 --- /dev/null +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart @@ -0,0 +1,3 @@ +export 'color_button.dart'; +export 'color_grid_delegate.dart'; +export 'clear_color_button.dart'; diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/toolbar_items.dart b/lib/src/editor/toolbar/mobile/toolbar_items/toolbar_items.dart index e50e9f839..560aca8bd 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/toolbar_items.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/toolbar_items.dart @@ -6,3 +6,4 @@ export 'quote_mobile_toolbar_item.dart'; export 'heading_mobile_toolbar_item.dart'; export 'divider_mobile_toolbar_item.dart'; export 'todo_list_mobile_toolbar_item.dart'; +export 'color/text_and_background_color_tool_bar_item.dart'; diff --git a/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart b/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart index 25f49c8c5..44bd583f1 100644 --- a/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart +++ b/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart @@ -26,15 +26,17 @@ class MobileToolbarItemMenuBtn extends StatelessWidget { alignment: Alignment.centerLeft, foregroundColor: MaterialStateProperty.all(style.foregroundColor), splashFactory: NoSplash.splashFactory, - side: MaterialStateProperty.resolveWith((states) { - if (isSelected == true) { - return BorderSide( - color: style.itemHighlightColor, - width: 2, - ); - } - return BorderSide(color: style.itemOutlineColor); - }), + side: MaterialStateProperty.resolveWith( + (states) { + if (isSelected == true) { + return BorderSide( + color: style.itemHighlightColor, + width: style.buttonBorderWidth, + ); + } + return BorderSide(color: style.itemOutlineColor); + }, + ), ), ); } From 2421dd116696ffe9c8c3df37c26bd5d609966cc1 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Tue, 20 Jun 2023 18:19:28 -0500 Subject: [PATCH 06/21] chore: dart fix --- .../mobile/toolbar_items/color/utils/color_grid_delegate.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart index 47dfb04c1..e5cabb694 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart @@ -67,7 +67,8 @@ class SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight @override bool shouldRelayout( - SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight oldDelegate) { + SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight oldDelegate, + ) { return oldDelegate.crossAxisCount != crossAxisCount || oldDelegate.mainAxisSpacing != mainAxisSpacing || oldDelegate.crossAxisSpacing != crossAxisSpacing || From fcfa642bd8f45fbb04ec615ceefae33ca70474ab Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Tue, 20 Jun 2023 19:40:32 -0500 Subject: [PATCH 07/21] refactor: extract MobileToolbarMenuGridDelegate --- .../background_color_options_widgets.dart | 5 +++- .../color/text_color_options_widgets.dart | 5 +++- .../toolbar_items/color/utils/utils.dart | 1 - .../heading_mobile_toolbar_item.dart | 9 +++++-- .../text_decoration_mobile_toolbar_item.dart | 26 ++++++------------- .../mobile_toolbar_menu_grid_delegate.dart} | 13 ++++++---- .../editor/toolbar/mobile/utils/utils.dart | 1 + 7 files changed, 32 insertions(+), 28 deletions(-) rename lib/src/editor/toolbar/mobile/{toolbar_items/color/utils/color_grid_delegate.dart => utils/mobile_toolbar_menu_grid_delegate.dart} (88%) diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart index 4af36802d..75f1b9479 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart @@ -37,7 +37,10 @@ class _BackgroundColorOptionsWidgetsState children: [ GridView( shrinkWrap: true, - gridDelegate: buildColorGridDelegate(style), + gridDelegate: buildMobileToolbarMenuGridDelegate( + mobileToolbarStyle: style, + crossAxisCount: 3, + ), children: [ ClearColorButton( onPressed: () { diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart index 36bcb2a0f..f302f6de5 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart @@ -36,7 +36,10 @@ class _TextColorOptionsWidgetsState extends State { children: [ GridView( shrinkWrap: true, - gridDelegate: buildColorGridDelegate(style), + gridDelegate: buildMobileToolbarMenuGridDelegate( + mobileToolbarStyle: style, + crossAxisCount: 3, + ), children: [ ClearColorButton( onPressed: () { diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart index 59abed721..7618293f6 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart @@ -1,3 +1,2 @@ export 'color_button.dart'; -export 'color_grid_delegate.dart'; export 'clear_color_button.dart'; diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart index 7a78e4f3d..33702b15f 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart @@ -46,6 +46,7 @@ class _HeadingMenuState extends State<_HeadingMenu> { @override Widget build(BuildContext context) { + final style = MobileToolbarStyle.of(context); final btnList = headings.map((currentHeading) { // Check if current node is heading and its level final node = @@ -78,8 +79,12 @@ class _HeadingMenuState extends State<_HeadingMenu> { ); }).toList(); - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + return GridView( + shrinkWrap: true, + gridDelegate: buildMobileToolbarMenuGridDelegate( + mobileToolbarStyle: style, + crossAxisCount: 3, + ), children: btnList, ); } diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item.dart index d65110481..b3922d9b9 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item.dart @@ -47,6 +47,7 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> { ]; @override Widget build(BuildContext context) { + final style = MobileToolbarStyle.of(context); final btnList = textDecorations.map((currentDecoration) { // Check current decoration is active or not final nodes = widget.editorState.getNodesInSelection(widget.selection); @@ -74,24 +75,13 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> { ); }).toList(); - return Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GridView( - shrinkWrap: true, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - childAspectRatio: 5, - ), - children: btnList, - ), - // TODO(yijing): Add color after showColorMenu moved into desktop - // Text(AppFlowyEditorLocalizations.current.textColor), - // Text(AppFlowyEditorLocalizations.current.highlightColor), - ], + return GridView( + shrinkWrap: true, + gridDelegate: buildMobileToolbarMenuGridDelegate( + mobileToolbarStyle: style, + crossAxisCount: 2, + ), + children: btnList, ); } } diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart b/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_menu_grid_delegate.dart similarity index 88% rename from lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart rename to lib/src/editor/toolbar/mobile/utils/mobile_toolbar_menu_grid_delegate.dart index e5cabb694..4b1cd7984 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/color_grid_delegate.dart +++ b/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_menu_grid_delegate.dart @@ -1,12 +1,15 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/rendering.dart'; -SliverGridDelegate buildColorGridDelegate(MobileToolbarStyle style) { +SliverGridDelegate buildMobileToolbarMenuGridDelegate({ + required MobileToolbarStyle mobileToolbarStyle, + required int crossAxisCount, +}) { return SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight( - crossAxisCount: 3, - mainAxisSpacing: style.buttonSpacing, - crossAxisSpacing: style.buttonSpacing, - height: style.buttonHeight, + crossAxisCount: crossAxisCount, + mainAxisSpacing: mobileToolbarStyle.buttonSpacing, + crossAxisSpacing: mobileToolbarStyle.buttonSpacing, + height: mobileToolbarStyle.buttonHeight, ); } diff --git a/lib/src/editor/toolbar/mobile/utils/utils.dart b/lib/src/editor/toolbar/mobile/utils/utils.dart index 309d3e557..693bcc508 100644 --- a/lib/src/editor/toolbar/mobile/utils/utils.dart +++ b/lib/src/editor/toolbar/mobile/utils/utils.dart @@ -1,2 +1,3 @@ export 'mobile_toolbar_item_menu_btn.dart'; export 'mobile_toolbar_item_menu.dart'; +export 'mobile_toolbar_menu_grid_delegate.dart'; From 3983b7d7f9326a769ce68da55ca9f0ea8487cccb Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Tue, 20 Jun 2023 19:41:35 -0500 Subject: [PATCH 08/21] chore: update UI parameters --- .../editor/toolbar/mobile/mobile_toolbar.dart | 29 +++++++++---------- ...xt_and_background_color_tool_bar_item.dart | 1 + .../color/utils/clear_color_button.dart | 2 +- .../utils/mobile_toolbar_item_menu_btn.dart | 13 ++++++++- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart index a6ddfef07..41c532896 100644 --- a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart +++ b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart @@ -193,22 +193,19 @@ class _ToolbarItemListView extends StatelessWidget { return ListView.builder( itemBuilder: (context, index) { final toobarItem = toolbarItems[index]; - return Material( - color: Colors.transparent, - child: IconButton( - icon: toobarItem.itemIcon, - onPressed: () { - if (toobarItem.hasMenu) { - // open /close current item menu through its parent widget(MobileToolbarWidget) - itemOnPressed.call(index); - } else { - toolbarItems[index].actionHandler?.call( - editorState, - selection, - ); - } - }, - ), + return IconButton( + icon: toobarItem.itemIcon, + onPressed: () { + if (toobarItem.hasMenu) { + // open /close current item menu through its parent widget(MobileToolbarWidget) + itemOnPressed.call(index); + } else { + toolbarItems[index].actionHandler?.call( + editorState, + selection, + ); + } + }, ); }, itemCount: toolbarItems.length, diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart index 85eae06c1..3ece4da28 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart @@ -43,6 +43,7 @@ class _TextAndBackgroundColorMenuState SizedBox( height: style.buttonHeight, child: TabBar( + indicatorSize: TabBarIndicatorSize.tab, tabs: myTabs, labelColor: style.tabbarSelectedForegroundColor, indicator: BoxDecoration( diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/clear_color_button.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/clear_color_button.dart index 14af5677c..a953a67e1 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/clear_color_button.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/utils/clear_color_button.dart @@ -45,7 +45,7 @@ class _DiagonalLinePainter extends CustomPainter { void paint(Canvas canvas, Size size) { final paint = Paint() ..color = diagonalLineColor - ..strokeWidth = 2.0; + ..strokeWidth = 1.0; canvas.drawLine( Offset(0, size.height), diff --git a/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart b/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart index 44bd583f1..22660bf9c 100644 --- a/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart +++ b/lib/src/editor/toolbar/mobile/utils/mobile_toolbar_item_menu_btn.dart @@ -31,12 +31,23 @@ class MobileToolbarItemMenuBtn extends StatelessWidget { if (isSelected == true) { return BorderSide( color: style.itemHighlightColor, - width: style.buttonBorderWidth, + width: style.buttonSelectedBorderWidth, ); } return BorderSide(color: style.itemOutlineColor); }, ), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(style.borderRadius), + ), + ), + padding: MaterialStateProperty.all( + const EdgeInsets.symmetric( + vertical: 0, + horizontal: 8, + ), + ), ), ); } From 0c2300f3a880d8debdda159b883862bf3e173ba9 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Tue, 20 Jun 2023 23:25:52 -0500 Subject: [PATCH 09/21] refactor: delete format color in format_rich_text_style.dart and refactor the code --- .../toolbar/desktop/items/color/color_menu.dart | 4 +--- .../color/background_color_options_widgets.dart | 4 +--- .../mobile/toolbar_items/color/color.dart | 1 + .../color/text_color_options_widgets.dart | 4 +--- .../mobile/toolbar_items/toolbar_items.dart | 2 +- lib/src/editor/toolbar/toolbar.dart | 2 +- lib/src/editor/toolbar/util/util.dart | 5 ----- .../{util => utils}/color_generators.dart | 0 .../toolbar/{util => utils}/color_option.dart | 0 .../toolbar/{util => utils}/format_color.dart | 0 lib/src/editor/toolbar/utils/utils.dart | 3 +++ .../format_rich_text_style.dart | 16 ---------------- 12 files changed, 9 insertions(+), 32 deletions(-) delete mode 100644 lib/src/editor/toolbar/util/util.dart rename lib/src/editor/toolbar/{util => utils}/color_generators.dart (100%) rename lib/src/editor/toolbar/{util => utils}/color_option.dart (100%) rename lib/src/editor/toolbar/{util => utils}/format_color.dart (100%) create mode 100644 lib/src/editor/toolbar/utils/utils.dart diff --git a/lib/src/editor/toolbar/desktop/items/color/color_menu.dart b/lib/src/editor/toolbar/desktop/items/color/color_menu.dart index 468f89d45..a1dd310c0 100644 --- a/lib/src/editor/toolbar/desktop/items/color/color_menu.dart +++ b/lib/src/editor/toolbar/desktop/items/color/color_menu.dart @@ -1,6 +1,4 @@ -import 'package:appflowy_editor/appflowy_editor.dart' - hide formatFontColor, formatHighlightColor; -import 'package:appflowy_editor/src/editor/toolbar/util/format_color.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; void showColorMenu( diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart index 75f1b9479..9bd0e7346 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart @@ -1,7 +1,5 @@ -import 'package:appflowy_editor/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart'; -import 'package:appflowy_editor/src/editor/toolbar/util/format_color.dart'; import 'package:flutter/material.dart'; -import 'package:appflowy_editor/appflowy_editor.dart' hide formatHighlightColor; +import 'package:appflowy_editor/appflowy_editor.dart'; class BackgroundColorOptionsWidgets extends StatefulWidget { const BackgroundColorOptionsWidgets( diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/color.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/color.dart index a8ea24c77..50fa0a080 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/color.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/color.dart @@ -1,3 +1,4 @@ export 'text_and_background_color_tool_bar_item.dart'; export 'text_color_options_widgets.dart'; export 'background_color_options_widgets.dart'; +export 'utils/utils.dart'; diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart index f302f6de5..3c2f2d998 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart @@ -1,7 +1,5 @@ -import 'package:appflowy_editor/src/editor/toolbar/mobile/toolbar_items/color/utils/utils.dart'; -import 'package:appflowy_editor/src/editor/toolbar/util/format_color.dart'; import 'package:flutter/material.dart'; -import 'package:appflowy_editor/appflowy_editor.dart' hide formatFontColor; +import 'package:appflowy_editor/appflowy_editor.dart'; class TextColorOptionsWidgets extends StatefulWidget { const TextColorOptionsWidgets( diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/toolbar_items.dart b/lib/src/editor/toolbar/mobile/toolbar_items/toolbar_items.dart index 560aca8bd..27c2f2ef9 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/toolbar_items.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/toolbar_items.dart @@ -6,4 +6,4 @@ export 'quote_mobile_toolbar_item.dart'; export 'heading_mobile_toolbar_item.dart'; export 'divider_mobile_toolbar_item.dart'; export 'todo_list_mobile_toolbar_item.dart'; -export 'color/text_and_background_color_tool_bar_item.dart'; +export 'color/color.dart'; diff --git a/lib/src/editor/toolbar/toolbar.dart b/lib/src/editor/toolbar/toolbar.dart index fcaf5315d..b3fec9b8b 100644 --- a/lib/src/editor/toolbar/toolbar.dart +++ b/lib/src/editor/toolbar/toolbar.dart @@ -1,3 +1,3 @@ export 'desktop/desktop.dart'; export 'mobile/mobile.dart'; -export 'util/util.dart'; +export 'utils/utils.dart'; diff --git a/lib/src/editor/toolbar/util/util.dart b/lib/src/editor/toolbar/util/util.dart deleted file mode 100644 index 5a6320252..000000000 --- a/lib/src/editor/toolbar/util/util.dart +++ /dev/null @@ -1,5 +0,0 @@ -export 'color_generators.dart'; -export 'color_option.dart'; -// formatHighlightColor & formatFontColor -// also exist in package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart -// export 'format_color.dart'; diff --git a/lib/src/editor/toolbar/util/color_generators.dart b/lib/src/editor/toolbar/utils/color_generators.dart similarity index 100% rename from lib/src/editor/toolbar/util/color_generators.dart rename to lib/src/editor/toolbar/utils/color_generators.dart diff --git a/lib/src/editor/toolbar/util/color_option.dart b/lib/src/editor/toolbar/utils/color_option.dart similarity index 100% rename from lib/src/editor/toolbar/util/color_option.dart rename to lib/src/editor/toolbar/utils/color_option.dart diff --git a/lib/src/editor/toolbar/util/format_color.dart b/lib/src/editor/toolbar/utils/format_color.dart similarity index 100% rename from lib/src/editor/toolbar/util/format_color.dart rename to lib/src/editor/toolbar/utils/format_color.dart diff --git a/lib/src/editor/toolbar/utils/utils.dart b/lib/src/editor/toolbar/utils/utils.dart new file mode 100644 index 000000000..2d412854b --- /dev/null +++ b/lib/src/editor/toolbar/utils/utils.dart @@ -0,0 +1,3 @@ +export 'color_generators.dart'; +export 'color_option.dart'; +export 'format_color.dart'; diff --git a/lib/src/service/default_text_operations/format_rich_text_style.dart b/lib/src/service/default_text_operations/format_rich_text_style.dart index c333d336f..4df852b98 100644 --- a/lib/src/service/default_text_operations/format_rich_text_style.dart +++ b/lib/src/service/default_text_operations/format_rich_text_style.dart @@ -123,22 +123,6 @@ bool formatHighlight(EditorState editorState, String colorHex) { ); } -bool formatHighlightColor(EditorState editorState, String colorHex) { - return formatRichTextPartialStyle( - editorState, - BuiltInAttributeKey.highlightColor, - customValue: colorHex, - ); -} - -bool formatFontColor(EditorState editorState, String colorHex) { - return formatRichTextPartialStyle( - editorState, - BuiltInAttributeKey.textColor, - customValue: colorHex, - ); -} - bool formatRichTextPartialStyle( EditorState editorState, String styleKey, { From f6a6f8ee951b11dc6df77eaacd7c77a16361da20 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Tue, 20 Jun 2023 23:45:22 -0500 Subject: [PATCH 10/21] chore: remove the bottom line of tabbar --- .../color/text_and_background_color_tool_bar_item.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart index 3ece4da28..56da3c9e2 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart @@ -50,6 +50,8 @@ class _TextAndBackgroundColorMenuState borderRadius: BorderRadius.circular(style.borderRadius), color: style.tabbarSelectedBackgroundColor, ), + // remove the bottom line of TabBar + dividerColor: Colors.transparent, ), ), Container( From b7008a51f223890b9d67d7fb9842c75fd5932c2a Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 21 Jun 2023 12:18:44 -0500 Subject: [PATCH 11/21] refactor: set color opitions to be customizable --- example/lib/pages/simple_editor.dart | 76 +++++++++++++++++++ .../editor/toolbar/mobile/mobile_toolbar.dart | 76 ++++++++++++++++++- .../toolbar/mobile/mobile_toolbar_style.dart | 9 ++- .../background_color_options_widgets.dart | 3 +- ...xt_and_background_color_tool_bar_item.dart | 1 - .../color/text_color_options_widgets.dart | 3 +- .../toolbar/utils/color_generators.dart | 2 + 7 files changed, 165 insertions(+), 5 deletions(-) diff --git a/example/lib/pages/simple_editor.dart b/example/lib/pages/simple_editor.dart index bc41c6543..07c4bb574 100644 --- a/example/lib/pages/simple_editor.dart +++ b/example/lib/pages/simple_editor.dart @@ -78,6 +78,82 @@ class SimpleEditor extends StatelessWidget { codeMobileToolbarItem, // dividerMobileToolbarItem, ], + textColorOptions: [ + ColorOption( + colorHex: Colors.grey.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorGray, + ), + ColorOption( + colorHex: Colors.brown.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorBrown, + ), + ColorOption( + colorHex: Colors.yellow.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorYellow, + ), + ColorOption( + colorHex: Colors.green.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorGreen, + ), + ColorOption( + colorHex: Colors.blue.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorBlue, + ), + ColorOption( + colorHex: Colors.purple.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorPurple, + ), + ColorOption( + colorHex: Colors.pink.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorPink, + ), + ColorOption( + colorHex: Colors.red.toHex(), + name: AppFlowyEditorLocalizations.current.fontColorRed, + ), + ], + backgroundColorOptions: [ + ColorOption( + colorHex: Colors.grey.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations + .current.backgroundColorGray, + ), + ColorOption( + colorHex: Colors.brown.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations + .current.backgroundColorBrown, + ), + ColorOption( + colorHex: Colors.yellow.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations + .current.backgroundColorYellow, + ), + ColorOption( + colorHex: Colors.green.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations + .current.backgroundColorGreen, + ), + ColorOption( + colorHex: Colors.blue.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations + .current.backgroundColorBlue, + ), + ColorOption( + colorHex: Colors.purple.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations + .current.backgroundColorPurple, + ), + ColorOption( + colorHex: Colors.pink.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations + .current.backgroundColorPink, + ), + ColorOption( + colorHex: Colors.red.withOpacity(0.3).toHex(), + name: AppFlowyEditorLocalizations + .current.backgroundColorRed, + ), + ], ), ], ); diff --git a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart index 41c532896..3af7f3814 100644 --- a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart +++ b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart @@ -20,7 +20,77 @@ class MobileToolbar extends StatelessWidget { this.buttonSpacing = 8, this.buttonBorderWidth = 1, this.buttonSelectedBorderWidth = 2, - }); + this.textColorOptions = const [ + ColorOption( + colorHex: '#808080', + name: 'Gray', + ), + ColorOption( + colorHex: '#A52A2A', + name: 'Brown', + ), + ColorOption( + colorHex: '#FFFF00', + name: 'Yellow', + ), + ColorOption( + colorHex: '#008000', + name: 'Green', + ), + ColorOption( + colorHex: '#0000FF', + name: 'Blue', + ), + ColorOption( + colorHex: '#800080', + name: 'Purple', + ), + ColorOption( + colorHex: '#FFC0CB', + name: 'Pink', + ), + ColorOption( + colorHex: '#FF0000', + name: 'Red', + ), + ], + this.backgroundColorOptions = const [ + ColorOption( + colorHex: '#4d4d4d', + name: 'Gray', + ), + ColorOption( + colorHex: '#a52a2a', + name: 'Brown', + ), + ColorOption( + colorHex: '#ffff00', + name: 'Yellow', + ), + ColorOption( + colorHex: '#008000', + name: 'Green', + ), + ColorOption( + colorHex: '#0000ff', + name: 'Blue', + ), + ColorOption( + colorHex: '#800080', + name: 'Purple', + ), + ColorOption( + colorHex: '#ffc0cb', + name: 'Pink', + ), + ColorOption( + colorHex: '#ff0000', + name: 'Red', + ), + ], + }) : assert( + textColorOptions.length > 0 && backgroundColorOptions.length > 0, + ); final EditorState editorState; final List toolbarItems; @@ -38,6 +108,8 @@ class MobileToolbar extends StatelessWidget { final double buttonSpacing; final double buttonBorderWidth; final double buttonSelectedBorderWidth; + final List textColorOptions; + final List backgroundColorOptions; @override Widget build(BuildContext context) { @@ -61,6 +133,8 @@ class MobileToolbar extends StatelessWidget { buttonSpacing: buttonSpacing, buttonBorderWidth: buttonBorderWidth, buttonSelectedBorderWidth: buttonSelectedBorderWidth, + textColorOptions: textColorOptions, + backgroundColorOptions: backgroundColorOptions, child: MobileToolbarWidget( // Use selection as key to force rebuild toolbar widget when selection changed. key: ValueKey(selection), diff --git a/lib/src/editor/toolbar/mobile/mobile_toolbar_style.dart b/lib/src/editor/toolbar/mobile/mobile_toolbar_style.dart index 2a1b2f00e..d65cb8548 100644 --- a/lib/src/editor/toolbar/mobile/mobile_toolbar_style.dart +++ b/lib/src/editor/toolbar/mobile/mobile_toolbar_style.dart @@ -1,3 +1,4 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; /// Style for the mobile toolbar. @@ -21,6 +22,8 @@ class MobileToolbarStyle extends InheritedWidget { final double buttonSpacing; final double buttonBorderWidth; final double buttonSelectedBorderWidth; + final List textColorOptions; + final List backgroundColorOptions; const MobileToolbarStyle({ Key? key, @@ -37,6 +40,8 @@ class MobileToolbarStyle extends InheritedWidget { required this.buttonSpacing, required this.buttonBorderWidth, required this.buttonSelectedBorderWidth, + required this.textColorOptions, + required this.backgroundColorOptions, required Widget child, }) : super(key: key, child: child); @@ -62,6 +67,8 @@ class MobileToolbarStyle extends InheritedWidget { buttonHeight != oldWidget.buttonHeight || buttonSpacing != oldWidget.buttonSpacing || buttonBorderWidth != oldWidget.buttonBorderWidth || - buttonSelectedBorderWidth != oldWidget.buttonSelectedBorderWidth; + buttonSelectedBorderWidth != oldWidget.buttonSelectedBorderWidth || + textColorOptions != oldWidget.textColorOptions || + backgroundColorOptions != oldWidget.backgroundColorOptions; } } diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart index 9bd0e7346..649990b14 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart @@ -53,7 +53,8 @@ class _BackgroundColorOptionsWidgetsState }, isSelected: !hasTextColor, ), - ...generateHighlightColorOptions().map((e) { + // color option buttons + ...style.backgroundColorOptions.map((e) { final isSelected = nodes.allSatisfyInSelection(selection, (delta) { return delta.everyAttributes( diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart index 56da3c9e2..e73056671 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart @@ -1,6 +1,5 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; -import 'color.dart'; final textAndBackgroundColorMobileToolbarItem = MobileToolbarItem.withMenu( itemIcon: const AFMobileIcon(afMobileIcons: AFMobileIcons.color), diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart index 3c2f2d998..ce717ea87 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart @@ -52,7 +52,8 @@ class _TextColorOptionsWidgetsState extends State { }, isSelected: !hasTextColor, ), - ...generateTextColorOptions().map((e) { + // color option buttons + ...style.textColorOptions.map((e) { final isSelected = nodes.allSatisfyInSelection(selection, (delta) { return delta.everyAttributes( diff --git a/lib/src/editor/toolbar/utils/color_generators.dart b/lib/src/editor/toolbar/utils/color_generators.dart index cd2066db1..95b9a549e 100644 --- a/lib/src/editor/toolbar/utils/color_generators.dart +++ b/lib/src/editor/toolbar/utils/color_generators.dart @@ -1,6 +1,8 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; +/// Used in Desktop only. +/// Needs to refactor to enable customization List generateTextColorOptions() { return [ ColorOption( From deb551970338303d8a429e5c6d10d7924f710940 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 21 Jun 2023 13:38:22 -0500 Subject: [PATCH 12/21] chore: add scrollbar in opitions grid view --- .../background_color_options_widgets.dart | 86 +++++++++---------- ...xt_and_background_color_tool_bar_item.dart | 3 +- .../color/text_color_options_widgets.dart | 83 +++++++++--------- 3 files changed, 82 insertions(+), 90 deletions(-) diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart index 649990b14..b44902d2f 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/background_color_options_widgets.dart @@ -30,58 +30,54 @@ class _BackgroundColorOptionsWidgetsState ); }); - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GridView( - shrinkWrap: true, - gridDelegate: buildMobileToolbarMenuGridDelegate( - mobileToolbarStyle: style, - crossAxisCount: 3, + return Scrollbar( + child: GridView( + shrinkWrap: true, + gridDelegate: buildMobileToolbarMenuGridDelegate( + mobileToolbarStyle: style, + crossAxisCount: 3, + ), + padding: EdgeInsets.all(style.buttonSpacing), + children: [ + ClearColorButton( + onPressed: () { + if (hasTextColor) { + setState(() { + widget.editorState.formatDelta( + selection, + {FlowyRichTextKeys.highlightColor: null}, + ); + }); + } + }, + isSelected: !hasTextColor, ), - children: [ - ClearColorButton( + // color option buttons + ...style.backgroundColorOptions.map((e) { + final isSelected = nodes.allSatisfyInSelection(selection, (delta) { + return delta.everyAttributes( + (attributes) => + attributes[FlowyRichTextKeys.highlightColor] == e.colorHex, + ); + }); + return ColorButton( + isBackgroundColor: true, + colorOption: e, onPressed: () { - if (hasTextColor) { + if (!isSelected) { setState(() { - widget.editorState.formatDelta( - selection, - {FlowyRichTextKeys.highlightColor: null}, + formatHighlightColor( + widget.editorState, + e.colorHex, ); }); } }, - isSelected: !hasTextColor, - ), - // color option buttons - ...style.backgroundColorOptions.map((e) { - final isSelected = - nodes.allSatisfyInSelection(selection, (delta) { - return delta.everyAttributes( - (attributes) => - attributes[FlowyRichTextKeys.highlightColor] == - e.colorHex, - ); - }); - return ColorButton( - isBackgroundColor: true, - colorOption: e, - onPressed: () { - if (!isSelected) { - setState(() { - formatHighlightColor( - widget.editorState, - e.colorHex, - ); - }); - } - }, - isSelected: isSelected, - ); - }).toList() - ], - ), - ], + isSelected: isSelected, + ); + }).toList() + ], + ), ); } } diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart index e73056671..6b8e4c976 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart @@ -53,10 +53,9 @@ class _TextAndBackgroundColorMenuState dividerColor: Colors.transparent, ), ), - Container( + SizedBox( // 3 lines of buttons height: 3 * style.buttonHeight + 4 * style.buttonSpacing, - padding: EdgeInsets.all(style.buttonSpacing), child: TabBarView( children: [ TextColorOptionsWidgets( diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart index ce717ea87..dcd58dd14 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_color_options_widgets.dart @@ -29,56 +29,53 @@ class _TextColorOptionsWidgetsState extends State { ); }); - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GridView( - shrinkWrap: true, - gridDelegate: buildMobileToolbarMenuGridDelegate( - mobileToolbarStyle: style, - crossAxisCount: 3, + return Scrollbar( + child: GridView( + shrinkWrap: true, + gridDelegate: buildMobileToolbarMenuGridDelegate( + mobileToolbarStyle: style, + crossAxisCount: 3, + ), + padding: EdgeInsets.all(style.buttonSpacing), + children: [ + ClearColorButton( + onPressed: () { + if (hasTextColor) { + setState(() { + widget.editorState.formatDelta( + selection, + {FlowyRichTextKeys.textColor: null}, + ); + }); + } + }, + isSelected: !hasTextColor, ), - children: [ - ClearColorButton( + // color option buttons + ...style.textColorOptions.map((e) { + final isSelected = nodes.allSatisfyInSelection(selection, (delta) { + return delta.everyAttributes( + (attributes) => + attributes[FlowyRichTextKeys.textColor] == e.colorHex, + ); + }); + return ColorButton( + colorOption: e, onPressed: () { - if (hasTextColor) { + if (!isSelected) { setState(() { - widget.editorState.formatDelta( - selection, - {FlowyRichTextKeys.textColor: null}, + formatFontColor( + widget.editorState, + e.colorHex, ); }); } }, - isSelected: !hasTextColor, - ), - // color option buttons - ...style.textColorOptions.map((e) { - final isSelected = - nodes.allSatisfyInSelection(selection, (delta) { - return delta.everyAttributes( - (attributes) => - attributes[FlowyRichTextKeys.textColor] == e.colorHex, - ); - }); - return ColorButton( - colorOption: e, - onPressed: () { - if (!isSelected) { - setState(() { - formatFontColor( - widget.editorState, - e.colorHex, - ); - }); - } - }, - isSelected: isSelected, - ); - }).toList() - ], - ), - ], + isSelected: isSelected, + ); + }).toList() + ], + ), ); } } From 5c662f8ea903ff9b6bf039fb7487dbabd948f0e6 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 21 Jun 2023 14:21:11 -0500 Subject: [PATCH 13/21] test: update code to pass the previous tests --- .../editor/toolbar/mobile/mobile_toolbar.dart | 38 ++++--- .../mobile/mobile_toolbar_style_test.dart | 91 +++++++++++++++- .../mobile_toolbar_style_test_widget.dart | 101 +++++++++++++++++- .../mobile_toolbar_item_menu_btn_test.dart | 2 +- 4 files changed, 207 insertions(+), 25 deletions(-) diff --git a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart index 3af7f3814..acd734709 100644 --- a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart +++ b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart @@ -16,10 +16,10 @@ class MobileToolbar extends StatelessWidget { this.tabbarSelectedForegroundColor = Colors.black, this.toolbarHeight = 50.0, this.borderRadius = 6.0, - this.buttonHeight = 40, - this.buttonSpacing = 8, - this.buttonBorderWidth = 1, - this.buttonSelectedBorderWidth = 2, + this.buttonHeight = 40.0, + this.buttonSpacing = 8.0, + this.buttonBorderWidth = 1.0, + this.buttonSelectedBorderWidth = 2.0, this.textColorOptions = const [ ColorOption( colorHex: '#808080', @@ -267,19 +267,23 @@ class _ToolbarItemListView extends StatelessWidget { return ListView.builder( itemBuilder: (context, index) { final toobarItem = toolbarItems[index]; - return IconButton( - icon: toobarItem.itemIcon, - onPressed: () { - if (toobarItem.hasMenu) { - // open /close current item menu through its parent widget(MobileToolbarWidget) - itemOnPressed.call(index); - } else { - toolbarItems[index].actionHandler?.call( - editorState, - selection, - ); - } - }, + return Material( + // Need Material to pass the test in mobile_toolbar_test.dart + color: Colors.transparent, + child: IconButton( + icon: toobarItem.itemIcon, + onPressed: () { + if (toobarItem.hasMenu) { + // open /close current item menu through its parent widget(MobileToolbarWidget) + itemOnPressed.call(index); + } else { + toolbarItems[index].actionHandler?.call( + editorState, + selection, + ); + } + }, + ), ); }, itemCount: toolbarItems.length, diff --git a/test/mobile/toolbar/mobile/mobile_toolbar_style_test.dart b/test/mobile/toolbar/mobile/mobile_toolbar_style_test.dart index 0749ab391..b36e532d1 100644 --- a/test/mobile/toolbar/mobile/mobile_toolbar_style_test.dart +++ b/test/mobile/toolbar/mobile/mobile_toolbar_style_test.dart @@ -1,25 +1,110 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:appflowy_editor/src/editor/toolbar/mobile/mobile_toolbar_style.dart'; +import 'package:appflowy_editor/src/editor/toolbar/utils/utils.dart'; void main() { testWidgets('MobileToolbarStyle should have correct values', (WidgetTester tester) async { const backgroundColor = Colors.white; const foregroundColor = Colors.black; - const itemHighlightColor = Colors.blue; - const itemOutlineColor = Colors.grey; + const clearDiagonalLineColor = const Color(0xffB3261E); + const itemHighlightColor = const Color(0xff1F71AC); + const itemOutlineColor = const Color(0xFFE3E3E3); + const tabbarSelectedBackgroundColor = const Color(0x23808080); + const tabbarSelectedForegroundColor = Colors.black; const toolbarHeight = 50.0; - const borderRadius = 10.0; + const borderRadius = 6.0; + const buttonHeight = 40.0; + const buttonSpacing = 8.0; + const buttonBorderWidth = 1.0; + const buttonSelectedBorderWidth = 2.0; + const textColorOptions = const [ + ColorOption( + colorHex: '#808080', + name: 'Gray', + ), + ColorOption( + colorHex: '#A52A2A', + name: 'Brown', + ), + ColorOption( + colorHex: '#FFFF00', + name: 'Yellow', + ), + ColorOption( + colorHex: '#008000', + name: 'Green', + ), + ColorOption( + colorHex: '#0000FF', + name: 'Blue', + ), + ColorOption( + colorHex: '#800080', + name: 'Purple', + ), + ColorOption( + colorHex: '#FFC0CB', + name: 'Pink', + ), + ColorOption( + colorHex: '#FF0000', + name: 'Red', + ), + ]; + const backgroundColorOptions = [ + ColorOption( + colorHex: '#4d4d4d', + name: 'Gray', + ), + ColorOption( + colorHex: '#a52a2a', + name: 'Brown', + ), + ColorOption( + colorHex: '#ffff00', + name: 'Yellow', + ), + ColorOption( + colorHex: '#008000', + name: 'Green', + ), + ColorOption( + colorHex: '#0000ff', + name: 'Blue', + ), + ColorOption( + colorHex: '#800080', + name: 'Purple', + ), + ColorOption( + colorHex: '#ffc0cb', + name: 'Pink', + ), + ColorOption( + colorHex: '#ff0000', + name: 'Red', + ), + ]; await tester.pumpWidget( const MobileToolbarStyle( backgroundColor: backgroundColor, foregroundColor: foregroundColor, + clearDiagonalLineColor: clearDiagonalLineColor, itemHighlightColor: itemHighlightColor, itemOutlineColor: itemOutlineColor, + tabbarSelectedBackgroundColor: tabbarSelectedBackgroundColor, + tabbarSelectedForegroundColor: tabbarSelectedForegroundColor, toolbarHeight: toolbarHeight, borderRadius: borderRadius, + buttonHeight: buttonHeight, + buttonSpacing: buttonSpacing, + buttonBorderWidth: buttonBorderWidth, + buttonSelectedBorderWidth: buttonSelectedBorderWidth, + textColorOptions: textColorOptions, + backgroundColorOptions: backgroundColorOptions, child: SizedBox(), ), ); diff --git a/test/mobile/toolbar/mobile/test_helpers/mobile_toolbar_style_test_widget.dart b/test/mobile/toolbar/mobile/test_helpers/mobile_toolbar_style_test_widget.dart index 389ea8c30..99a6a5497 100644 --- a/test/mobile/toolbar/mobile/test_helpers/mobile_toolbar_style_test_widget.dart +++ b/test/mobile/toolbar/mobile/test_helpers/mobile_toolbar_style_test_widget.dart @@ -7,20 +7,104 @@ class MobileToolbarStyleTestWidget extends StatelessWidget { required this.child, super.key, this.backgroundColor = Colors.white, - this.foregroundColor = Colors.black, - this.itemHighlightColor = Colors.blue, - this.itemOutlineColor = Colors.grey, + this.foregroundColor = const Color(0xff676666), + this.clearDiagonalLineColor = const Color(0xffB3261E), + this.itemHighlightColor = const Color(0xff1F71AC), + this.itemOutlineColor = const Color(0xFFE3E3E3), + this.tabbarSelectedBackgroundColor = const Color(0x23808080), + this.tabbarSelectedForegroundColor = Colors.black, this.toolbarHeight = 50.0, - this.borderRadius = 10.0, + this.borderRadius = 6.0, + this.buttonHeight = 40, + this.buttonSpacing = 8, + this.buttonBorderWidth = 1, + this.buttonSelectedBorderWidth = 2, + this.textColorOptions = const [ + ColorOption( + colorHex: '#808080', + name: 'Gray', + ), + ColorOption( + colorHex: '#A52A2A', + name: 'Brown', + ), + ColorOption( + colorHex: '#FFFF00', + name: 'Yellow', + ), + ColorOption( + colorHex: '#008000', + name: 'Green', + ), + ColorOption( + colorHex: '#0000FF', + name: 'Blue', + ), + ColorOption( + colorHex: '#800080', + name: 'Purple', + ), + ColorOption( + colorHex: '#FFC0CB', + name: 'Pink', + ), + ColorOption( + colorHex: '#FF0000', + name: 'Red', + ), + ], + this.backgroundColorOptions = const [ + ColorOption( + colorHex: '#4d4d4d', + name: 'Gray', + ), + ColorOption( + colorHex: '#a52a2a', + name: 'Brown', + ), + ColorOption( + colorHex: '#ffff00', + name: 'Yellow', + ), + ColorOption( + colorHex: '#008000', + name: 'Green', + ), + ColorOption( + colorHex: '#0000ff', + name: 'Blue', + ), + ColorOption( + colorHex: '#800080', + name: 'Purple', + ), + ColorOption( + colorHex: '#ffc0cb', + name: 'Pink', + ), + ColorOption( + colorHex: '#ff0000', + name: 'Red', + ), + ], }); final Widget child; final Color backgroundColor; final Color foregroundColor; + final Color clearDiagonalLineColor; final Color itemHighlightColor; final Color itemOutlineColor; + final Color tabbarSelectedBackgroundColor; + final Color tabbarSelectedForegroundColor; final double toolbarHeight; final double borderRadius; + final double buttonHeight; + final double buttonSpacing; + final double buttonBorderWidth; + final double buttonSelectedBorderWidth; + final List textColorOptions; + final List backgroundColorOptions; @override Widget build(BuildContext context) { @@ -28,10 +112,19 @@ class MobileToolbarStyleTestWidget extends StatelessWidget { home: MobileToolbarStyle( backgroundColor: backgroundColor, foregroundColor: foregroundColor, + clearDiagonalLineColor: clearDiagonalLineColor, itemHighlightColor: itemHighlightColor, itemOutlineColor: itemOutlineColor, + tabbarSelectedBackgroundColor: tabbarSelectedBackgroundColor, + tabbarSelectedForegroundColor: tabbarSelectedForegroundColor, toolbarHeight: toolbarHeight, borderRadius: borderRadius, + buttonHeight: buttonHeight, + buttonSpacing: buttonSpacing, + buttonBorderWidth: buttonBorderWidth, + buttonSelectedBorderWidth: buttonSelectedBorderWidth, + textColorOptions: textColorOptions, + backgroundColorOptions: backgroundColorOptions, child: child, ), ); diff --git a/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart b/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart index 7ca9270af..2939319bb 100644 --- a/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart +++ b/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart @@ -14,7 +14,7 @@ void main() { child: MobileToolbarItemMenuBtn( onPressed: () {}, icon: icon, - label: label, + label: Text(label), isSelected: false, ), ), From 5716efc8e59ac1082f20493e2f0ebf41b300ed07 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 21 Jun 2023 17:48:45 -0500 Subject: [PATCH 14/21] chore: add Material in testing --- .../editor/toolbar/mobile/mobile_toolbar.dart | 45 ++++++++----------- .../toolbar/mobile/mobile_toolbar_test.dart | 6 +-- .../code_mobile_toolbar_item_test.dart | 12 ++--- .../heading_mobile_toolbar_item_test.dart | 6 +-- .../link_mobile_toolbar_item_test.dart | 6 +-- .../list_mobile_toobar_item_test.dart | 6 +-- .../quote_mobile_toolbar_item_test.dart | 6 +-- ...t_decoration_mobile_toolbar_item_test.dart | 6 +-- .../todo_list_mobile_toolbar_item_test.dart | 6 +-- .../mobile_toolbar_item_menu_btn_test.dart | 6 +-- 10 files changed, 50 insertions(+), 55 deletions(-) diff --git a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart index acd734709..36ae72503 100644 --- a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart +++ b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart @@ -235,15 +235,12 @@ class _CloseKeyboardBtn extends StatelessWidget { @override Widget build(BuildContext context) { - return Material( - color: Colors.transparent, - child: IconButton( - onPressed: () { - // clear selection to close keyboard and toolbar - editorState.selectionService.updateSelection(null); - }, - icon: const Icon(Icons.keyboard_hide), - ), + return IconButton( + onPressed: () { + // clear selection to close keyboard and toolbar + editorState.selectionService.updateSelection(null); + }, + icon: const Icon(Icons.keyboard_hide), ); } } @@ -267,23 +264,19 @@ class _ToolbarItemListView extends StatelessWidget { return ListView.builder( itemBuilder: (context, index) { final toobarItem = toolbarItems[index]; - return Material( - // Need Material to pass the test in mobile_toolbar_test.dart - color: Colors.transparent, - child: IconButton( - icon: toobarItem.itemIcon, - onPressed: () { - if (toobarItem.hasMenu) { - // open /close current item menu through its parent widget(MobileToolbarWidget) - itemOnPressed.call(index); - } else { - toolbarItems[index].actionHandler?.call( - editorState, - selection, - ); - } - }, - ), + return IconButton( + icon: toobarItem.itemIcon, + onPressed: () { + if (toobarItem.hasMenu) { + // open /close current item menu through its parent widget(MobileToolbarWidget) + itemOnPressed.call(index); + } else { + toolbarItems[index].actionHandler?.call( + editorState, + selection, + ); + } + }, ); }, itemCount: toolbarItems.length, diff --git a/test/mobile/toolbar/mobile/mobile_toolbar_test.dart b/test/mobile/toolbar/mobile/mobile_toolbar_test.dart index 0f4520dc6..84fcd9016 100644 --- a/test/mobile/toolbar/mobile/mobile_toolbar_test.dart +++ b/test/mobile/toolbar/mobile/mobile_toolbar_test.dart @@ -43,9 +43,9 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget( - MobileAppWithToolbarWidget(editorState: editor.editorState), - ); + await tester.pumpWidget(Material( + child: MobileAppWithToolbarWidget(editorState: editor.editorState), + )); expect(find.byType(MobileToolbarWidget), findsOneWidget); }); diff --git a/test/mobile/toolbar/mobile/toolbar_items/code_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/code_mobile_toolbar_item_test.dart index 91805d779..82e76d7ba 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/code_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/code_mobile_toolbar_item_test.dart @@ -18,11 +18,13 @@ void main() { await editor.updateSelection(selection); await tester.pumpWidget( - MobileAppWithToolbarWidget( - editorState: editor.editorState, - toolbarItems: [ - codeMobileToolbarItem, - ], + Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + codeMobileToolbarItem, + ], + ), ), ); diff --git a/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart index 357166a64..861a8e577 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart @@ -17,14 +17,14 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget( - MobileAppWithToolbarWidget( + await tester.pumpWidget(Material( + child: MobileAppWithToolbarWidget( editorState: editor.editorState, toolbarItems: [ headingMobileToolbarItem, ], ), - ); + )); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); diff --git a/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart index 496a381ce..6ae0fdfb0 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart @@ -21,14 +21,14 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget( - MobileAppWithToolbarWidget( + await tester.pumpWidget(Material( + child: MobileAppWithToolbarWidget( editorState: editor.editorState, toolbarItems: [ linkMobileToolbarItem, ], ), - ); + )); // Tap link toolbar item await tester.tap(find.byType(IconButton).first); diff --git a/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart index 6baa5a207..ba2cf6c7a 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart @@ -17,14 +17,14 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget( - MobileAppWithToolbarWidget( + await tester.pumpWidget(Material( + child: MobileAppWithToolbarWidget( editorState: editor.editorState, toolbarItems: [ listMobileToolbarItem, ], ), - ); + )); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); diff --git a/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart index ddb7a1134..df2ab5d08 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart @@ -17,14 +17,14 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget( - MobileAppWithToolbarWidget( + await tester.pumpWidget(Material( + child: MobileAppWithToolbarWidget( editorState: editor.editorState, toolbarItems: [ quoteMobileToolbarItem, ], ), - ); + )); // Tap quote toolbar item final quoteBtn = find.byType(IconButton).first; diff --git a/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart index 019ba9370..51a5dee90 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart @@ -17,14 +17,14 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget( - MobileAppWithToolbarWidget( + await tester.pumpWidget(Material( + child: MobileAppWithToolbarWidget( editorState: editor.editorState, toolbarItems: [ textDecorationMobileToolbarItem, ], ), - ); + )); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); diff --git a/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart index 7312e86dd..4f0ed3477 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart @@ -17,14 +17,14 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget( - MobileAppWithToolbarWidget( + await tester.pumpWidget(Material( + child: MobileAppWithToolbarWidget( editorState: editor.editorState, toolbarItems: [ todoListMobileToolbarItem, ], ), - ); + )); // Tap todoList toolbar item final todoListBtn = find.byType(IconButton).first; diff --git a/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart b/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart index 2939319bb..38378ac47 100644 --- a/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart +++ b/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart @@ -9,8 +9,8 @@ void main() { const icon = Icon(Icons.add); const label = 'Add'; - await tester.pumpWidget( - MobileToolbarStyleTestWidget( + await tester.pumpWidget(Material( + child: MobileToolbarStyleTestWidget( child: MobileToolbarItemMenuBtn( onPressed: () {}, icon: icon, @@ -18,7 +18,7 @@ void main() { isSelected: false, ), ), - ); + )); expect(find.byIcon(Icons.add), findsOneWidget); expect(find.text('Add'), findsOneWidget); }); From e304aae0d53f99ae65baffed09c43943ca1e52dd Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 21 Jun 2023 18:44:28 -0500 Subject: [PATCH 15/21] chore: unify text and background default color opitions --- lib/src/editor/toolbar/mobile/mobile_toolbar.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart index 36ae72503..873283e7e 100644 --- a/lib/src/editor/toolbar/mobile/mobile_toolbar.dart +++ b/lib/src/editor/toolbar/mobile/mobile_toolbar.dart @@ -56,15 +56,15 @@ class MobileToolbar extends StatelessWidget { ], this.backgroundColorOptions = const [ ColorOption( - colorHex: '#4d4d4d', + colorHex: '#4D4D4D', name: 'Gray', ), ColorOption( - colorHex: '#a52a2a', + colorHex: '#A52A2A', name: 'Brown', ), ColorOption( - colorHex: '#ffff00', + colorHex: '#FFFF00', name: 'Yellow', ), ColorOption( @@ -72,7 +72,7 @@ class MobileToolbar extends StatelessWidget { name: 'Green', ), ColorOption( - colorHex: '#0000ff', + colorHex: '#0000FF', name: 'Blue', ), ColorOption( @@ -80,11 +80,11 @@ class MobileToolbar extends StatelessWidget { name: 'Purple', ), ColorOption( - colorHex: '#ffc0cb', + colorHex: '#FFC0CB', name: 'Pink', ), ColorOption( - colorHex: '#ff0000', + colorHex: '#FF0000', name: 'Red', ), ], From 92ff5a8bb29a16228767d828d3855288dcbae532 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Wed, 21 Jun 2023 18:45:05 -0500 Subject: [PATCH 16/21] test: add textAndBackgroundColorMobileToolbarItem test --- ...d_background_color_tool_bar_item_test.dart | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart diff --git a/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart new file mode 100644 index 000000000..ec7aca17d --- /dev/null +++ b/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; +import '../../../../../new/infra/testable_editor.dart'; +import '../../test_helpers/mobile_app_with_toolbar_widget.dart'; + +void main() { + testWidgets('textAndBackgroundColorMobileToolbarItem', + (WidgetTester tester) async { + const text = 'Welcome to Appflowy 😁'; + final editor = tester.editor..addParagraphs(3, initialText: text); + await editor.startTesting(); + + var selection = Selection.single( + path: [1], + startOffset: 2, + endOffset: text.length - 2, + ); + + await editor.updateSelection(selection); + await tester.pumpWidget(Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + textAndBackgroundColorMobileToolbarItem, + ], + ), + )); + + // Tap color toolbar item + await tester.tap(find.byType(IconButton).first); + await tester.pumpAndSettle(const Duration(milliseconds: 500)); + + // Show its menu and it has a tabbar to switch between text and background color + expect(find.byType(MobileToolbarItemMenu), findsOneWidget); + expect(find.text('Text Color'), findsOneWidget); + expect(find.text('Background Color'), findsOneWidget); + + // Test text color tab + // It has 9 buttons(default setting is clear + 8 colors) + expect(find.byType(ClearColorButton), findsOneWidget); + expect(find.byType(ColorButton), findsNWidgets(8)); + // Tap red color button + await tester.tap(find.widgetWithText(ColorButton, 'Red')); + await tester.pumpAndSettle(const Duration(milliseconds: 500)); + var node = editor.editorState.getNodeAtPath([1]); + // Check if the text color is red + expect( + node?.allSatisfyInSelection(selection, (delta) { + return delta.whereType().every( + (element) => + element.attributes?[FlowyRichTextKeys.textColor] == '#FF0000', + ); + }), + true, + ); + // Tap clear color button + await tester.tap(find.byType(ClearColorButton)); + await tester.pumpAndSettle(const Duration(milliseconds: 500)); + expect( + node?.allSatisfyInSelection(selection, (delta) { + return delta.whereType().every( + (element) => + element.attributes?[FlowyRichTextKeys.textColor] == null, + ); + }), + true, + ); + + // Test background color tab + await tester.tap(find.widgetWithText(TabBar, 'Background Color')); + await tester.pumpAndSettle(const Duration(milliseconds: 500)); + // Tap red color button + await tester.tap(find.byType(ColorButton).last); + await tester.pumpAndSettle(const Duration(milliseconds: 500)); + // Check if the background color is red + expect( + node?.allSatisfyInSelection(selection, (delta) { + return delta.whereType().every((element) => + element.attributes?[FlowyRichTextKeys.highlightColor] == '#FF0000'); + }), + true, + ); + // Tap clear color button + await tester.tap(find.byType(ClearColorButton)); + await tester.pumpAndSettle(const Duration(milliseconds: 500)); + expect( + node?.allSatisfyInSelection(selection, (delta) { + return delta.whereType().every( + (element) => + element.attributes?[FlowyRichTextKeys.highlightColor] == null, + ); + }), + true, + ); + }); +} From 819732601aa21393986e4afd3527a3b9e68871fc Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Thu, 22 Jun 2023 21:07:58 -0500 Subject: [PATCH 17/21] chore: update AppFlowyEditorLocalizations --- lib/l10n/intl_en.arb | 11 +++- ...xt_and_background_color_tool_bar_item.dart | 6 +- .../heading_mobile_toolbar_item.dart | 6 +- .../link_mobile_toolbar_item.dart | 2 +- .../list_mobile_toolbar_item.dart | 4 +- lib/src/l10n/intl/messages_en.dart | 12 +++- lib/src/l10n/l10n.dart | 62 +++++++++++++++++-- 7 files changed, 82 insertions(+), 21 deletions(-) diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 0b956df3a..c677069ce 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -2,7 +2,7 @@ "@@locale": "en", "bold": "Bold", "@bold": {}, - "bulletedList": "Bulleted list", + "bulletedList": "Bulleted List", "@bulletedList": {}, "checkbox": "Checkbox", "@checkbox": {}, @@ -24,7 +24,7 @@ "@italic": {}, "link": "Link", "@link": {}, - "numberedList": "Numbered list", + "numberedList": "Numbered List", "@numberedList": {}, "quote": "Quote", "@quote": {}, @@ -74,6 +74,7 @@ "@backgroundColorPink": {}, "backgroundColorRed": "Red background", "@backgroundColorRed": {}, + "done": "Done", "tint1": "Tint 1", "tint2": "Tint 2", "tint3": "Tint 3", @@ -92,7 +93,11 @@ "lightLightTint7": "Green", "lightLightTint8": "Aqua", "lightLightTint9": "Blue", - "textColor": "Text color", + "mobileHeading1": "Heading 1", + "mobileHeading2": "Heading 2", + "mobileHeading3": "Heading 3", + "textColor": "Text Color", + "backgroundColor": "Background Color", "addYourLink": "Add your link", "openLink": "Open link", "copyLink": "Copy link", diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart index 6b8e4c976..48c4baf32 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item.dart @@ -29,10 +29,10 @@ class _TextAndBackgroundColorMenuState Widget build(BuildContext context) { final style = MobileToolbarStyle.of(context); List myTabs = [ - const Tab( - text: 'Text Color', + Tab( + text: AppFlowyEditorLocalizations.current.textColor, ), - const Tab(text: 'Background Color'), + Tab(text: AppFlowyEditorLocalizations.current.backgroundColor), ]; return DefaultTabController( diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart index 33702b15f..f9161a0cd 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item.dart @@ -29,17 +29,17 @@ class _HeadingMenuState extends State<_HeadingMenu> { final headings = [ HeadingUnit( icon: AFMobileIcons.h1, - label: 'Heading 1', + label: AppFlowyEditorLocalizations.current.mobileHeading1, level: 1, ), HeadingUnit( icon: AFMobileIcons.h2, - label: 'Heading 2', + label: AppFlowyEditorLocalizations.current.mobileHeading2, level: 2, ), HeadingUnit( icon: AFMobileIcons.h3, - label: 'Heading 3', + label: AppFlowyEditorLocalizations.current.mobileHeading3, level: 3, ), ]; diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/link_mobile_toolbar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/link_mobile_toolbar_item.dart index 86420dc3f..4bc1dd0ad 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/link_mobile_toolbar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/link_mobile_toolbar_item.dart @@ -127,7 +127,7 @@ class _MobileLinkMenuState extends State<_MobileLinkMenu> { ), ), ), - child: const Text('Done'), + child: Text(AppFlowyEditorLocalizations.current.done), ), ) // TODO(yijing): edit link? diff --git a/lib/src/editor/toolbar/mobile/toolbar_items/list_mobile_toolbar_item.dart b/lib/src/editor/toolbar/mobile/toolbar_items/list_mobile_toolbar_item.dart index f913accdd..5997af554 100644 --- a/lib/src/editor/toolbar/mobile/toolbar_items/list_mobile_toolbar_item.dart +++ b/lib/src/editor/toolbar/mobile/toolbar_items/list_mobile_toolbar_item.dart @@ -26,12 +26,12 @@ class _ListMenuState extends State<_ListMenu> { final lists = [ ListUnit( icon: AFMobileIcons.bulletedList, - label: 'Bulleted List', + label: AppFlowyEditorLocalizations.current.bulletedList, name: 'bulleted_list', ), ListUnit( icon: AFMobileIcons.numberedList, - label: 'Numbered List', + label: AppFlowyEditorLocalizations.current.numberedList, name: 'numbered_list', ), ]; diff --git a/lib/src/l10n/intl/messages_en.dart b/lib/src/l10n/intl/messages_en.dart index a771624c6..44c19b54e 100644 --- a/lib/src/l10n/intl/messages_en.dart +++ b/lib/src/l10n/intl/messages_en.dart @@ -23,6 +23,8 @@ class MessageLookup extends MessageLookupByLibrary { final messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { "addYourLink": MessageLookupByLibrary.simpleMessage("Add your link"), + "backgroundColor": + MessageLookupByLibrary.simpleMessage("Background Color"), "backgroundColorBlue": MessageLookupByLibrary.simpleMessage("Blue background"), "backgroundColorBrown": @@ -44,13 +46,14 @@ class MessageLookup extends MessageLookupByLibrary { "backgroundColorYellow": MessageLookupByLibrary.simpleMessage("Yellow background"), "bold": MessageLookupByLibrary.simpleMessage("Bold"), - "bulletedList": MessageLookupByLibrary.simpleMessage("Bulleted list"), + "bulletedList": MessageLookupByLibrary.simpleMessage("Bulleted List"), "checkbox": MessageLookupByLibrary.simpleMessage("Checkbox"), "clearHighlightColor": MessageLookupByLibrary.simpleMessage("Clear highlight color"), "color": MessageLookupByLibrary.simpleMessage("Color"), "copyLink": MessageLookupByLibrary.simpleMessage("Copy link"), "customColor": MessageLookupByLibrary.simpleMessage("Custom color"), + "done": MessageLookupByLibrary.simpleMessage("Done"), "embedCode": MessageLookupByLibrary.simpleMessage("Embed Code"), "fontColorBlue": MessageLookupByLibrary.simpleMessage("Blue"), "fontColorBrown": MessageLookupByLibrary.simpleMessage("Brown"), @@ -81,7 +84,10 @@ class MessageLookup extends MessageLookupByLibrary { "lightLightTint8": MessageLookupByLibrary.simpleMessage("Aqua"), "lightLightTint9": MessageLookupByLibrary.simpleMessage("Blue"), "link": MessageLookupByLibrary.simpleMessage("Link"), - "numberedList": MessageLookupByLibrary.simpleMessage("Numbered list"), + "mobileHeading1": MessageLookupByLibrary.simpleMessage("Heading 1"), + "mobileHeading2": MessageLookupByLibrary.simpleMessage("Heading 2"), + "mobileHeading3": MessageLookupByLibrary.simpleMessage("Heading 3"), + "numberedList": MessageLookupByLibrary.simpleMessage("Numbered List"), "opacity": MessageLookupByLibrary.simpleMessage("Opacity"), "openLink": MessageLookupByLibrary.simpleMessage("Open link"), "quote": MessageLookupByLibrary.simpleMessage("Quote"), @@ -90,7 +96,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("Reset to default color"), "strikethrough": MessageLookupByLibrary.simpleMessage("Strikethrough"), "text": MessageLookupByLibrary.simpleMessage("Text"), - "textColor": MessageLookupByLibrary.simpleMessage("Text color"), + "textColor": MessageLookupByLibrary.simpleMessage("Text Color"), "tint1": MessageLookupByLibrary.simpleMessage("Tint 1"), "tint2": MessageLookupByLibrary.simpleMessage("Tint 2"), "tint3": MessageLookupByLibrary.simpleMessage("Tint 3"), diff --git a/lib/src/l10n/l10n.dart b/lib/src/l10n/l10n.dart index dfef3b2a6..53689a907 100644 --- a/lib/src/l10n/l10n.dart +++ b/lib/src/l10n/l10n.dart @@ -61,10 +61,10 @@ class AppFlowyEditorLocalizations { ); } - /// `Bulleted list` + /// `Bulleted List` String get bulletedList { return Intl.message( - 'Bulleted list', + 'Bulleted List', name: 'bulletedList', desc: '', args: [], @@ -171,10 +171,10 @@ class AppFlowyEditorLocalizations { ); } - /// `Numbered list` + /// `Numbered List` String get numberedList { return Intl.message( - 'Numbered list', + 'Numbered List', name: 'numberedList', desc: '', args: [], @@ -421,6 +421,16 @@ class AppFlowyEditorLocalizations { ); } + /// `Done` + String get done { + return Intl.message( + 'Done', + name: 'done', + desc: '', + args: [], + ); + } + /// `Tint 1` String get tint1 { return Intl.message( @@ -601,16 +611,56 @@ class AppFlowyEditorLocalizations { ); } - /// `Text color` + /// `Heading 1` + String get mobileHeading1 { + return Intl.message( + 'Heading 1', + name: 'mobileHeading1', + desc: '', + args: [], + ); + } + + /// `Heading 2` + String get mobileHeading2 { + return Intl.message( + 'Heading 2', + name: 'mobileHeading2', + desc: '', + args: [], + ); + } + + /// `Heading 3` + String get mobileHeading3 { + return Intl.message( + 'Heading 3', + name: 'mobileHeading3', + desc: '', + args: [], + ); + } + + /// `Text Color` String get textColor { return Intl.message( - 'Text color', + 'Text Color', name: 'textColor', desc: '', args: [], ); } + /// `Background Color` + String get backgroundColor { + return Intl.message( + 'Background Color', + name: 'backgroundColor', + desc: '', + args: [], + ); + } + /// `Add your link` String get addYourLink { return Intl.message( From 4d10a8d5fcdb8ea6dd6bf7033142045de0ec43e1 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Thu, 22 Jun 2023 21:21:47 -0500 Subject: [PATCH 18/21] chore: replace string by components' key in tests --- ...d_background_color_tool_bar_item_test.dart | 9 ++++-- .../heading_mobile_toolbar_item_test.dart | 30 +++++++++++-------- .../list_mobile_toobar_item_test.dart | 18 ++++++----- .../quote_mobile_toolbar_item_test.dart | 2 +- ...t_decoration_mobile_toolbar_item_test.dart | 25 +++++++++------- .../todo_list_mobile_toolbar_item_test.dart | 2 +- 6 files changed, 51 insertions(+), 35 deletions(-) diff --git a/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart index ec7aca17d..75148dba8 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart @@ -33,8 +33,10 @@ void main() { // Show its menu and it has a tabbar to switch between text and background color expect(find.byType(MobileToolbarItemMenu), findsOneWidget); - expect(find.text('Text Color'), findsOneWidget); - expect(find.text('Background Color'), findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.textColor), + findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.backgroundColor), + findsOneWidget); // Test text color tab // It has 9 buttons(default setting is clear + 8 colors) @@ -68,7 +70,8 @@ void main() { ); // Test background color tab - await tester.tap(find.widgetWithText(TabBar, 'Background Color')); + await tester.tap(find.widgetWithText( + TabBar, AppFlowyEditorLocalizations.current.backgroundColor)); await tester.pumpAndSettle(const Duration(milliseconds: 500)); // Tap red color button await tester.tap(find.byType(ColorButton).last); diff --git a/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart index 861a8e577..d6d69c845 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart @@ -32,39 +32,45 @@ void main() { // Show its menu and it has 3 buttons expect(find.byType(MobileToolbarItemMenu), findsOneWidget); - expect(find.text('Heading 1'), findsOneWidget); - expect(find.text('Heading 2'), findsOneWidget); - expect(find.text('Heading 3'), findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading1), + findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading2), + findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading3), + findsOneWidget); // Test Heading 1 button - await tester - .tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Heading 1')); + await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.mobileHeading1)); var node = editor.editorState.getNodeAtPath([1]); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( - node?.type == 'heading' && node?.attributes['level'] == 1, + node?.type == HeadingBlockKeys.type && + node?.attributes[HeadingBlockKeys.level] == 1, true, ); // Test Heading 2 button - await tester - .tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Heading 2')); + await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.mobileHeading2)); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); expect( - node?.type == 'heading' && node?.attributes['level'] == 2, + node?.type == HeadingBlockKeys.type && + node?.attributes[HeadingBlockKeys.level] == 2, true, ); // Test Heading 3 button - await tester - .tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Heading 3')); + await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.mobileHeading3)); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); expect( - node?.type == 'heading' && node?.attributes['level'] == 3, + node?.type == HeadingBlockKeys.type && + node?.attributes[HeadingBlockKeys.level] == 3, true, ); }); diff --git a/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart index ba2cf6c7a..8032be1fa 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart @@ -32,27 +32,29 @@ void main() { // Show its menu and it has 2 buttons expect(find.byType(MobileToolbarItemMenu), findsOneWidget); - expect(find.text('Bulleted List'), findsOneWidget); - expect(find.text('Numbered List'), findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.bulletedList), + findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.numberedList), + findsOneWidget); // Test Bulleted List button - await tester - .tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Bulleted List')); + await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.bulletedList)); var node = editor.editorState.getNodeAtPath([1]); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( - node?.type == 'bulleted_list', + node?.type == BulletedListBlockKeys.type, true, ); // Test Numbered List button - await tester - .tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Numbered List')); + await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.numberedList)); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); expect( - node?.type == 'numbered_list', + node?.type == NumberedListBlockKeys.type, true, ); }); diff --git a/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart index df2ab5d08..508681ad8 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart @@ -33,7 +33,7 @@ void main() { // Check if the text becomes quote node final node = editor.editorState.getNodeAtPath([1]); expect( - node?.type == 'quote', + node?.type == QuoteBlockKeys.type, true, ); }); diff --git a/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart index 51a5dee90..d07de74da 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart @@ -32,13 +32,17 @@ void main() { // Show its menu and it has 4 buttons expect(find.byType(MobileToolbarItemMenu), findsOneWidget); - expect(find.text('Bold'), findsOneWidget); - expect(find.text('Italic'), findsOneWidget); - expect(find.text('Underline'), findsOneWidget); - expect(find.text('Strikethrough'), findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.bold), findsOneWidget); + expect( + find.text(AppFlowyEditorLocalizations.current.italic), findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.underline), + findsOneWidget); + expect(find.text(AppFlowyEditorLocalizations.current.strikethrough), + findsOneWidget); // Test bold button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Bold')); + await tester.tap(find.widgetWithText( + MobileToolbarItemMenuBtn, AppFlowyEditorLocalizations.current.bold)); await tester.pumpAndSettle(const Duration(milliseconds: 500)); final node = editor.editorState.getNodeAtPath([1]); expect( @@ -51,7 +55,8 @@ void main() { ); // Test Italic button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Italic')); + await tester.tap(find.widgetWithText( + MobileToolbarItemMenuBtn, AppFlowyEditorLocalizations.current.italic)); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { @@ -64,8 +69,8 @@ void main() { ); // Test Underline button - await tester - .tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Underline')); + await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.underline)); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { @@ -78,8 +83,8 @@ void main() { ); // Test Strikethrough button - await tester - .tap(find.widgetWithText(MobileToolbarItemMenuBtn, 'Strikethrough')); + await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.strikethrough)); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { diff --git a/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart index 4f0ed3477..4f5a2f39a 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart @@ -33,7 +33,7 @@ void main() { // Check if the text becomes quote node final node = editor.editorState.getNodeAtPath([1]); expect( - node?.type == 'todo_list', + node?.type == TodoListBlockKeys.type, true, ); }); From 7ccecc7ce7d7534fc86de3ed5c07f20aca93da98 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Thu, 22 Jun 2023 22:03:53 -0500 Subject: [PATCH 19/21] test: add color options widgets tests --- ...background_color_options_widgets_test.dart | 28 +++++++++++++++++++ .../text_color_options_widgets_test.dart | 28 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 test/mobile/toolbar/mobile/toolbar_items/color/background_color_options_widgets_test.dart create mode 100644 test/mobile/toolbar/mobile/toolbar_items/color/text_color_options_widgets_test.dart diff --git a/test/mobile/toolbar/mobile/toolbar_items/color/background_color_options_widgets_test.dart b/test/mobile/toolbar/mobile/toolbar_items/color/background_color_options_widgets_test.dart new file mode 100644 index 000000000..68d87de90 --- /dev/null +++ b/test/mobile/toolbar/mobile/toolbar_items/color/background_color_options_widgets_test.dart @@ -0,0 +1,28 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import '../../../../../new/infra/testable_editor.dart'; +import '../../test_helpers/mobile_toolbar_style_test_widget.dart'; + +void main() { + group('BackgroundColorOptionsWidgets', () { + testWidgets('renders ClearColorButton', (tester) async { + const text = 'Welcome to Appflowy 😁'; + final editor = tester.editor..addParagraphs(3, initialText: text); + await editor.startTesting(); + + var selection = Selection.single( + path: [1], + startOffset: 2, + endOffset: text.length - 2, + ); + + await tester.pumpWidget(Material( + child: MobileToolbarStyleTestWidget( + child: BackgroundColorOptionsWidgets(editor.editorState, selection), + ),),); + + expect(find.byType(ClearColorButton), findsOneWidget); + }); + }); +} diff --git a/test/mobile/toolbar/mobile/toolbar_items/color/text_color_options_widgets_test.dart b/test/mobile/toolbar/mobile/toolbar_items/color/text_color_options_widgets_test.dart new file mode 100644 index 000000000..7b250b873 --- /dev/null +++ b/test/mobile/toolbar/mobile/toolbar_items/color/text_color_options_widgets_test.dart @@ -0,0 +1,28 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import '../../../../../new/infra/testable_editor.dart'; +import '../../test_helpers/mobile_toolbar_style_test_widget.dart'; + +void main() { + group('TextColorOptionsWidgets', () { + testWidgets('renders ClearColorButton', (tester) async { + const text = 'Welcome to Appflowy 😁'; + final editor = tester.editor..addParagraphs(3, initialText: text); + await editor.startTesting(); + + var selection = Selection.single( + path: [1], + startOffset: 2, + endOffset: text.length - 2, + ); + + await tester.pumpWidget(Material( + child: MobileToolbarStyleTestWidget( + child: TextColorOptionsWidgets(editor.editorState, selection), + ),),); + + expect(find.byType(ClearColorButton), findsOneWidget); + }); + }); +} From 4e6fef0c7fc48de7876a5d55c58d0494c2a4c098 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Thu, 22 Jun 2023 22:04:26 -0500 Subject: [PATCH 20/21] chore: dart fix --- .../mobile/mobile_toolbar_style_test.dart | 10 +++++----- .../toolbar/mobile/mobile_toolbar_test.dart | 2 +- ...nd_background_color_tool_bar_item_test.dart | 10 +++++----- .../heading_mobile_toolbar_item_test.dart | 14 +++++++------- .../link_mobile_toolbar_item_test.dart | 2 +- .../list_mobile_toobar_item_test.dart | 10 +++++----- .../quote_mobile_toolbar_item_test.dart | 2 +- ...xt_decoration_mobile_toolbar_item_test.dart | 16 ++++++++-------- .../todo_list_mobile_toolbar_item_test.dart | 2 +- .../mobile_toolbar_item_menu_btn_test.dart | 18 ++++++++++-------- 10 files changed, 44 insertions(+), 42 deletions(-) diff --git a/test/mobile/toolbar/mobile/mobile_toolbar_style_test.dart b/test/mobile/toolbar/mobile/mobile_toolbar_style_test.dart index b36e532d1..40b464a96 100644 --- a/test/mobile/toolbar/mobile/mobile_toolbar_style_test.dart +++ b/test/mobile/toolbar/mobile/mobile_toolbar_style_test.dart @@ -8,10 +8,10 @@ void main() { (WidgetTester tester) async { const backgroundColor = Colors.white; const foregroundColor = Colors.black; - const clearDiagonalLineColor = const Color(0xffB3261E); - const itemHighlightColor = const Color(0xff1F71AC); - const itemOutlineColor = const Color(0xFFE3E3E3); - const tabbarSelectedBackgroundColor = const Color(0x23808080); + const clearDiagonalLineColor = Color(0xffB3261E); + const itemHighlightColor = Color(0xff1F71AC); + const itemOutlineColor = Color(0xFFE3E3E3); + const tabbarSelectedBackgroundColor = Color(0x23808080); const tabbarSelectedForegroundColor = Colors.black; const toolbarHeight = 50.0; const borderRadius = 6.0; @@ -19,7 +19,7 @@ void main() { const buttonSpacing = 8.0; const buttonBorderWidth = 1.0; const buttonSelectedBorderWidth = 2.0; - const textColorOptions = const [ + const textColorOptions = [ ColorOption( colorHex: '#808080', name: 'Gray', diff --git a/test/mobile/toolbar/mobile/mobile_toolbar_test.dart b/test/mobile/toolbar/mobile/mobile_toolbar_test.dart index 84fcd9016..65a14c70a 100644 --- a/test/mobile/toolbar/mobile/mobile_toolbar_test.dart +++ b/test/mobile/toolbar/mobile/mobile_toolbar_test.dart @@ -45,7 +45,7 @@ void main() { await tester.pumpWidget(Material( child: MobileAppWithToolbarWidget(editorState: editor.editorState), - )); + ),); expect(find.byType(MobileToolbarWidget), findsOneWidget); }); diff --git a/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart index 75148dba8..90fd4b8e1 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart @@ -25,7 +25,7 @@ void main() { textAndBackgroundColorMobileToolbarItem, ], ), - )); + ),); // Tap color toolbar item await tester.tap(find.byType(IconButton).first); @@ -34,9 +34,9 @@ void main() { // Show its menu and it has a tabbar to switch between text and background color expect(find.byType(MobileToolbarItemMenu), findsOneWidget); expect(find.text(AppFlowyEditorLocalizations.current.textColor), - findsOneWidget); + findsOneWidget,); expect(find.text(AppFlowyEditorLocalizations.current.backgroundColor), - findsOneWidget); + findsOneWidget,); // Test text color tab // It has 9 buttons(default setting is clear + 8 colors) @@ -71,7 +71,7 @@ void main() { // Test background color tab await tester.tap(find.widgetWithText( - TabBar, AppFlowyEditorLocalizations.current.backgroundColor)); + TabBar, AppFlowyEditorLocalizations.current.backgroundColor,),); await tester.pumpAndSettle(const Duration(milliseconds: 500)); // Tap red color button await tester.tap(find.byType(ColorButton).last); @@ -80,7 +80,7 @@ void main() { expect( node?.allSatisfyInSelection(selection, (delta) { return delta.whereType().every((element) => - element.attributes?[FlowyRichTextKeys.highlightColor] == '#FF0000'); + element.attributes?[FlowyRichTextKeys.highlightColor] == '#FF0000',); }), true, ); diff --git a/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart index d6d69c845..82f19212c 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart @@ -24,7 +24,7 @@ void main() { headingMobileToolbarItem, ], ), - )); + ),); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); @@ -33,15 +33,15 @@ void main() { // Show its menu and it has 3 buttons expect(find.byType(MobileToolbarItemMenu), findsOneWidget); expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading1), - findsOneWidget); + findsOneWidget,); expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading2), - findsOneWidget); + findsOneWidget,); expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading3), - findsOneWidget); + findsOneWidget,); // Test Heading 1 button await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.mobileHeading1)); + AppFlowyEditorLocalizations.current.mobileHeading1,),); var node = editor.editorState.getNodeAtPath([1]); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( @@ -52,7 +52,7 @@ void main() { // Test Heading 2 button await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.mobileHeading2)); + AppFlowyEditorLocalizations.current.mobileHeading2,),); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); @@ -64,7 +64,7 @@ void main() { // Test Heading 3 button await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.mobileHeading3)); + AppFlowyEditorLocalizations.current.mobileHeading3,),); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); diff --git a/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart index 6ae0fdfb0..fe3f649d6 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart @@ -28,7 +28,7 @@ void main() { linkMobileToolbarItem, ], ), - )); + ),); // Tap link toolbar item await tester.tap(find.byType(IconButton).first); diff --git a/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart index 8032be1fa..912602739 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart @@ -24,7 +24,7 @@ void main() { listMobileToolbarItem, ], ), - )); + ),); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); @@ -33,13 +33,13 @@ void main() { // Show its menu and it has 2 buttons expect(find.byType(MobileToolbarItemMenu), findsOneWidget); expect(find.text(AppFlowyEditorLocalizations.current.bulletedList), - findsOneWidget); + findsOneWidget,); expect(find.text(AppFlowyEditorLocalizations.current.numberedList), - findsOneWidget); + findsOneWidget,); // Test Bulleted List button await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.bulletedList)); + AppFlowyEditorLocalizations.current.bulletedList,),); var node = editor.editorState.getNodeAtPath([1]); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( @@ -49,7 +49,7 @@ void main() { // Test Numbered List button await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.numberedList)); + AppFlowyEditorLocalizations.current.numberedList,),); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); diff --git a/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart index 508681ad8..fa5fe4fc5 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart @@ -24,7 +24,7 @@ void main() { quoteMobileToolbarItem, ], ), - )); + ),); // Tap quote toolbar item final quoteBtn = find.byType(IconButton).first; diff --git a/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart index d07de74da..9b01b28f6 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart @@ -24,7 +24,7 @@ void main() { textDecorationMobileToolbarItem, ], ), - )); + ),); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); @@ -34,15 +34,15 @@ void main() { expect(find.byType(MobileToolbarItemMenu), findsOneWidget); expect(find.text(AppFlowyEditorLocalizations.current.bold), findsOneWidget); expect( - find.text(AppFlowyEditorLocalizations.current.italic), findsOneWidget); + find.text(AppFlowyEditorLocalizations.current.italic), findsOneWidget,); expect(find.text(AppFlowyEditorLocalizations.current.underline), - findsOneWidget); + findsOneWidget,); expect(find.text(AppFlowyEditorLocalizations.current.strikethrough), - findsOneWidget); + findsOneWidget,); // Test bold button await tester.tap(find.widgetWithText( - MobileToolbarItemMenuBtn, AppFlowyEditorLocalizations.current.bold)); + MobileToolbarItemMenuBtn, AppFlowyEditorLocalizations.current.bold,),); await tester.pumpAndSettle(const Duration(milliseconds: 500)); final node = editor.editorState.getNodeAtPath([1]); expect( @@ -56,7 +56,7 @@ void main() { // Test Italic button await tester.tap(find.widgetWithText( - MobileToolbarItemMenuBtn, AppFlowyEditorLocalizations.current.italic)); + MobileToolbarItemMenuBtn, AppFlowyEditorLocalizations.current.italic,),); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { @@ -70,7 +70,7 @@ void main() { // Test Underline button await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.underline)); + AppFlowyEditorLocalizations.current.underline,),); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { @@ -84,7 +84,7 @@ void main() { // Test Strikethrough button await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.strikethrough)); + AppFlowyEditorLocalizations.current.strikethrough,),); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { diff --git a/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart index 4f5a2f39a..125249716 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart @@ -24,7 +24,7 @@ void main() { todoListMobileToolbarItem, ], ), - )); + ),); // Tap todoList toolbar item final todoListBtn = find.byType(IconButton).first; diff --git a/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart b/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart index 38378ac47..cdb322549 100644 --- a/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart +++ b/test/mobile/toolbar/mobile/utils/mobile_toolbar_item_menu_btn_test.dart @@ -9,16 +9,18 @@ void main() { const icon = Icon(Icons.add); const label = 'Add'; - await tester.pumpWidget(Material( - child: MobileToolbarStyleTestWidget( - child: MobileToolbarItemMenuBtn( - onPressed: () {}, - icon: icon, - label: Text(label), - isSelected: false, + await tester.pumpWidget( + Material( + child: MobileToolbarStyleTestWidget( + child: MobileToolbarItemMenuBtn( + onPressed: () {}, + icon: icon, + label: const Text(label), + isSelected: false, + ), ), ), - )); + ); expect(find.byIcon(Icons.add), findsOneWidget); expect(find.text('Add'), findsOneWidget); }); From 0fffeb85a4413964da0d41e23ad12dfad348fb57 Mon Sep 17 00:00:00 2001 From: Yijing Huang Date: Thu, 22 Jun 2023 22:07:58 -0500 Subject: [PATCH 21/21] chore: dart format --- .../toolbar/mobile/mobile_toolbar_test.dart | 8 ++- ...background_color_options_widgets_test.dart | 9 ++- ...d_background_color_tool_bar_item_test.dart | 43 ++++++++----- .../text_color_options_widgets_test.dart | 9 ++- .../heading_mobile_toolbar_item_test.dart | 58 +++++++++++------ .../link_mobile_toolbar_item_test.dart | 16 +++-- .../list_mobile_toobar_item_test.dart | 44 ++++++++----- .../quote_mobile_toolbar_item_test.dart | 16 +++-- ...t_decoration_mobile_toolbar_item_test.dart | 64 +++++++++++++------ .../todo_list_mobile_toolbar_item_test.dart | 16 +++-- 10 files changed, 184 insertions(+), 99 deletions(-) diff --git a/test/mobile/toolbar/mobile/mobile_toolbar_test.dart b/test/mobile/toolbar/mobile/mobile_toolbar_test.dart index 65a14c70a..b6a4cfe41 100644 --- a/test/mobile/toolbar/mobile/mobile_toolbar_test.dart +++ b/test/mobile/toolbar/mobile/mobile_toolbar_test.dart @@ -43,9 +43,11 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget(Material( - child: MobileAppWithToolbarWidget(editorState: editor.editorState), - ),); + await tester.pumpWidget( + Material( + child: MobileAppWithToolbarWidget(editorState: editor.editorState), + ), + ); expect(find.byType(MobileToolbarWidget), findsOneWidget); }); diff --git a/test/mobile/toolbar/mobile/toolbar_items/color/background_color_options_widgets_test.dart b/test/mobile/toolbar/mobile/toolbar_items/color/background_color_options_widgets_test.dart index 68d87de90..9d2a82fbb 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/color/background_color_options_widgets_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/color/background_color_options_widgets_test.dart @@ -17,10 +17,13 @@ void main() { endOffset: text.length - 2, ); - await tester.pumpWidget(Material( + await tester.pumpWidget( + Material( child: MobileToolbarStyleTestWidget( - child: BackgroundColorOptionsWidgets(editor.editorState, selection), - ),),); + child: BackgroundColorOptionsWidgets(editor.editorState, selection), + ), + ), + ); expect(find.byType(ClearColorButton), findsOneWidget); }); diff --git a/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart index 90fd4b8e1..fc299cd1c 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/color/text_and_background_color_tool_bar_item_test.dart @@ -18,14 +18,16 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget(Material( - child: MobileAppWithToolbarWidget( - editorState: editor.editorState, - toolbarItems: [ - textAndBackgroundColorMobileToolbarItem, - ], + await tester.pumpWidget( + Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + textAndBackgroundColorMobileToolbarItem, + ], + ), ), - ),); + ); // Tap color toolbar item await tester.tap(find.byType(IconButton).first); @@ -33,10 +35,14 @@ void main() { // Show its menu and it has a tabbar to switch between text and background color expect(find.byType(MobileToolbarItemMenu), findsOneWidget); - expect(find.text(AppFlowyEditorLocalizations.current.textColor), - findsOneWidget,); - expect(find.text(AppFlowyEditorLocalizations.current.backgroundColor), - findsOneWidget,); + expect( + find.text(AppFlowyEditorLocalizations.current.textColor), + findsOneWidget, + ); + expect( + find.text(AppFlowyEditorLocalizations.current.backgroundColor), + findsOneWidget, + ); // Test text color tab // It has 9 buttons(default setting is clear + 8 colors) @@ -70,8 +76,12 @@ void main() { ); // Test background color tab - await tester.tap(find.widgetWithText( - TabBar, AppFlowyEditorLocalizations.current.backgroundColor,),); + await tester.tap( + find.widgetWithText( + TabBar, + AppFlowyEditorLocalizations.current.backgroundColor, + ), + ); await tester.pumpAndSettle(const Duration(milliseconds: 500)); // Tap red color button await tester.tap(find.byType(ColorButton).last); @@ -79,8 +89,11 @@ void main() { // Check if the background color is red expect( node?.allSatisfyInSelection(selection, (delta) { - return delta.whereType().every((element) => - element.attributes?[FlowyRichTextKeys.highlightColor] == '#FF0000',); + return delta.whereType().every( + (element) => + element.attributes?[FlowyRichTextKeys.highlightColor] == + '#FF0000', + ); }), true, ); diff --git a/test/mobile/toolbar/mobile/toolbar_items/color/text_color_options_widgets_test.dart b/test/mobile/toolbar/mobile/toolbar_items/color/text_color_options_widgets_test.dart index 7b250b873..a414a8967 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/color/text_color_options_widgets_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/color/text_color_options_widgets_test.dart @@ -17,10 +17,13 @@ void main() { endOffset: text.length - 2, ); - await tester.pumpWidget(Material( + await tester.pumpWidget( + Material( child: MobileToolbarStyleTestWidget( - child: TextColorOptionsWidgets(editor.editorState, selection), - ),),); + child: TextColorOptionsWidgets(editor.editorState, selection), + ), + ), + ); expect(find.byType(ClearColorButton), findsOneWidget); }); diff --git a/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart index 82f19212c..fbe64066c 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/heading_mobile_toolbar_item_test.dart @@ -17,14 +17,16 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget(Material( - child: MobileAppWithToolbarWidget( - editorState: editor.editorState, - toolbarItems: [ - headingMobileToolbarItem, - ], + await tester.pumpWidget( + Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + headingMobileToolbarItem, + ], + ), ), - ),); + ); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); @@ -32,16 +34,26 @@ void main() { // Show its menu and it has 3 buttons expect(find.byType(MobileToolbarItemMenu), findsOneWidget); - expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading1), - findsOneWidget,); - expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading2), - findsOneWidget,); - expect(find.text(AppFlowyEditorLocalizations.current.mobileHeading3), - findsOneWidget,); + expect( + find.text(AppFlowyEditorLocalizations.current.mobileHeading1), + findsOneWidget, + ); + expect( + find.text(AppFlowyEditorLocalizations.current.mobileHeading2), + findsOneWidget, + ); + expect( + find.text(AppFlowyEditorLocalizations.current.mobileHeading3), + findsOneWidget, + ); // Test Heading 1 button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.mobileHeading1,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.mobileHeading1, + ), + ); var node = editor.editorState.getNodeAtPath([1]); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( @@ -51,8 +63,12 @@ void main() { ); // Test Heading 2 button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.mobileHeading2,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.mobileHeading2, + ), + ); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); @@ -63,8 +79,12 @@ void main() { ); // Test Heading 3 button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.mobileHeading3,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.mobileHeading3, + ), + ); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); diff --git a/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart index fe3f649d6..8d071fd1d 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/link_mobile_toolbar_item_test.dart @@ -21,14 +21,16 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget(Material( - child: MobileAppWithToolbarWidget( - editorState: editor.editorState, - toolbarItems: [ - linkMobileToolbarItem, - ], + await tester.pumpWidget( + Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + linkMobileToolbarItem, + ], + ), ), - ),); + ); // Tap link toolbar item await tester.tap(find.byType(IconButton).first); diff --git a/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart index 912602739..6939ec8c4 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/list_mobile_toobar_item_test.dart @@ -17,14 +17,16 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget(Material( - child: MobileAppWithToolbarWidget( - editorState: editor.editorState, - toolbarItems: [ - listMobileToolbarItem, - ], + await tester.pumpWidget( + Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + listMobileToolbarItem, + ], + ), ), - ),); + ); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); @@ -32,14 +34,22 @@ void main() { // Show its menu and it has 2 buttons expect(find.byType(MobileToolbarItemMenu), findsOneWidget); - expect(find.text(AppFlowyEditorLocalizations.current.bulletedList), - findsOneWidget,); - expect(find.text(AppFlowyEditorLocalizations.current.numberedList), - findsOneWidget,); + expect( + find.text(AppFlowyEditorLocalizations.current.bulletedList), + findsOneWidget, + ); + expect( + find.text(AppFlowyEditorLocalizations.current.numberedList), + findsOneWidget, + ); // Test Bulleted List button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.bulletedList,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.bulletedList, + ), + ); var node = editor.editorState.getNodeAtPath([1]); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( @@ -48,8 +58,12 @@ void main() { ); // Test Numbered List button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.numberedList,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.numberedList, + ), + ); await tester.pumpAndSettle(const Duration(milliseconds: 500)); //Get updated node node = editor.editorState.getNodeAtPath([1]); diff --git a/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart index fa5fe4fc5..9c7fc6e5a 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/quote_mobile_toolbar_item_test.dart @@ -17,14 +17,16 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget(Material( - child: MobileAppWithToolbarWidget( - editorState: editor.editorState, - toolbarItems: [ - quoteMobileToolbarItem, - ], + await tester.pumpWidget( + Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + quoteMobileToolbarItem, + ], + ), ), - ),); + ); // Tap quote toolbar item final quoteBtn = find.byType(IconButton).first; diff --git a/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart index 9b01b28f6..ce262d3b4 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/text_decoration_mobile_toolbar_item_test.dart @@ -17,14 +17,16 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget(Material( - child: MobileAppWithToolbarWidget( - editorState: editor.editorState, - toolbarItems: [ - textDecorationMobileToolbarItem, - ], + await tester.pumpWidget( + Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + textDecorationMobileToolbarItem, + ], + ), ), - ),); + ); // Tap text decoration toolbar item await tester.tap(find.byType(IconButton).first); @@ -34,15 +36,25 @@ void main() { expect(find.byType(MobileToolbarItemMenu), findsOneWidget); expect(find.text(AppFlowyEditorLocalizations.current.bold), findsOneWidget); expect( - find.text(AppFlowyEditorLocalizations.current.italic), findsOneWidget,); - expect(find.text(AppFlowyEditorLocalizations.current.underline), - findsOneWidget,); - expect(find.text(AppFlowyEditorLocalizations.current.strikethrough), - findsOneWidget,); + find.text(AppFlowyEditorLocalizations.current.italic), + findsOneWidget, + ); + expect( + find.text(AppFlowyEditorLocalizations.current.underline), + findsOneWidget, + ); + expect( + find.text(AppFlowyEditorLocalizations.current.strikethrough), + findsOneWidget, + ); // Test bold button - await tester.tap(find.widgetWithText( - MobileToolbarItemMenuBtn, AppFlowyEditorLocalizations.current.bold,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.bold, + ), + ); await tester.pumpAndSettle(const Duration(milliseconds: 500)); final node = editor.editorState.getNodeAtPath([1]); expect( @@ -55,8 +67,12 @@ void main() { ); // Test Italic button - await tester.tap(find.widgetWithText( - MobileToolbarItemMenuBtn, AppFlowyEditorLocalizations.current.italic,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.italic, + ), + ); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { @@ -69,8 +85,12 @@ void main() { ); // Test Underline button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.underline,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.underline, + ), + ); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { @@ -83,8 +103,12 @@ void main() { ); // Test Strikethrough button - await tester.tap(find.widgetWithText(MobileToolbarItemMenuBtn, - AppFlowyEditorLocalizations.current.strikethrough,),); + await tester.tap( + find.widgetWithText( + MobileToolbarItemMenuBtn, + AppFlowyEditorLocalizations.current.strikethrough, + ), + ); await tester.pumpAndSettle(const Duration(milliseconds: 500)); expect( node?.allSatisfyInSelection(selection, (delta) { diff --git a/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart b/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart index 125249716..e23ddd352 100644 --- a/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart +++ b/test/mobile/toolbar/mobile/toolbar_items/todo_list_mobile_toolbar_item_test.dart @@ -17,14 +17,16 @@ void main() { ); await editor.updateSelection(selection); - await tester.pumpWidget(Material( - child: MobileAppWithToolbarWidget( - editorState: editor.editorState, - toolbarItems: [ - todoListMobileToolbarItem, - ], + await tester.pumpWidget( + Material( + child: MobileAppWithToolbarWidget( + editorState: editor.editorState, + toolbarItems: [ + todoListMobileToolbarItem, + ], + ), ), - ),); + ); // Tap todoList toolbar item final todoListBtn = find.byType(IconButton).first;