Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: table plugin #62

Merged
merged 42 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
6951e1b
feat: table plugin requisites
zoli Apr 11, 2023
eff5444
feat: moved table plugin to appflowy-editor
zoli Apr 12, 2023
97e61b4
fix: flutter analyze
zoli Apr 12, 2023
1dc6bc4
fix: dont use nested maps in node attributes
zoli Apr 13, 2023
0346c89
feat: add table to appflowy editor default selection menu
zoli Apr 13, 2023
e15e07a
feat table markdown encoder
zoli Apr 13, 2023
bcea317
refactor: apply @Xazin review suggestions
zoli Apr 14, 2023
fa7d8e7
refactor: merge main and fix color picker conflicts
zoli Apr 14, 2023
04e083d
refactor: merge main, last merge i made mistake
zoli Apr 14, 2023
9665be1
feat: table markdown decoder
zoli Apr 15, 2023
d969384
fix: use specific backgroun generator for table
zoli Apr 15, 2023
aea642e
feat: table plugin
LucasXu0 Jun 23, 2023
752c32e
style: adapt new structure
zoli Jun 24, 2023
6d748df
fix: table columns border height
zoli Jun 24, 2023
a51f4a2
fix: adapt new style key commands
zoli Jun 24, 2023
0d74c64
style(merge): merge migrate_table_plugin branch
zoli Jun 24, 2023
ebfc6d3
fix: remove table context menu
zoli Jun 24, 2023
67b55b1
test: adapt to main branch changes
zoli Jun 25, 2023
20ac4f3
style: merge branch 'main' into feat/table-plugin
zoli Jun 25, 2023
cfe9c1f
fix: backspace handling regarding table
zoli Jun 25, 2023
b7746d7
fix: flutter analyze
zoli Jun 25, 2023
1819700
fix: enter when table cell is bullet list
zoli Jun 25, 2023
5434aa2
fix: selection bug on large table
zoli Jun 26, 2023
81950d3
feat: row/col action menu
zoli Jun 28, 2023
77849ba
style: merge branch 'main' into feat/table-plugin
zoli Jun 28, 2023
67f1419
fix: row action handler positioning
zoli Jun 28, 2023
394c3d7
refactor: merge row and col handler widget
zoli Jun 28, 2023
94d67f4
refactor: add size and color to handler icon
zoli Jun 28, 2023
a4eaa40
style(merge): merge main
zoli Jul 9, 2023
5449cbe
style(merge): merge main
zoli Jul 9, 2023
826c91b
style(merge): merge main
zoli Jul 14, 2023
868c137
style(merge): merge main and resolve conflicts
zoli Jul 19, 2023
5406f30
Merge branch 'main' into feat/table-plugin
LucasXu0 Aug 21, 2023
2751e4c
Merge branch 'main' into feat/table-plugin
LucasXu0 Aug 21, 2023
3f6cece
Merge branch 'main' into feat/table-plugin
zoli Aug 24, 2023
f5c45d4
feat: added padding and action wrapper
zoli Aug 24, 2023
082f092
feat: enable customizing icons and etc
zoli Aug 26, 2023
312fc94
feat: table menu builder
zoli Aug 27, 2023
2032f77
Merge remote-tracking branch 'origin/main' into feat/table-plugin
LucasXu0 Aug 28, 2023
ce0dd85
style: merge branch 'main' into feat/table-plugin
zoli Aug 28, 2023
c5f08d1
fix: table getBlockRect
zoli Aug 28, 2023
49c93ad
refactor: table action button design
zoli Aug 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/src/editor/block_component/block_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ export 'divider_block_component/divider_block_component.dart';
export 'divider_block_component/divider_character_shortcut.dart';
export 'divider_block_component/divider_menu_item.dart';

// table
export 'table_block_component/table_block_component.dart';
export 'table_block_component/table_cell_block_component.dart';
export 'table_block_component/table_commands.dart';
export 'table_block_component/table_action.dart';

// base
export 'base_component/convert_to_paragraph_command.dart';
export 'base_component/insert_newline_in_type_command.dart';
Expand Down
3 changes: 3 additions & 0 deletions lib/src/editor/block_component/standard_block_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ final Map<String, BlockComponentBuilder> standardBlockComponentBuilderMap = {
padding: (node) => const EdgeInsets.symmetric(vertical: 8.0),
),
),
TableBlockKeys.type: TableBlockComponentBuilder(),
TableCellBlockKeys.type: TableCellBlockComponentBuilder(),
};

final List<CharacterShortcutEvent> standardCharacterShortcutEvents = [
Expand Down Expand Up @@ -92,6 +94,7 @@ final List<CommandShortcutEvent> standardCommandShortcutEvents = [

// backspace
convertToParagraphCommand,
...tableCommands,
backspaceCommand,
deleteLeftWordCommand,
deleteLeftSentenceCommand,
Expand Down
350 changes: 350 additions & 0 deletions lib/src/editor/block_component/table_block_component/table_action.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,350 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/block_component/table_block_component/util.dart';

class TableActions {
const TableActions._();

Check warning on line 5 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L5

Added line #L5 was not covered by tests

static void add(
Node node,
int position,
Transaction transaction,
TableDirection dir,
) {
if (dir == TableDirection.col) {
_addCol(node, position, transaction);
} else {
_addRow(node, position, transaction);
}
}

static void delete(
Node node,
int position,
Transaction transaction,
TableDirection dir,
) {
if (dir == TableDirection.col) {
_deleteCol(node, position, transaction);
} else {
_deleteRow(node, position, transaction);
}
}

static void duplicate(
Node node,
int position,
Transaction transaction,
TableDirection dir,
) {
if (dir == TableDirection.col) {
_duplicateCol(node, position, transaction);
} else {
_duplicateRow(node, position, transaction);
}
}

static void clear(

Check warning on line 46 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L46

Added line #L46 was not covered by tests
Node node,
int position,
Transaction transaction,
TableDirection dir,
) {
if (dir == TableDirection.col) {
_clearCol(node, position, transaction);

Check warning on line 53 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L52-L53

Added lines #L52 - L53 were not covered by tests
} else {
_clearRow(node, position, transaction);

Check warning on line 55 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L55

Added line #L55 was not covered by tests
}
}

static void setBgColor(

Check warning on line 59 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L59

Added line #L59 was not covered by tests
Node node,
int position,
Transaction transaction,
String? color,
TableDirection dir,
) {
if (dir == TableDirection.col) {
_setColBgColor(node, position, transaction, color);

Check warning on line 67 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L66-L67

Added lines #L66 - L67 were not covered by tests
} else {
_setRowBgColor(node, position, transaction, color);

Check warning on line 69 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L69

Added line #L69 was not covered by tests
}
}
}

void _addCol(Node tableNode, int position, Transaction transaction) {
assert(position >= 0);

List<Node> cellNodes = [];
final int rowsLen = tableNode.attributes[TableBlockKeys.rowsLen],
colsLen = tableNode.attributes[TableBlockKeys.colsLen];

if (position != colsLen) {
for (var i = position; i < colsLen; i++) {
for (var j = 0; j < rowsLen; j++) {
final node = getCellNode(tableNode, i, j)!;
transaction.updateNode(node, {TableBlockKeys.colPosition: i + 1});

Check warning on line 85 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L82-L85

Added lines #L82 - L85 were not covered by tests
}
}
}

for (var i = 0; i < rowsLen; i++) {
final node = Node(
type: TableCellBlockKeys.type,
attributes: {
TableBlockKeys.colPosition: position,
TableBlockKeys.rowPosition: i,
},
);
node.insert(paragraphNode());

cellNodes.add(newCellNode(tableNode, node));
}

late Path insertPath;
if (position == 0) {
insertPath = getCellNode(tableNode, 0, 0)!.path;

Check warning on line 105 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L105

Added line #L105 was not covered by tests
} else {
insertPath = getCellNode(tableNode, position - 1, rowsLen - 1)!.path.next;
}
// TODO(zoli): this calls notifyListener rowsLen+1 times. isn't there a better
// way?
transaction.insertNodes(insertPath, cellNodes);
transaction.updateNode(tableNode, {TableBlockKeys.colsLen: colsLen + 1});
}

void _addRow(Node tableNode, int position, Transaction transaction) {
assert(position >= 0);

final int rowsLen = tableNode.attributes[TableBlockKeys.rowsLen],
colsLen = tableNode.attributes[TableBlockKeys.colsLen];

if (position != rowsLen) {
for (var i = position; i < rowsLen; i++) {
for (var j = 0; j < colsLen; j++) {
final node = getCellNode(tableNode, j, i)!;
transaction.updateNode(node, {TableBlockKeys.rowPosition: i + 1});

Check warning on line 125 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L122-L125

Added lines #L122 - L125 were not covered by tests
}
}
}

for (var i = 0; i < colsLen; i++) {
final node = Node(
type: TableCellBlockKeys.type,
attributes: {
TableBlockKeys.colPosition: i,
TableBlockKeys.rowPosition: position,
},
);
node.insert(paragraphNode());

late Path insertPath;
if (position == 0) {
insertPath = getCellNode(tableNode, i, 0)!.path;

Check warning on line 142 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L142

Added line #L142 was not covered by tests
} else {
insertPath = getCellNode(tableNode, i, position - 1)!.path.next;
}
transaction.insertNode(
insertPath,
newCellNode(tableNode, node),
);
}
transaction.updateNode(tableNode, {TableBlockKeys.rowsLen: rowsLen + 1});
}

void _deleteCol(Node tableNode, int col, Transaction transaction) {
final int rowsLen = tableNode.attributes[TableBlockKeys.rowsLen],
colsLen = tableNode.attributes[TableBlockKeys.colsLen];
List<Node> nodes = [];
for (var i = 0; i < rowsLen; i++) {
nodes.add(getCellNode(tableNode, col, i)!);
}
transaction.deleteNodes(nodes);

_updateCellPositions(tableNode, transaction, col + 1, 0, -1, 0);

transaction.updateNode(tableNode, {TableBlockKeys.colsLen: colsLen - 1});
}

void _deleteRow(Node tableNode, int row, Transaction transaction) {
final int rowsLen = tableNode.attributes[TableBlockKeys.rowsLen],
colsLen = tableNode.attributes[TableBlockKeys.colsLen];
List<Node> nodes = [];
for (var i = 0; i < colsLen; i++) {
nodes.add(getCellNode(tableNode, i, row)!);
}
transaction.deleteNodes(nodes);

_updateCellPositions(tableNode, transaction, 0, row + 1, 0, -1);

transaction.updateNode(tableNode, {TableBlockKeys.rowsLen: rowsLen - 1});
}

void _duplicateCol(Node tableNode, int col, Transaction transaction) {
final int rowsLen = tableNode.attributes[TableBlockKeys.rowsLen],
colsLen = tableNode.attributes[TableBlockKeys.colsLen];
List<Node> nodes = [];
for (var i = 0; i < rowsLen; i++) {
final node = getCellNode(tableNode, col, i)!;
nodes.add(
node.copyWith(
attributes: {
...node.attributes,
TableBlockKeys.colPosition: col + 1,
TableBlockKeys.rowPosition: i,
},
),
);
}
transaction.insertNodes(
getCellNode(tableNode, col, rowsLen - 1)!.path.next,
nodes,
);

_updateCellPositions(tableNode, transaction, col + 1, 0, 1, 0);

transaction.updateNode(tableNode, {TableBlockKeys.colsLen: colsLen + 1});
}

void _duplicateRow(Node tableNode, int row, Transaction transaction) {
final int rowsLen = tableNode.attributes[TableBlockKeys.rowsLen],
colsLen = tableNode.attributes[TableBlockKeys.colsLen];
for (var i = 0; i < colsLen; i++) {
final node = getCellNode(tableNode, i, row)!;
transaction.insertNode(
node.path.next,
node.copyWith(
attributes: {
...node.attributes,
TableBlockKeys.rowPosition: row + 1,
TableBlockKeys.colPosition: i,
},
),
);
}

_updateCellPositions(tableNode, transaction, 0, row + 1, 0, 1);

transaction.updateNode(tableNode, {TableBlockKeys.rowsLen: rowsLen + 1});
}

void _setColBgColor(

Check warning on line 230 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L230

Added line #L230 was not covered by tests
Node tableNode,
int col,
Transaction transaction,
String? color,
) {
final rowslen = tableNode.attributes[TableBlockKeys.rowsLen];
for (var i = 0; i < rowslen; i++) {
final node = getCellNode(tableNode, col, i)!;
transaction.updateNode(

Check warning on line 239 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L236-L239

Added lines #L236 - L239 were not covered by tests
node,
{TableBlockKeys.backgroundColor: color},

Check warning on line 241 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L241

Added line #L241 was not covered by tests
);
}
}

void _setRowBgColor(

Check warning on line 246 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L246

Added line #L246 was not covered by tests
Node tableNode,
int row,
Transaction transaction,
String? color,
) {
final colsLen = tableNode.attributes[TableBlockKeys.colsLen];
for (var i = 0; i < colsLen; i++) {
final node = getCellNode(tableNode, i, row)!;
transaction.updateNode(

Check warning on line 255 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L252-L255

Added lines #L252 - L255 were not covered by tests
node,
{TableBlockKeys.backgroundColor: color},

Check warning on line 257 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L257

Added line #L257 was not covered by tests
);
}
}

void _clearCol(

Check warning on line 262 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L262

Added line #L262 was not covered by tests
Node tableNode,
int col,
Transaction transaction,
) {
final rowsLen = tableNode.attributes[TableBlockKeys.rowsLen];
for (var i = 0; i < rowsLen; i++) {
final node = getCellNode(tableNode, col, i)!;
transaction.insertNode(
node.children.first.path,
paragraphNode(text: ''),

Check warning on line 272 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L267-L272

Added lines #L267 - L272 were not covered by tests
);
}
}

void _clearRow(

Check warning on line 277 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L277

Added line #L277 was not covered by tests
Node tableNode,
int row,
Transaction transaction,
) {
final colsLen = tableNode.attributes[TableBlockKeys.colsLen];
for (var i = 0; i < colsLen; i++) {
final node = getCellNode(tableNode, i, row)!;
transaction.insertNode(
node.children.first.path,
paragraphNode(text: ''),

Check warning on line 287 in lib/src/editor/block_component/table_block_component/table_action.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/editor/block_component/table_block_component/table_action.dart#L282-L287

Added lines #L282 - L287 were not covered by tests
);
}
}

dynamic newCellNode(Node tableNode, n) {
final row = n.attributes[TableBlockKeys.rowPosition] as int;
final col = n.attributes[TableBlockKeys.colPosition] as int;
final int rowsLen = tableNode.attributes[TableBlockKeys.rowsLen];
final int colsLen = tableNode.attributes[TableBlockKeys.colsLen];

if (!n.attributes.containsKey(TableBlockKeys.height)) {
double nodeHeight = double.tryParse(
tableNode.attributes[TableBlockKeys.rowDefaultHeight].toString(),
)!;
if (row < rowsLen) {
nodeHeight = double.tryParse(
getCellNode(tableNode, 0, row)!
.attributes[TableBlockKeys.height]
.toString(),
) ??
nodeHeight;
}
n.updateAttributes({TableBlockKeys.height: nodeHeight});
}

if (!n.attributes.containsKey(TableBlockKeys.width)) {
double nodeWidth = double.tryParse(
tableNode.attributes[TableBlockKeys.colDefaultWidth].toString(),
)!;
if (col < colsLen) {
nodeWidth = double.tryParse(
getCellNode(tableNode, col, 0)!
.attributes[TableBlockKeys.width]
.toString(),
) ??
nodeWidth;
}
n.updateAttributes({TableBlockKeys.width: nodeWidth});
}

return n;
}

void _updateCellPositions(
Node tableNode,
Transaction transaction,
int fromCol,
int fromRow,
int addToCol,
int addToRow,
) {
final int rowsLen = tableNode.attributes[TableBlockKeys.rowsLen],
colsLen = tableNode.attributes[TableBlockKeys.colsLen];

for (var i = fromCol; i < colsLen; i++) {
for (var j = fromRow; j < rowsLen; j++) {
transaction.updateNode(getCellNode(tableNode, i, j)!, {
TableBlockKeys.colPosition: i + addToCol,
TableBlockKeys.rowPosition: j + addToRow,
});
}
}
}