diff --git a/CHANGELOG.md b/CHANGELOG.md index c60ea259a7..51df2a5742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,13 @@ # Release Notes +## Version 0.7.6 - 03/12/2024 +### New Features +- Revamped the simple table UI +- Added support for capturing images from camera on mobile +### Bug Fixes +- Improved markdown rendering capabilities in AI writer +- Fixed an issue where pressing Enter on a collapsed toggle list would add an unnecessary new line +- Fixed an issue where creating a document from slash menu could insert content at incorrect position + ## Version 0.7.5 - 25/11/2024 ### Bug Fixes - Improved chat response parsing diff --git a/frontend/appflowy_flutter/integration_test/desktop/document/document_with_simple_table_test.dart b/frontend/appflowy_flutter/integration_test/desktop/document/document_with_simple_table_test.dart index 65d206c720..4a8436f8b6 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/document/document_with_simple_table_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/document/document_with_simple_table_test.dart @@ -115,19 +115,41 @@ void main() { await tester.editor.tapLineOfEditorAt(0); await tester.insertTableInDocument(); - // hover on the table - final tableBlock = find.byType(SimpleTableBlockWidget).first; + // add a new row + final row = find.byWidgetPredicate((w) { + return w is SimpleTableRowBlockWidget && w.node.rowIndex == 1; + }); await tester.hoverOnWidget( - tableBlock, + row, onHover: () async { - // click the add row button final addRowButton = find.byType(SimpleTableAddRowButton).first; await tester.tap(addRowButton); + }, + ); + await tester.pumpAndSettle(); - // click the add column button + // add a new column + final column = find.byWidgetPredicate((w) { + return w is SimpleTableCellBlockWidget && w.node.columnIndex == 1; + }).first; + await tester.hoverOnWidget( + column, + onHover: () async { final addColumnButton = find.byType(SimpleTableAddColumnButton).first; await tester.tap(addColumnButton); + }, + ); + await tester.pumpAndSettle(); + // add a new row and a new column + final row2 = find.byWidgetPredicate((w) { + return w is SimpleTableCellBlockWidget && + w.node.rowIndex == 2 && + w.node.columnIndex == 2; + }).first; + await tester.hoverOnWidget( + row2, + onHover: () async { // click the add row and column button final addRowAndColumnButton = find.byType(SimpleTableAddColumnAndRowButton).first; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index 6d9aa8d1e5..e39c9bbd4c 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -92,9 +92,9 @@ class _AppFlowyEditorPageState extends State inlineMathEquationItem, linkItem, alignToolbarItem, - buildTextColorItem(), - buildHighlightColorItem(), - customizeFontToolbarItem, + buildTextColorItem()..isActive = showInAnyTextType, + buildHighlightColorItem()..isActive = showInAnyTextType, + customizeFontToolbarItem..isActive = showInAnyTextType, ]; late List slashMenuItems; @@ -164,6 +164,9 @@ class _AppFlowyEditorPageState extends State ToggleListBlockKeys.type, CalloutBlockKeys.type, TableBlockKeys.type, + SimpleTableBlockKeys.type, + SimpleTableCellBlockKeys.type, + SimpleTableRowBlockKeys.type, ]); AppFlowyRichTextKeys.supportSliced.add(AppFlowyRichTextKeys.fontFamily); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_block_component.dart index c6efde601b..6ff5321bce 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_block_component.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_block_component.dart @@ -202,7 +202,11 @@ class _SimpleTableBlockWidgetState extends State onExit: (event) { simpleTableContext.isHoveringOnTableBlock.value = false; }, - child: child, + child: Container( + alignment: Alignment.topLeft, + padding: padding, + child: child, + ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_operations/simple_table_node_extension.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_operations/simple_table_node_extension.dart index d31f127b91..70f67bfe3b 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_operations/simple_table_node_extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_operations/simple_table_node_extension.dart @@ -16,6 +16,17 @@ enum TableAlign { right; String get name => switch (this) { + TableAlign.left => 'Left', + TableAlign.center => 'Center', + TableAlign.right => 'Right', + }; + + // The key used in the attributes of the table node. + // + // Example: + // + // attributes[SimpleTableBlockKeys.columnAligns] = {0: 'left', 1: 'center', 2: 'right'} + String get key => switch (this) { TableAlign.left => 'left', TableAlign.center => 'center', TableAlign.right => 'right', @@ -130,7 +141,7 @@ extension TableNodeExtension on Node { parentTableNode.attributes[SimpleTableBlockKeys.rowAligns]; final align = rowAligns?[rowIndex.toString()]; return TableAlign.values.firstWhere( - (e) => e.name == align, + (e) => e.key == align, orElse: () => TableAlign.left, ); } catch (e) { @@ -151,7 +162,7 @@ extension TableNodeExtension on Node { parentTableNode.attributes[SimpleTableBlockKeys.columnAligns]; final align = columnAligns?[columnIndex.toString()]; return TableAlign.values.firstWhere( - (e) => e.name == align, + (e) => e.key == align, orElse: () => TableAlign.left, ); } catch (e) { diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_operations/simple_table_style_operation.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_operations/simple_table_style_operation.dart index 40d2649f01..edcd30e608 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_operations/simple_table_style_operation.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_operations/simple_table_style_operation.dart @@ -129,7 +129,7 @@ extension TableOptionOperation on EditorState { final attributes = parentTableNode.attributes.mergeValues( SimpleTableBlockKeys.columnAligns, parentTableNode.columnAligns, - duplicatedEntry: MapEntry(columnIndex.toString(), align.name), + duplicatedEntry: MapEntry(columnIndex.toString(), align.key), ); transaction.updateNode(parentTableNode, attributes); await apply(transaction); @@ -167,7 +167,7 @@ extension TableOptionOperation on EditorState { final attributes = parentTableNode.attributes.mergeValues( SimpleTableBlockKeys.rowAligns, parentTableNode.rowAligns, - duplicatedEntry: MapEntry(rowIndex.toString(), align.name), + duplicatedEntry: MapEntry(rowIndex.toString(), align.key), ); transaction.updateNode(parentTableNode, attributes); await apply(transaction); diff --git a/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_delete_operation_test.dart b/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_delete_operation_test.dart index ca687bc0c8..c9c1be8379 100644 --- a/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_delete_operation_test.dart +++ b/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_delete_operation_test.dart @@ -67,7 +67,7 @@ void main() { align: TableAlign.center, ); expect(tableNode.rowAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); await editorState.deleteRowInTable(tableNode, 1); expect(tableNode.rowLength, 2); @@ -96,7 +96,7 @@ void main() { align: TableAlign.center, ); expect(tableNode.rowAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); await editorState.deleteRowInTable(tableNode, 0); expect(tableNode.rowLength, 2); @@ -105,7 +105,7 @@ void main() { '0': '0xFF0000FF', }); expect(tableNode.rowAligns, { - '0': TableAlign.center.name, + '0': TableAlign.center.key, }); }); @@ -129,7 +129,7 @@ void main() { align: TableAlign.center, ); expect(tableNode.columnAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); await editorState.deleteColumnInTable(tableNode, 1); expect(tableNode.rowLength, 3); @@ -158,7 +158,7 @@ void main() { align: TableAlign.center, ); expect(tableNode.columnAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); await editorState.deleteColumnInTable(tableNode, 0); expect(tableNode.rowLength, 3); @@ -167,7 +167,7 @@ void main() { '0': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '0': TableAlign.center.name, + '0': TableAlign.center.key, }); }); }); diff --git a/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_duplicate_operation_test.dart b/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_duplicate_operation_test.dart index d8b33c7fd9..123310538a 100644 --- a/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_duplicate_operation_test.dart +++ b/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_duplicate_operation_test.dart @@ -54,7 +54,7 @@ void main() { align: TableAlign.center, ); expect(tableNode.rowAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); await editorState.duplicateRowInTable(tableNode, 1); expect(tableCellNode.rowColors, { @@ -62,8 +62,8 @@ void main() { '2': '0xFF0000FF', }); expect(tableNode.rowAligns, { - '1': TableAlign.center.name, - '2': TableAlign.center.name, + '1': TableAlign.center.key, + '2': TableAlign.center.key, }); }); @@ -87,14 +87,14 @@ void main() { align: TableAlign.center, ); expect(tableNode.rowAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); await editorState.duplicateRowInTable(tableNode, 2); expect(tableCellNode.rowColors, { '1': '0xFF0000FF', }); expect(tableNode.rowAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); }); @@ -118,7 +118,7 @@ void main() { '1': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); await editorState.duplicateColumnInTable(tableNode, 1); expect(tableCellNode.columnColors, { @@ -126,8 +126,8 @@ void main() { '2': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '1': TableAlign.center.name, - '2': TableAlign.center.name, + '1': TableAlign.center.key, + '2': TableAlign.center.key, }); }); @@ -151,14 +151,14 @@ void main() { '1': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); await editorState.duplicateColumnInTable(tableNode, 2); expect(tableCellNode.columnColors, { '1': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); }); }); diff --git a/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_insert_operation_test.dart b/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_insert_operation_test.dart index b99c1342a7..c84615ac42 100644 --- a/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_insert_operation_test.dart +++ b/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_insert_operation_test.dart @@ -87,14 +87,14 @@ void main() { align: TableAlign.center, ); expect(tableNode.rowAligns, { - '0': TableAlign.center.name, + '0': TableAlign.center.key, }); await editorState.insertRowInTable(tableNode, 0); expect(tableNode.rowColors, { '1': '0xFF0000FF', }); expect(tableNode.rowAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); }); @@ -118,14 +118,14 @@ void main() { align: TableAlign.center, ); expect(tableNode.rowAligns, { - '0': TableAlign.center.name, + '0': TableAlign.center.key, }); await editorState.insertRowInTable(tableNode, 1); expect(tableNode.rowColors, { '0': '0xFF0000FF', }); expect(tableNode.rowAligns, { - '0': TableAlign.center.name, + '0': TableAlign.center.key, }); }); @@ -149,14 +149,14 @@ void main() { '0': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '0': TableAlign.center.name, + '0': TableAlign.center.key, }); await editorState.insertColumnInTable(tableNode, 0); expect(tableNode.columnColors, { '1': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '1': TableAlign.center.name, + '1': TableAlign.center.key, }); }); @@ -180,14 +180,14 @@ void main() { '0': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '0': TableAlign.center.name, + '0': TableAlign.center.key, }); await editorState.insertColumnInTable(tableNode, 1); expect(tableNode.columnColors, { '0': '0xFF0000FF', }); expect(tableNode.columnAligns, { - '0': TableAlign.center.name, + '0': TableAlign.center.key, }); }); }); diff --git a/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_style_operation_test.dart b/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_style_operation_test.dart index 2b20276d37..54b3b93660 100644 --- a/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_style_operation_test.dart +++ b/frontend/appflowy_flutter/test/unit_test/simple_table/simple_table_style_operation_test.dart @@ -100,9 +100,9 @@ void main() { ); } expect(tableNode.columnAligns, { - '0': TableAlign.center.name, - '1': TableAlign.center.name, - '2': TableAlign.center.name, + '0': TableAlign.center.key, + '1': TableAlign.center.key, + '2': TableAlign.center.key, }); }); @@ -124,8 +124,8 @@ void main() { } expect(tableNode.rowAligns, { - '0': TableAlign.center.name, - '1': TableAlign.center.name, + '0': TableAlign.center.key, + '1': TableAlign.center.key, }); });