chore: release version 0.7.6 (#6910)

* chore: update changelog

* feat: support displaying text color, background color and font item in table cell

* fix: integration test and unit test
This commit is contained in:
Lucas 2024-12-03 17:27:59 +08:00 committed by GitHub
parent ca195887e0
commit 64e4416f54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 91 additions and 42 deletions

View File

@ -1,4 +1,13 @@
# Release Notes # 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 ## Version 0.7.5 - 25/11/2024
### Bug Fixes ### Bug Fixes
- Improved chat response parsing - Improved chat response parsing

View File

@ -115,19 +115,41 @@ void main() {
await tester.editor.tapLineOfEditorAt(0); await tester.editor.tapLineOfEditorAt(0);
await tester.insertTableInDocument(); await tester.insertTableInDocument();
// hover on the table // add a new row
final tableBlock = find.byType(SimpleTableBlockWidget).first; final row = find.byWidgetPredicate((w) {
return w is SimpleTableRowBlockWidget && w.node.rowIndex == 1;
});
await tester.hoverOnWidget( await tester.hoverOnWidget(
tableBlock, row,
onHover: () async { onHover: () async {
// click the add row button
final addRowButton = find.byType(SimpleTableAddRowButton).first; final addRowButton = find.byType(SimpleTableAddRowButton).first;
await tester.tap(addRowButton); 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; final addColumnButton = find.byType(SimpleTableAddColumnButton).first;
await tester.tap(addColumnButton); 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 // click the add row and column button
final addRowAndColumnButton = final addRowAndColumnButton =
find.byType(SimpleTableAddColumnAndRowButton).first; find.byType(SimpleTableAddColumnAndRowButton).first;

View File

@ -92,9 +92,9 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage>
inlineMathEquationItem, inlineMathEquationItem,
linkItem, linkItem,
alignToolbarItem, alignToolbarItem,
buildTextColorItem(), buildTextColorItem()..isActive = showInAnyTextType,
buildHighlightColorItem(), buildHighlightColorItem()..isActive = showInAnyTextType,
customizeFontToolbarItem, customizeFontToolbarItem..isActive = showInAnyTextType,
]; ];
late List<SelectionMenuItem> slashMenuItems; late List<SelectionMenuItem> slashMenuItems;
@ -164,6 +164,9 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage>
ToggleListBlockKeys.type, ToggleListBlockKeys.type,
CalloutBlockKeys.type, CalloutBlockKeys.type,
TableBlockKeys.type, TableBlockKeys.type,
SimpleTableBlockKeys.type,
SimpleTableCellBlockKeys.type,
SimpleTableRowBlockKeys.type,
]); ]);
AppFlowyRichTextKeys.supportSliced.add(AppFlowyRichTextKeys.fontFamily); AppFlowyRichTextKeys.supportSliced.add(AppFlowyRichTextKeys.fontFamily);

View File

@ -202,8 +202,12 @@ class _SimpleTableBlockWidgetState extends State<SimpleTableBlockWidget>
onExit: (event) { onExit: (event) {
simpleTableContext.isHoveringOnTableBlock.value = false; simpleTableContext.isHoveringOnTableBlock.value = false;
}, },
child: Container(
alignment: Alignment.topLeft,
padding: padding,
child: child, child: child,
), ),
),
); );
if (widget.showActions && widget.actionBuilder != null) { if (widget.showActions && widget.actionBuilder != null) {

View File

@ -16,6 +16,17 @@ enum TableAlign {
right; right;
String get name => switch (this) { 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.left => 'left',
TableAlign.center => 'center', TableAlign.center => 'center',
TableAlign.right => 'right', TableAlign.right => 'right',
@ -130,7 +141,7 @@ extension TableNodeExtension on Node {
parentTableNode.attributes[SimpleTableBlockKeys.rowAligns]; parentTableNode.attributes[SimpleTableBlockKeys.rowAligns];
final align = rowAligns?[rowIndex.toString()]; final align = rowAligns?[rowIndex.toString()];
return TableAlign.values.firstWhere( return TableAlign.values.firstWhere(
(e) => e.name == align, (e) => e.key == align,
orElse: () => TableAlign.left, orElse: () => TableAlign.left,
); );
} catch (e) { } catch (e) {
@ -151,7 +162,7 @@ extension TableNodeExtension on Node {
parentTableNode.attributes[SimpleTableBlockKeys.columnAligns]; parentTableNode.attributes[SimpleTableBlockKeys.columnAligns];
final align = columnAligns?[columnIndex.toString()]; final align = columnAligns?[columnIndex.toString()];
return TableAlign.values.firstWhere( return TableAlign.values.firstWhere(
(e) => e.name == align, (e) => e.key == align,
orElse: () => TableAlign.left, orElse: () => TableAlign.left,
); );
} catch (e) { } catch (e) {

View File

@ -129,7 +129,7 @@ extension TableOptionOperation on EditorState {
final attributes = parentTableNode.attributes.mergeValues( final attributes = parentTableNode.attributes.mergeValues(
SimpleTableBlockKeys.columnAligns, SimpleTableBlockKeys.columnAligns,
parentTableNode.columnAligns, parentTableNode.columnAligns,
duplicatedEntry: MapEntry(columnIndex.toString(), align.name), duplicatedEntry: MapEntry(columnIndex.toString(), align.key),
); );
transaction.updateNode(parentTableNode, attributes); transaction.updateNode(parentTableNode, attributes);
await apply(transaction); await apply(transaction);
@ -167,7 +167,7 @@ extension TableOptionOperation on EditorState {
final attributes = parentTableNode.attributes.mergeValues( final attributes = parentTableNode.attributes.mergeValues(
SimpleTableBlockKeys.rowAligns, SimpleTableBlockKeys.rowAligns,
parentTableNode.rowAligns, parentTableNode.rowAligns,
duplicatedEntry: MapEntry(rowIndex.toString(), align.name), duplicatedEntry: MapEntry(rowIndex.toString(), align.key),
); );
transaction.updateNode(parentTableNode, attributes); transaction.updateNode(parentTableNode, attributes);
await apply(transaction); await apply(transaction);

View File

@ -67,7 +67,7 @@ void main() {
align: TableAlign.center, align: TableAlign.center,
); );
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
await editorState.deleteRowInTable(tableNode, 1); await editorState.deleteRowInTable(tableNode, 1);
expect(tableNode.rowLength, 2); expect(tableNode.rowLength, 2);
@ -96,7 +96,7 @@ void main() {
align: TableAlign.center, align: TableAlign.center,
); );
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
await editorState.deleteRowInTable(tableNode, 0); await editorState.deleteRowInTable(tableNode, 0);
expect(tableNode.rowLength, 2); expect(tableNode.rowLength, 2);
@ -105,7 +105,7 @@ void main() {
'0': '0xFF0000FF', '0': '0xFF0000FF',
}); });
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
}); });
}); });
@ -129,7 +129,7 @@ void main() {
align: TableAlign.center, align: TableAlign.center,
); );
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
await editorState.deleteColumnInTable(tableNode, 1); await editorState.deleteColumnInTable(tableNode, 1);
expect(tableNode.rowLength, 3); expect(tableNode.rowLength, 3);
@ -158,7 +158,7 @@ void main() {
align: TableAlign.center, align: TableAlign.center,
); );
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
await editorState.deleteColumnInTable(tableNode, 0); await editorState.deleteColumnInTable(tableNode, 0);
expect(tableNode.rowLength, 3); expect(tableNode.rowLength, 3);
@ -167,7 +167,7 @@ void main() {
'0': '0xFF0000FF', '0': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
}); });
}); });
}); });

View File

@ -54,7 +54,7 @@ void main() {
align: TableAlign.center, align: TableAlign.center,
); );
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
await editorState.duplicateRowInTable(tableNode, 1); await editorState.duplicateRowInTable(tableNode, 1);
expect(tableCellNode.rowColors, { expect(tableCellNode.rowColors, {
@ -62,8 +62,8 @@ void main() {
'2': '0xFF0000FF', '2': '0xFF0000FF',
}); });
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
'2': TableAlign.center.name, '2': TableAlign.center.key,
}); });
}); });
@ -87,14 +87,14 @@ void main() {
align: TableAlign.center, align: TableAlign.center,
); );
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
await editorState.duplicateRowInTable(tableNode, 2); await editorState.duplicateRowInTable(tableNode, 2);
expect(tableCellNode.rowColors, { expect(tableCellNode.rowColors, {
'1': '0xFF0000FF', '1': '0xFF0000FF',
}); });
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
}); });
@ -118,7 +118,7 @@ void main() {
'1': '0xFF0000FF', '1': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
await editorState.duplicateColumnInTable(tableNode, 1); await editorState.duplicateColumnInTable(tableNode, 1);
expect(tableCellNode.columnColors, { expect(tableCellNode.columnColors, {
@ -126,8 +126,8 @@ void main() {
'2': '0xFF0000FF', '2': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
'2': TableAlign.center.name, '2': TableAlign.center.key,
}); });
}); });
@ -151,14 +151,14 @@ void main() {
'1': '0xFF0000FF', '1': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
await editorState.duplicateColumnInTable(tableNode, 2); await editorState.duplicateColumnInTable(tableNode, 2);
expect(tableCellNode.columnColors, { expect(tableCellNode.columnColors, {
'1': '0xFF0000FF', '1': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
}); });
}); });

View File

@ -87,14 +87,14 @@ void main() {
align: TableAlign.center, align: TableAlign.center,
); );
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
}); });
await editorState.insertRowInTable(tableNode, 0); await editorState.insertRowInTable(tableNode, 0);
expect(tableNode.rowColors, { expect(tableNode.rowColors, {
'1': '0xFF0000FF', '1': '0xFF0000FF',
}); });
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
}); });
@ -118,14 +118,14 @@ void main() {
align: TableAlign.center, align: TableAlign.center,
); );
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
}); });
await editorState.insertRowInTable(tableNode, 1); await editorState.insertRowInTable(tableNode, 1);
expect(tableNode.rowColors, { expect(tableNode.rowColors, {
'0': '0xFF0000FF', '0': '0xFF0000FF',
}); });
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
}); });
}); });
@ -149,14 +149,14 @@ void main() {
'0': '0xFF0000FF', '0': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
}); });
await editorState.insertColumnInTable(tableNode, 0); await editorState.insertColumnInTable(tableNode, 0);
expect(tableNode.columnColors, { expect(tableNode.columnColors, {
'1': '0xFF0000FF', '1': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
}); });
@ -180,14 +180,14 @@ void main() {
'0': '0xFF0000FF', '0': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
}); });
await editorState.insertColumnInTable(tableNode, 1); await editorState.insertColumnInTable(tableNode, 1);
expect(tableNode.columnColors, { expect(tableNode.columnColors, {
'0': '0xFF0000FF', '0': '0xFF0000FF',
}); });
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
}); });
}); });
}); });

View File

@ -100,9 +100,9 @@ void main() {
); );
} }
expect(tableNode.columnAligns, { expect(tableNode.columnAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
'1': TableAlign.center.name, '1': TableAlign.center.key,
'2': TableAlign.center.name, '2': TableAlign.center.key,
}); });
}); });
@ -124,8 +124,8 @@ void main() {
} }
expect(tableNode.rowAligns, { expect(tableNode.rowAligns, {
'0': TableAlign.center.name, '0': TableAlign.center.key,
'1': TableAlign.center.name, '1': TableAlign.center.key,
}); });
}); });