mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-11-01 18:43:22 +00:00
feat: auto-dismiss collapsed handle on Android if no interaction occurs (#7088)
* feat: support auto-dismiss collapsed handle on Android * fix: hit test area of collasepd handle is too big * chore: upgrade appflowy_editor * fix: simple table issues on mobile * feat: highlight cell after insertion * test: text color and cell background color test * fix: sign_in_page_settings_test
This commit is contained in:
parent
92722d0922
commit
dfe994b341
@ -67,6 +67,7 @@ void main() {
|
|||||||
|
|
||||||
// open settings page to check the result
|
// open settings page to check the result
|
||||||
await tester.tapButton(settingsButton);
|
await tester.tapButton(settingsButton);
|
||||||
|
await tester.pumpAndSettle(const Duration(milliseconds: 250));
|
||||||
|
|
||||||
// check the server type
|
// check the server type
|
||||||
expect(
|
expect(
|
||||||
|
|||||||
@ -505,6 +505,10 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage>
|
|||||||
Position(path: lastNode.path),
|
Position(path: lastNode.path),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transaction.customSelectionType = SelectionType.inline;
|
||||||
|
transaction.reason = SelectionUpdateReason.uiEvent;
|
||||||
|
|
||||||
await editorState.apply(transaction);
|
await editorState.apply(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -104,6 +104,18 @@ extension TableMapOperation on Node {
|
|||||||
comparator: (iKey, index) => iKey >= index,
|
comparator: (iKey, index) => iKey >= index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final rowBoldAttributes = _remapSource(
|
||||||
|
this.rowBoldAttributes,
|
||||||
|
index,
|
||||||
|
comparator: (iKey, index) => iKey >= index,
|
||||||
|
);
|
||||||
|
|
||||||
|
final rowTextColors = _remapSource(
|
||||||
|
this.rowTextColors,
|
||||||
|
index,
|
||||||
|
comparator: (iKey, index) => iKey >= index,
|
||||||
|
);
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.rowColors,
|
SimpleTableBlockKeys.rowColors,
|
||||||
@ -112,6 +124,14 @@ extension TableMapOperation on Node {
|
|||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.rowAligns,
|
SimpleTableBlockKeys.rowAligns,
|
||||||
rowAligns,
|
rowAligns,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.rowBoldAttributes,
|
||||||
|
rowBoldAttributes,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.rowTextColors,
|
||||||
|
rowTextColors,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.warn('Failed to map row insertion attributes: $e');
|
Log.warn('Failed to map row insertion attributes: $e');
|
||||||
@ -167,6 +187,18 @@ extension TableMapOperation on Node {
|
|||||||
comparator: (iKey, index) => iKey >= index,
|
comparator: (iKey, index) => iKey >= index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final columnBoldAttributes = _remapSource(
|
||||||
|
this.columnBoldAttributes,
|
||||||
|
index,
|
||||||
|
comparator: (iKey, index) => iKey >= index,
|
||||||
|
);
|
||||||
|
|
||||||
|
final columnTextColors = _remapSource(
|
||||||
|
this.columnTextColors,
|
||||||
|
index,
|
||||||
|
comparator: (iKey, index) => iKey >= index,
|
||||||
|
);
|
||||||
|
|
||||||
final bool distributeColumnWidthsEvenly =
|
final bool distributeColumnWidthsEvenly =
|
||||||
attributes[SimpleTableBlockKeys.distributeColumnWidthsEvenly] ??
|
attributes[SimpleTableBlockKeys.distributeColumnWidthsEvenly] ??
|
||||||
false;
|
false;
|
||||||
@ -189,6 +221,14 @@ extension TableMapOperation on Node {
|
|||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.columnWidths,
|
SimpleTableBlockKeys.columnWidths,
|
||||||
columnWidths,
|
columnWidths,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.columnBoldAttributes,
|
||||||
|
columnBoldAttributes,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.columnTextColors,
|
||||||
|
columnTextColors,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.warn('Failed to map row insertion attributes: $e');
|
Log.warn('Failed to map row insertion attributes: $e');
|
||||||
@ -238,6 +278,18 @@ extension TableMapOperation on Node {
|
|||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final (rowBoldAttributes, duplicatedRowBoldAttribute) =
|
||||||
|
_findDuplicatedEntryAndRemap(
|
||||||
|
this.rowBoldAttributes,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
|
||||||
|
final (rowTextColors, duplicatedRowTextColor) =
|
||||||
|
_findDuplicatedEntryAndRemap(
|
||||||
|
this.rowTextColors,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.rowColors,
|
SimpleTableBlockKeys.rowColors,
|
||||||
@ -248,6 +300,16 @@ extension TableMapOperation on Node {
|
|||||||
SimpleTableBlockKeys.rowAligns,
|
SimpleTableBlockKeys.rowAligns,
|
||||||
rowAligns,
|
rowAligns,
|
||||||
duplicatedEntry: duplicatedRowAlign,
|
duplicatedEntry: duplicatedRowAlign,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.rowBoldAttributes,
|
||||||
|
rowBoldAttributes,
|
||||||
|
duplicatedEntry: duplicatedRowBoldAttribute,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.rowTextColors,
|
||||||
|
rowTextColors,
|
||||||
|
duplicatedEntry: duplicatedRowTextColor,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.warn('Failed to map row insertion attributes: $e');
|
Log.warn('Failed to map row insertion attributes: $e');
|
||||||
@ -304,6 +366,18 @@ extension TableMapOperation on Node {
|
|||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final (columnBoldAttributes, duplicatedColumnBoldAttribute) =
|
||||||
|
_findDuplicatedEntryAndRemap(
|
||||||
|
this.columnBoldAttributes,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
|
||||||
|
final (columnTextColors, duplicatedColumnTextColor) =
|
||||||
|
_findDuplicatedEntryAndRemap(
|
||||||
|
this.columnTextColors,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.columnColors,
|
SimpleTableBlockKeys.columnColors,
|
||||||
@ -319,6 +393,16 @@ extension TableMapOperation on Node {
|
|||||||
SimpleTableBlockKeys.columnWidths,
|
SimpleTableBlockKeys.columnWidths,
|
||||||
columnWidths,
|
columnWidths,
|
||||||
duplicatedEntry: duplicatedColumnWidth,
|
duplicatedEntry: duplicatedColumnWidth,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.columnBoldAttributes,
|
||||||
|
columnBoldAttributes,
|
||||||
|
duplicatedEntry: duplicatedColumnBoldAttribute,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.columnTextColors,
|
||||||
|
columnTextColors,
|
||||||
|
duplicatedEntry: duplicatedColumnTextColor,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.warn('Failed to map column duplication attributes: $e');
|
Log.warn('Failed to map column duplication attributes: $e');
|
||||||
@ -364,6 +448,7 @@ extension TableMapOperation on Node {
|
|||||||
comparator: (iKey, index) => iKey > index,
|
comparator: (iKey, index) => iKey > index,
|
||||||
filterIndex: index,
|
filterIndex: index,
|
||||||
);
|
);
|
||||||
|
|
||||||
final columnAligns = _remapSource(
|
final columnAligns = _remapSource(
|
||||||
this.columnAligns,
|
this.columnAligns,
|
||||||
index,
|
index,
|
||||||
@ -371,6 +456,7 @@ extension TableMapOperation on Node {
|
|||||||
comparator: (iKey, index) => iKey > index,
|
comparator: (iKey, index) => iKey > index,
|
||||||
filterIndex: index,
|
filterIndex: index,
|
||||||
);
|
);
|
||||||
|
|
||||||
final columnWidths = _remapSource(
|
final columnWidths = _remapSource(
|
||||||
this.columnWidths,
|
this.columnWidths,
|
||||||
index,
|
index,
|
||||||
@ -379,6 +465,22 @@ extension TableMapOperation on Node {
|
|||||||
filterIndex: index,
|
filterIndex: index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final columnBoldAttributes = _remapSource(
|
||||||
|
this.columnBoldAttributes,
|
||||||
|
index,
|
||||||
|
increment: false,
|
||||||
|
comparator: (iKey, index) => iKey > index,
|
||||||
|
filterIndex: index,
|
||||||
|
);
|
||||||
|
|
||||||
|
final columnTextColors = _remapSource(
|
||||||
|
this.columnTextColors,
|
||||||
|
index,
|
||||||
|
increment: false,
|
||||||
|
comparator: (iKey, index) => iKey > index,
|
||||||
|
filterIndex: index,
|
||||||
|
);
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.columnColors,
|
SimpleTableBlockKeys.columnColors,
|
||||||
@ -391,6 +493,14 @@ extension TableMapOperation on Node {
|
|||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.columnWidths,
|
SimpleTableBlockKeys.columnWidths,
|
||||||
columnWidths,
|
columnWidths,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.columnBoldAttributes,
|
||||||
|
columnBoldAttributes,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.columnTextColors,
|
||||||
|
columnTextColors,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.warn('Failed to map column deletion attributes: $e');
|
Log.warn('Failed to map column deletion attributes: $e');
|
||||||
@ -443,6 +553,22 @@ extension TableMapOperation on Node {
|
|||||||
filterIndex: index,
|
filterIndex: index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final rowBoldAttributes = _remapSource(
|
||||||
|
this.rowBoldAttributes,
|
||||||
|
index,
|
||||||
|
increment: false,
|
||||||
|
comparator: (iKey, index) => iKey > index,
|
||||||
|
filterIndex: index,
|
||||||
|
);
|
||||||
|
|
||||||
|
final rowTextColors = _remapSource(
|
||||||
|
this.rowTextColors,
|
||||||
|
index,
|
||||||
|
increment: false,
|
||||||
|
comparator: (iKey, index) => iKey > index,
|
||||||
|
filterIndex: index,
|
||||||
|
);
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.rowColors,
|
SimpleTableBlockKeys.rowColors,
|
||||||
@ -451,6 +577,14 @@ extension TableMapOperation on Node {
|
|||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.rowAligns,
|
SimpleTableBlockKeys.rowAligns,
|
||||||
rowAligns,
|
rowAligns,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.rowBoldAttributes,
|
||||||
|
rowBoldAttributes,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.rowTextColors,
|
||||||
|
rowTextColors,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.warn('Failed to map row deletion attributes: $e');
|
Log.warn('Failed to map row deletion attributes: $e');
|
||||||
@ -531,6 +665,10 @@ extension TableMapOperation on Node {
|
|||||||
final duplicatedColumnColor = this.columnColors[fromIndex.toString()];
|
final duplicatedColumnColor = this.columnColors[fromIndex.toString()];
|
||||||
final duplicatedColumnAlign = this.columnAligns[fromIndex.toString()];
|
final duplicatedColumnAlign = this.columnAligns[fromIndex.toString()];
|
||||||
final duplicatedColumnWidth = this.columnWidths[fromIndex.toString()];
|
final duplicatedColumnWidth = this.columnWidths[fromIndex.toString()];
|
||||||
|
final duplicatedColumnBoldAttribute =
|
||||||
|
this.columnBoldAttributes[fromIndex.toString()];
|
||||||
|
final duplicatedColumnTextColor =
|
||||||
|
this.columnTextColors[fromIndex.toString()];
|
||||||
|
|
||||||
/// Case 1: fromIndex > toIndex
|
/// Case 1: fromIndex > toIndex
|
||||||
/// Before:
|
/// Before:
|
||||||
@ -619,6 +757,34 @@ extension TableMapOperation on Node {
|
|||||||
filterIndex: fromIndex,
|
filterIndex: fromIndex,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final columnBoldAttributes = _remapSource(
|
||||||
|
this.columnBoldAttributes,
|
||||||
|
fromIndex,
|
||||||
|
increment: fromIndex > toIndex,
|
||||||
|
comparator: (iKey, index) {
|
||||||
|
if (fromIndex > toIndex) {
|
||||||
|
return iKey < fromIndex && iKey >= toIndex;
|
||||||
|
} else {
|
||||||
|
return iKey > fromIndex && iKey <= toIndex;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filterIndex: fromIndex,
|
||||||
|
);
|
||||||
|
|
||||||
|
final columnTextColors = _remapSource(
|
||||||
|
this.columnTextColors,
|
||||||
|
fromIndex,
|
||||||
|
increment: fromIndex > toIndex,
|
||||||
|
comparator: (iKey, index) {
|
||||||
|
if (fromIndex > toIndex) {
|
||||||
|
return iKey < fromIndex && iKey >= toIndex;
|
||||||
|
} else {
|
||||||
|
return iKey > fromIndex && iKey <= toIndex;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filterIndex: fromIndex,
|
||||||
|
);
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.columnColors,
|
SimpleTableBlockKeys.columnColors,
|
||||||
@ -652,6 +818,28 @@ extension TableMapOperation on Node {
|
|||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
removeNullValue: true,
|
removeNullValue: true,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.columnBoldAttributes,
|
||||||
|
columnBoldAttributes,
|
||||||
|
duplicatedEntry: duplicatedColumnBoldAttribute != null
|
||||||
|
? MapEntry(
|
||||||
|
toIndex.toString(),
|
||||||
|
duplicatedColumnBoldAttribute,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
removeNullValue: true,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.columnTextColors,
|
||||||
|
columnTextColors,
|
||||||
|
duplicatedEntry: duplicatedColumnTextColor != null
|
||||||
|
? MapEntry(
|
||||||
|
toIndex.toString(),
|
||||||
|
duplicatedColumnTextColor,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
removeNullValue: true,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.warn('Failed to map column deletion attributes: $e');
|
Log.warn('Failed to map column deletion attributes: $e');
|
||||||
@ -667,6 +855,9 @@ extension TableMapOperation on Node {
|
|||||||
try {
|
try {
|
||||||
final duplicatedRowColor = this.rowColors[fromIndex.toString()];
|
final duplicatedRowColor = this.rowColors[fromIndex.toString()];
|
||||||
final duplicatedRowAlign = this.rowAligns[fromIndex.toString()];
|
final duplicatedRowAlign = this.rowAligns[fromIndex.toString()];
|
||||||
|
final duplicatedRowBoldAttribute =
|
||||||
|
this.rowBoldAttributes[fromIndex.toString()];
|
||||||
|
final duplicatedRowTextColor = this.rowTextColors[fromIndex.toString()];
|
||||||
|
|
||||||
/// Example:
|
/// Example:
|
||||||
/// Case 1: fromIndex > toIndex
|
/// Case 1: fromIndex > toIndex
|
||||||
@ -742,6 +933,34 @@ extension TableMapOperation on Node {
|
|||||||
filterIndex: fromIndex,
|
filterIndex: fromIndex,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final rowBoldAttributes = _remapSource(
|
||||||
|
this.rowBoldAttributes,
|
||||||
|
fromIndex,
|
||||||
|
increment: fromIndex > toIndex,
|
||||||
|
comparator: (iKey, index) {
|
||||||
|
if (fromIndex > toIndex) {
|
||||||
|
return iKey < fromIndex && iKey >= toIndex;
|
||||||
|
} else {
|
||||||
|
return iKey > fromIndex && iKey <= toIndex;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filterIndex: fromIndex,
|
||||||
|
);
|
||||||
|
|
||||||
|
final rowTextColors = _remapSource(
|
||||||
|
this.rowTextColors,
|
||||||
|
fromIndex,
|
||||||
|
increment: fromIndex > toIndex,
|
||||||
|
comparator: (iKey, index) {
|
||||||
|
if (fromIndex > toIndex) {
|
||||||
|
return iKey < fromIndex && iKey >= toIndex;
|
||||||
|
} else {
|
||||||
|
return iKey > fromIndex && iKey <= toIndex;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filterIndex: fromIndex,
|
||||||
|
);
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
.mergeValues(
|
.mergeValues(
|
||||||
SimpleTableBlockKeys.rowColors,
|
SimpleTableBlockKeys.rowColors,
|
||||||
@ -764,6 +983,28 @@ extension TableMapOperation on Node {
|
|||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
removeNullValue: true,
|
removeNullValue: true,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.rowBoldAttributes,
|
||||||
|
rowBoldAttributes,
|
||||||
|
duplicatedEntry: duplicatedRowBoldAttribute != null
|
||||||
|
? MapEntry(
|
||||||
|
toIndex.toString(),
|
||||||
|
duplicatedRowBoldAttribute,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
removeNullValue: true,
|
||||||
|
)
|
||||||
|
.mergeValues(
|
||||||
|
SimpleTableBlockKeys.rowTextColors,
|
||||||
|
rowTextColors,
|
||||||
|
duplicatedEntry: duplicatedRowTextColor != null
|
||||||
|
? MapEntry(
|
||||||
|
toIndex.toString(),
|
||||||
|
duplicatedRowTextColor,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
removeNullValue: true,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.warn('Failed to map row reordering attributes: $e');
|
Log.warn('Failed to map row reordering attributes: $e');
|
||||||
|
|||||||
@ -455,6 +455,21 @@ class _SimpleTableMoreActionItemState extends State<SimpleTableMoreActionItem> {
|
|||||||
final columnIndex = node.columnIndex;
|
final columnIndex = node.columnIndex;
|
||||||
final editorState = context.read<EditorState>();
|
final editorState = context.read<EditorState>();
|
||||||
editorState.insertColumnInTable(table, columnIndex);
|
editorState.insertColumnInTable(table, columnIndex);
|
||||||
|
|
||||||
|
final cell = table.getTableCellNode(
|
||||||
|
rowIndex: 0,
|
||||||
|
columnIndex: columnIndex,
|
||||||
|
);
|
||||||
|
if (cell == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update selection
|
||||||
|
editorState.selection = Selection.collapsed(
|
||||||
|
Position(
|
||||||
|
path: cell.path.child(0),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _insertColumnRight() {
|
void _insertColumnRight() {
|
||||||
@ -466,6 +481,21 @@ class _SimpleTableMoreActionItemState extends State<SimpleTableMoreActionItem> {
|
|||||||
final columnIndex = node.columnIndex;
|
final columnIndex = node.columnIndex;
|
||||||
final editorState = context.read<EditorState>();
|
final editorState = context.read<EditorState>();
|
||||||
editorState.insertColumnInTable(table, columnIndex + 1);
|
editorState.insertColumnInTable(table, columnIndex + 1);
|
||||||
|
|
||||||
|
final cell = table.getTableCellNode(
|
||||||
|
rowIndex: 0,
|
||||||
|
columnIndex: columnIndex + 1,
|
||||||
|
);
|
||||||
|
if (cell == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update selection
|
||||||
|
editorState.selection = Selection.collapsed(
|
||||||
|
Position(
|
||||||
|
path: cell.path.child(0),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _insertRowAbove() {
|
void _insertRowAbove() {
|
||||||
@ -477,6 +507,18 @@ class _SimpleTableMoreActionItemState extends State<SimpleTableMoreActionItem> {
|
|||||||
final rowIndex = node.rowIndex;
|
final rowIndex = node.rowIndex;
|
||||||
final editorState = context.read<EditorState>();
|
final editorState = context.read<EditorState>();
|
||||||
editorState.insertRowInTable(table, rowIndex);
|
editorState.insertRowInTable(table, rowIndex);
|
||||||
|
|
||||||
|
final cell = table.getTableCellNode(rowIndex: rowIndex, columnIndex: 0);
|
||||||
|
if (cell == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update selection
|
||||||
|
editorState.selection = Selection.collapsed(
|
||||||
|
Position(
|
||||||
|
path: cell.path.child(0),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _insertRowBelow() {
|
void _insertRowBelow() {
|
||||||
@ -488,6 +530,18 @@ class _SimpleTableMoreActionItemState extends State<SimpleTableMoreActionItem> {
|
|||||||
final rowIndex = node.rowIndex;
|
final rowIndex = node.rowIndex;
|
||||||
final editorState = context.read<EditorState>();
|
final editorState = context.read<EditorState>();
|
||||||
editorState.insertRowInTable(table, rowIndex + 1);
|
editorState.insertRowInTable(table, rowIndex + 1);
|
||||||
|
|
||||||
|
final cell = table.getTableCellNode(rowIndex: rowIndex + 1, columnIndex: 0);
|
||||||
|
if (cell == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update selection
|
||||||
|
editorState.selection = Selection.collapsed(
|
||||||
|
Position(
|
||||||
|
path: cell.path.child(0),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _deleteRow() {
|
void _deleteRow() {
|
||||||
|
|||||||
@ -166,9 +166,10 @@ class EditorStyleCustomizer {
|
|||||||
applyHeightToLastDescent: true,
|
applyHeightToLastDescent: true,
|
||||||
),
|
),
|
||||||
textSpanDecorator: customizeAttributeDecorator,
|
textSpanDecorator: customizeAttributeDecorator,
|
||||||
mobileDragHandleBallSize: const Size.square(12.0),
|
|
||||||
magnifierSize: const Size(144, 96),
|
magnifierSize: const Size(144, 96),
|
||||||
textScaleFactor: textScaleFactor,
|
textScaleFactor: textScaleFactor,
|
||||||
|
mobileDragHandleLeftExtend: 12.0,
|
||||||
|
mobileDragHandleWidthExtend: 24.0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,8 +61,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: c68e5f6
|
ref: cfb8b1b
|
||||||
resolved-ref: c68e5f6c585205083e27e875b822656425b2853f
|
resolved-ref: cfb8b1b6eb06f73a4fb297b6fd1d54b0ccec2922
|
||||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||||
source: git
|
source: git
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
|
|||||||
@ -174,7 +174,7 @@ dependency_overrides:
|
|||||||
appflowy_editor:
|
appflowy_editor:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||||
ref: "c68e5f6"
|
ref: "cfb8b1b"
|
||||||
|
|
||||||
appflowy_editor_plugins:
|
appflowy_editor_plugins:
|
||||||
git:
|
git:
|
||||||
|
|||||||
@ -170,5 +170,67 @@ void main() {
|
|||||||
'0': TableAlign.center.key,
|
'0': TableAlign.center.key,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('delete a column with text color & bold style (1)', () async {
|
||||||
|
final (editorState, tableNode) = createEditorStateAndTable(
|
||||||
|
rowCount: 3,
|
||||||
|
columnCount: 4,
|
||||||
|
);
|
||||||
|
// delete the column 1
|
||||||
|
final tableCellNode =
|
||||||
|
tableNode.getTableCellNode(rowIndex: 0, columnIndex: 1);
|
||||||
|
await editorState.updateColumnTextColor(
|
||||||
|
tableCellNode: tableCellNode!,
|
||||||
|
color: '0xFF0000FF',
|
||||||
|
);
|
||||||
|
await editorState.toggleColumnBoldAttribute(
|
||||||
|
tableCellNode: tableCellNode,
|
||||||
|
isBold: true,
|
||||||
|
);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'1': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'1': true,
|
||||||
|
});
|
||||||
|
await editorState.deleteColumnInTable(tableNode, 0);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'0': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'0': true,
|
||||||
|
});
|
||||||
|
expect(tableNode.rowLength, 3);
|
||||||
|
expect(tableNode.columnLength, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('delete a column with text color & bold style (2)', () async {
|
||||||
|
final (editorState, tableNode) = createEditorStateAndTable(
|
||||||
|
rowCount: 3,
|
||||||
|
columnCount: 4,
|
||||||
|
);
|
||||||
|
// delete the column 1
|
||||||
|
final tableCellNode =
|
||||||
|
tableNode.getTableCellNode(rowIndex: 0, columnIndex: 1);
|
||||||
|
await editorState.updateColumnTextColor(
|
||||||
|
tableCellNode: tableCellNode!,
|
||||||
|
color: '0xFF0000FF',
|
||||||
|
);
|
||||||
|
await editorState.toggleColumnBoldAttribute(
|
||||||
|
tableCellNode: tableCellNode,
|
||||||
|
isBold: true,
|
||||||
|
);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'1': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'1': true,
|
||||||
|
});
|
||||||
|
await editorState.deleteColumnInTable(tableNode, 1);
|
||||||
|
expect(tableNode.columnTextColors, {});
|
||||||
|
expect(tableNode.columnBoldAttributes, {});
|
||||||
|
expect(tableNode.rowLength, 3);
|
||||||
|
expect(tableNode.columnLength, 3);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -161,5 +161,69 @@ void main() {
|
|||||||
'1': TableAlign.center.key,
|
'1': TableAlign.center.key,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('duplicate a column with text color & bold style (1)', () async {
|
||||||
|
final (editorState, tableNode) = createEditorStateAndTable(
|
||||||
|
rowCount: 3,
|
||||||
|
columnCount: 4,
|
||||||
|
);
|
||||||
|
// duplicate the column 1
|
||||||
|
final tableCellNode =
|
||||||
|
tableNode.getTableCellNode(rowIndex: 0, columnIndex: 1);
|
||||||
|
await editorState.updateColumnTextColor(
|
||||||
|
tableCellNode: tableCellNode!,
|
||||||
|
color: '0xFF0000FF',
|
||||||
|
);
|
||||||
|
await editorState.toggleColumnBoldAttribute(
|
||||||
|
tableCellNode: tableCellNode,
|
||||||
|
isBold: true,
|
||||||
|
);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'1': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'1': true,
|
||||||
|
});
|
||||||
|
await editorState.duplicateColumnInTable(tableNode, 1);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'1': '0xFF0000FF',
|
||||||
|
'2': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'1': true,
|
||||||
|
'2': true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('duplicate a column with text color & bold style (2)', () async {
|
||||||
|
final (editorState, tableNode) = createEditorStateAndTable(
|
||||||
|
rowCount: 3,
|
||||||
|
columnCount: 4,
|
||||||
|
);
|
||||||
|
// duplicate the column 1
|
||||||
|
final tableCellNode =
|
||||||
|
tableNode.getTableCellNode(rowIndex: 0, columnIndex: 1);
|
||||||
|
await editorState.updateColumnTextColor(
|
||||||
|
tableCellNode: tableCellNode!,
|
||||||
|
color: '0xFF0000FF',
|
||||||
|
);
|
||||||
|
await editorState.toggleColumnBoldAttribute(
|
||||||
|
tableCellNode: tableCellNode,
|
||||||
|
isBold: true,
|
||||||
|
);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'1': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'1': true,
|
||||||
|
});
|
||||||
|
await editorState.duplicateColumnInTable(tableNode, 0);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'2': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'2': true,
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -190,5 +190,67 @@ void main() {
|
|||||||
'0': TableAlign.center.key,
|
'0': TableAlign.center.key,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('insert a column with text color & bold style (1)', () async {
|
||||||
|
final (editorState, tableNode) = createEditorStateAndTable(
|
||||||
|
rowCount: 2,
|
||||||
|
columnCount: 3,
|
||||||
|
);
|
||||||
|
// insert the column at the first position
|
||||||
|
final tableCellNode =
|
||||||
|
tableNode.getTableCellNode(rowIndex: 0, columnIndex: 0);
|
||||||
|
await editorState.updateColumnTextColor(
|
||||||
|
tableCellNode: tableCellNode!,
|
||||||
|
color: '0xFF0000FF',
|
||||||
|
);
|
||||||
|
await editorState.toggleColumnBoldAttribute(
|
||||||
|
tableCellNode: tableCellNode,
|
||||||
|
isBold: true,
|
||||||
|
);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'0': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'0': true,
|
||||||
|
});
|
||||||
|
await editorState.insertColumnInTable(tableNode, 0);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'1': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'1': true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insert a column with text color & bold style (2)', () async {
|
||||||
|
final (editorState, tableNode) = createEditorStateAndTable(
|
||||||
|
rowCount: 2,
|
||||||
|
columnCount: 3,
|
||||||
|
);
|
||||||
|
// insert the column at the first position
|
||||||
|
final tableCellNode =
|
||||||
|
tableNode.getTableCellNode(rowIndex: 0, columnIndex: 0);
|
||||||
|
await editorState.updateColumnTextColor(
|
||||||
|
tableCellNode: tableCellNode!,
|
||||||
|
color: '0xFF0000FF',
|
||||||
|
);
|
||||||
|
await editorState.toggleColumnBoldAttribute(
|
||||||
|
tableCellNode: tableCellNode,
|
||||||
|
isBold: true,
|
||||||
|
);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'0': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'0': true,
|
||||||
|
});
|
||||||
|
await editorState.insertColumnInTable(tableNode, 1);
|
||||||
|
expect(tableNode.columnTextColors, {
|
||||||
|
'0': '0xFF0000FF',
|
||||||
|
});
|
||||||
|
expect(tableNode.columnBoldAttributes, {
|
||||||
|
'0': true,
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user