Compare commits

...
3 Commits
Author SHA1 Message Date
Lucas 687121ff14 chore: upgrade rust version to 1.80.1 (#6916) 2024-12-03 21:38:28 +08:00
Lucas e32c584b3b fix: remove extra padding in table on mobile (#6915) 2024-12-03 20:41:52 +08:00
Lucas 64e4416f54 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
2024-12-03 17:27:59 +08:00
18 changed files with 185 additions and 84 deletions

No files matched your search

+1 -1
View File
@@ -7,7 +7,7 @@ on:
env:
FLUTTER_VERSION: "3.22.0"
RUST_TOOLCHAIN: "1.77.2"
RUST_TOOLCHAIN: "1.80.1"
jobs:
create-release:
+1 -1
View File
@@ -19,7 +19,7 @@ on:
env:
CARGO_TERM_COLOR: always
CLOUD_VERSION: 0.7.6-amd64
RUST_TOOLCHAIN: "1.77.2"
RUST_TOOLCHAIN: "1.80.1"
jobs:
self-hosted-job:
+1 -1
View File
@@ -11,7 +11,7 @@ on:
env:
CARGO_TERM_COLOR: always
FLUTTER_VERSION: "3.22.0"
RUST_TOOLCHAIN: "1.77.2"
RUST_TOOLCHAIN: "1.80.1"
jobs:
tests:
+2 -2
View File
@@ -11,7 +11,7 @@ on:
env:
NODE_VERSION: "18.16.0"
PNPM_VERSION: "8.5.0"
RUST_TOOLCHAIN: "1.77.2"
RUST_TOOLCHAIN: "1.80.1"
CARGO_MAKE_VERSION: "0.36.6"
CI: true
@@ -121,4 +121,4 @@ jobs:
with:
tauriScript: pnpm tauri
projectPath: frontend/appflowy_web_app
args: "--debug"
args: "--debug"
+3 -3
View File
@@ -7,7 +7,7 @@ on:
env:
NODE_VERSION: "18.16.0"
PNPM_VERSION: "8.5.0"
RUST_TOOLCHAIN: "1.77.2"
RUST_TOOLCHAIN: "1.80.1"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ ubuntu-20.04 ]
platform: [ubuntu-20.04]
runs-on: ${{ matrix.platform }}
@@ -108,4 +108,4 @@ jobs:
with:
tauriScript: pnpm tauri
projectPath: frontend/appflowy_tauri
args: "--debug"
args: "--debug"
+5 -6
View File
@@ -4,20 +4,19 @@ on:
workflow_dispatch:
inputs:
branch:
description: 'The branch to release'
description: "The branch to release"
required: true
default: 'main'
default: "main"
version:
description: 'The version to release'
description: "The version to release"
required: true
default: '0.0.0'
default: "0.0.0"
env:
NODE_VERSION: "18.16.0"
PNPM_VERSION: "8.5.0"
RUST_TOOLCHAIN: "1.77.2"
RUST_TOOLCHAIN: "1.80.1"
jobs:
publish-tauri:
permissions:
contents: write
+9
View File
@@ -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
@@ -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;
@@ -316,7 +316,17 @@ SimpleTableBlockComponentBuilder _buildSimpleTableBlockComponentBuilder(
BuildContext context,
BlockComponentConfiguration configuration,
) {
return SimpleTableBlockComponentBuilder(configuration: configuration);
final copiedConfiguration = configuration.copyWith(
padding: (node) {
final padding = configuration.padding(node);
if (UniversalPlatform.isDesktop) {
return padding;
} else {
return padding.copyWith(right: padding.left);
}
},
);
return SimpleTableBlockComponentBuilder(configuration: copiedConfiguration);
}
SimpleTableRowBlockComponentBuilder _buildSimpleTableRowBlockComponentBuilder(
@@ -92,9 +92,9 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage>
inlineMathEquationItem,
linkItem,
alignToolbarItem,
buildTextColorItem(),
buildHighlightColorItem(),
customizeFontToolbarItem,
buildTextColorItem()..isActive = showInAnyTextType,
buildHighlightColorItem()..isActive = showInAnyTextType,
customizeFontToolbarItem..isActive = showInAnyTextType,
];
late List<SelectionMenuItem> slashMenuItems;
@@ -164,6 +164,9 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage>
ToggleListBlockKeys.type,
CalloutBlockKeys.type,
TableBlockKeys.type,
SimpleTableBlockKeys.type,
SimpleTableCellBlockKeys.type,
SimpleTableRowBlockKeys.type,
]);
AppFlowyRichTextKeys.supportSliced.add(AppFlowyRichTextKeys.fontFamily);
@@ -5,6 +5,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/simple_tab
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:universal_platform/universal_platform.dart';
typedef SimpleTableColumnWidthMap = Map<String, double>;
typedef SimpleTableRowAlignMap = Map<String, String>;
@@ -187,25 +188,35 @@ class _SimpleTableBlockWidgetState extends State<SimpleTableBlockWidget>
@override
Widget build(BuildContext context) {
Widget child = Transform.translate(
offset: const Offset(
-SimpleTableConstants.tableLeftPadding,
offset: Offset(
UniversalPlatform.isDesktop
? -SimpleTableConstants.tableLeftPadding
: 0,
0,
),
child: _buildTable(),
);
child = Provider.value(
value: simpleTableContext,
child: MouseRegion(
onEnter: (event) =>
simpleTableContext.isHoveringOnTableBlock.value = true,
onExit: (event) {
simpleTableContext.isHoveringOnTableBlock.value = false;
},
child: child,
),
child = Container(
alignment: Alignment.topLeft,
padding: padding,
child: child,
);
if (UniversalPlatform.isDesktop) {
child = Provider.value(
value: simpleTableContext,
child: MouseRegion(
onEnter: (event) =>
simpleTableContext.isHoveringOnTableBlock.value = true,
onExit: (event) {
simpleTableContext.isHoveringOnTableBlock.value = false;
},
child: child,
),
);
}
if (widget.showActions && widget.actionBuilder != null) {
child = BlockComponentActionWrapper(
node: node,
@@ -218,6 +229,14 @@ class _SimpleTableBlockWidgetState extends State<SimpleTableBlockWidget>
}
Widget _buildTable() {
if (UniversalPlatform.isDesktop) {
return _buildDesktopTable();
} else {
return _buildMobileTable();
}
}
Widget _buildDesktopTable() {
// IntrinsicWidth and IntrinsicHeight are used to make the table size fit the content.
return MouseRegion(
onEnter: (event) => simpleTableContext.isHoveringOnTableArea.value = true,
@@ -256,24 +275,45 @@ class _SimpleTableBlockWidgetState extends State<SimpleTableBlockWidget>
),
),
),
SimpleTableAddColumnHoverButton(
editorState: editorState,
node: node,
),
SimpleTableAddRowHoverButton(
editorState: editorState,
tableNode: node,
),
SimpleTableAddColumnAndRowHoverButton(
editorState: editorState,
node: node,
),
if (UniversalPlatform.isDesktop) ...[
SimpleTableAddColumnHoverButton(
editorState: editorState,
node: node,
),
SimpleTableAddRowHoverButton(
editorState: editorState,
tableNode: node,
),
SimpleTableAddColumnAndRowHoverButton(
editorState: editorState,
node: node,
),
],
],
),
),
);
}
Widget _buildMobileTable() {
return Provider.value(
value: simpleTableContext,
child: SingleChildScrollView(
controller: scrollController,
scrollDirection: Axis.horizontal,
child: IntrinsicWidth(
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: _buildRows(),
),
),
),
),
);
}
List<Widget> _buildRows() {
final List<Widget> rows = [];
@@ -3,6 +3,7 @@ import 'package:appflowy/util/theme_extension.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
import 'package:universal_platform/universal_platform.dart';
const enableTableDebugLog = false;
@@ -166,10 +167,16 @@ class SimpleTableConstants {
static const addColumnAndRowButtonBottomPadding = 2.5 * addRowButtonPadding;
// Table cell
static const cellEdgePadding = EdgeInsets.symmetric(
horizontal: 9.0,
vertical: 2.0,
);
static EdgeInsets get cellEdgePadding => UniversalPlatform.isDesktop
? const EdgeInsets.symmetric(
horizontal: 9.0,
vertical: 2.0,
)
: const EdgeInsets.only(
left: 8.0,
right: 8.0,
bottom: 6.0,
);
static const cellBorderWidth = 1.0;
static const resizeHandleWidth = 3.0;
@@ -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) {
@@ -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);
@@ -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,
});
});
});
@@ -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,
});
});
});
@@ -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,
});
});
});
@@ -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,
});
});