Skip to content

Commit 430e21a

Browse files
committed
fix: simple table issues and locale issues (#7138)
* fix: can't make changes on row or column of table * fix: fallback to en-US if the locale is invalid * chore: remove unused code * fix: simple table issues
1 parent 0c1eb73 commit 430e21a

File tree

15 files changed

+163
-56
lines changed

15 files changed

+163
-56
lines changed

frontend/appflowy_flutter/lib/plugins/document/application/document_collaborators_bloc.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ class DocumentCollaboratorsBloc
8585
final ids = <dynamic>{};
8686
final sorted = states.value.values.toList()
8787
..sort((a, b) => b.timestamp.compareTo(a.timestamp))
88-
..retainWhere((e) => ids.add(e.user.uid.toString() + e.user.deviceId));
88+
// filter the duplicate users
89+
..retainWhere((e) => ids.add(e.user.uid.toString() + e.user.deviceId))
90+
// only keep version 1 and metadata is not empty
91+
..retainWhere((e) => e.version == 1)
92+
..retainWhere((e) => e.metadata.isNotEmpty);
8993
for (final state in sorted) {
9094
if (state.version != 1) {
9195
continue;

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_configuration.dart

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,11 @@ ParagraphBlockComponentBuilder _buildParagraphBlockComponentBuilder(
399399
return ParagraphBlockComponentBuilder(
400400
configuration: configuration.copyWith(
401401
placeholderText: placeholderText,
402-
textStyle: (node) => _buildTextStyleInTableCell(
402+
textStyle: (node, {TextSpan? textSpan}) => _buildTextStyleInTableCell(
403403
context,
404404
node: node,
405405
configuration: configuration,
406+
textSpan: textSpan,
406407
),
407408
textAlign: (node) => _buildTextAlignInTableCell(
408409
context,
@@ -421,10 +422,11 @@ TodoListBlockComponentBuilder _buildTodoListBlockComponentBuilder(
421422
return TodoListBlockComponentBuilder(
422423
configuration: configuration.copyWith(
423424
placeholderText: (_) => LocaleKeys.blockPlaceholders_todoList.tr(),
424-
textStyle: (node) => _buildTextStyleInTableCell(
425+
textStyle: (node, {TextSpan? textSpan}) => _buildTextStyleInTableCell(
425426
context,
426427
node: node,
427428
configuration: configuration,
429+
textSpan: textSpan,
428430
),
429431
textAlign: (node) => _buildTextAlignInTableCell(
430432
context,
@@ -451,10 +453,11 @@ BulletedListBlockComponentBuilder _buildBulletedListBlockComponentBuilder(
451453
return BulletedListBlockComponentBuilder(
452454
configuration: configuration.copyWith(
453455
placeholderText: (_) => LocaleKeys.blockPlaceholders_bulletList.tr(),
454-
textStyle: (node) => _buildTextStyleInTableCell(
456+
textStyle: (node, {TextSpan? textSpan}) => _buildTextStyleInTableCell(
455457
context,
456458
node: node,
457459
configuration: configuration,
460+
textSpan: textSpan,
458461
),
459462
textAlign: (node) => _buildTextAlignInTableCell(
460463
context,
@@ -473,10 +476,11 @@ NumberedListBlockComponentBuilder _buildNumberedListBlockComponentBuilder(
473476
return NumberedListBlockComponentBuilder(
474477
configuration: configuration.copyWith(
475478
placeholderText: (_) => LocaleKeys.blockPlaceholders_numberList.tr(),
476-
textStyle: (node) => _buildTextStyleInTableCell(
479+
textStyle: (node, {TextSpan? textSpan}) => _buildTextStyleInTableCell(
477480
context,
478481
node: node,
479482
configuration: configuration,
483+
textSpan: textSpan,
480484
),
481485
textAlign: (node) => _buildTextAlignInTableCell(
482486
context,
@@ -507,10 +511,11 @@ QuoteBlockComponentBuilder _buildQuoteBlockComponentBuilder(
507511
return QuoteBlockComponentBuilder(
508512
configuration: configuration.copyWith(
509513
placeholderText: (_) => LocaleKeys.blockPlaceholders_quote.tr(),
510-
textStyle: (node) => _buildTextStyleInTableCell(
514+
textStyle: (node, {TextSpan? textSpan}) => _buildTextStyleInTableCell(
511515
context,
512516
node: node,
513517
configuration: configuration,
518+
textSpan: textSpan,
514519
),
515520
textAlign: (node) => _buildTextAlignInTableCell(
516521
context,
@@ -529,10 +534,11 @@ HeadingBlockComponentBuilder _buildHeadingBlockComponentBuilder(
529534
) {
530535
return HeadingBlockComponentBuilder(
531536
configuration: configuration.copyWith(
532-
textStyle: (node) => _buildTextStyleInTableCell(
537+
textStyle: (node, {TextSpan? textSpan}) => _buildTextStyleInTableCell(
533538
context,
534539
node: node,
535540
configuration: configuration,
541+
textSpan: textSpan,
536542
),
537543
padding: (node) {
538544
if (customHeadingPadding != null) {
@@ -698,10 +704,11 @@ CalloutBlockComponentBuilder _buildCalloutBlockComponentBuilder(
698704
node: node,
699705
configuration: configuration,
700706
),
701-
textStyle: (node) => _buildTextStyleInTableCell(
707+
textStyle: (node, {TextSpan? textSpan}) => _buildTextStyleInTableCell(
702708
context,
703709
node: node,
704710
configuration: configuration,
711+
textSpan: textSpan,
705712
),
706713
),
707714
inlinePadding: const EdgeInsets.symmetric(vertical: 8.0),
@@ -789,11 +796,12 @@ ToggleListBlockComponentBuilder _buildToggleListBlockComponentBuilder(
789796

790797
return const EdgeInsets.only(top: 12.0, bottom: 4.0);
791798
},
792-
textStyle: (node) {
799+
textStyle: (node, {TextSpan? textSpan}) {
793800
final textStyle = _buildTextStyleInTableCell(
794801
context,
795802
node: node,
796803
configuration: configuration,
804+
textSpan: textSpan,
797805
);
798806
final level = node.attributes[ToggleListBlockKeys.level] as int?;
799807
if (level == null) {
@@ -828,9 +836,14 @@ OutlineBlockComponentBuilder _buildOutlineBlockComponentBuilder(
828836
) {
829837
return OutlineBlockComponentBuilder(
830838
configuration: configuration.copyWith(
831-
placeholderTextStyle: (_) =>
839+
placeholderTextStyle: (node, {TextSpan? textSpan}) =>
832840
styleCustomizer.outlineBlockPlaceholderStyleBuilder(),
833-
padding: (_) => const EdgeInsets.only(top: 12.0, bottom: 4.0),
841+
padding: (node) {
842+
if (UniversalPlatform.isMobile) {
843+
return configuration.padding(node);
844+
}
845+
return const EdgeInsets.only(top: 12.0, bottom: 4.0);
846+
},
834847
),
835848
);
836849
}
@@ -877,7 +890,8 @@ SubPageBlockComponentBuilder _buildSubPageBlockComponentBuilder(
877890
}) {
878891
return SubPageBlockComponentBuilder(
879892
configuration: configuration.copyWith(
880-
textStyle: (node) => styleCustomizer.subPageBlockTextStyleBuilder(),
893+
textStyle: (node, {TextSpan? textSpan}) =>
894+
styleCustomizer.subPageBlockTextStyleBuilder(),
881895
padding: (node) {
882896
if (UniversalPlatform.isMobile) {
883897
return const EdgeInsets.symmetric(horizontal: 18);
@@ -892,8 +906,9 @@ TextStyle _buildTextStyleInTableCell(
892906
BuildContext context, {
893907
required Node node,
894908
required BlockComponentConfiguration configuration,
909+
required TextSpan? textSpan,
895910
}) {
896-
TextStyle textStyle = configuration.textStyle(node);
911+
TextStyle textStyle = configuration.textStyle(node, textSpan: textSpan);
897912

898913
if (node.isInHeaderColumn ||
899914
node.isInHeaderRow ||
@@ -906,6 +921,11 @@ TextStyle _buildTextStyleInTableCell(
906921

907922
final cellTextColor = node.textColorInColumn ?? node.textColorInRow;
908923

924+
// enable it if we need to support the text color of the text span
925+
// final isTextSpanColorNull = textSpan?.style?.color == null;
926+
// final isTextSpanChildrenColorNull =
927+
// textSpan?.children?.every((e) => e.style?.color == null) ?? true;
928+
909929
if (cellTextColor != null) {
910930
textStyle = textStyle.copyWith(
911931
color: buildEditorCustomizedColor(

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_drop_handler.dart

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart';
2-
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
3-
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
4-
import 'package:flutter/material.dart';
5-
61
import 'package:appflowy/plugins/document/presentation/editor_drop_manager.dart';
72
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/paste_from_file.dart';
83
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/paste_from_image.dart';
4+
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart';
5+
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
96
import 'package:appflowy/shared/patterns/file_type_patterns.dart';
7+
import 'package:appflowy/workspace/presentation/widgets/draggable_item/draggable_item.dart';
8+
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
109
import 'package:appflowy_editor/appflowy_editor.dart';
1110
import 'package:desktop_drop/desktop_drop.dart';
11+
import 'package:flutter/material.dart';
1212
import 'package:provider/provider.dart';
1313

1414
const _excludeFromDropTarget = [
1515
ImageBlockKeys.type,
1616
CustomImageBlockKeys.type,
1717
MultiImageBlockKeys.type,
1818
FileBlockKeys.type,
19+
SimpleTableBlockKeys.type,
20+
SimpleTableCellBlockKeys.type,
21+
SimpleTableRowBlockKeys.type,
1922
];
2023

2124
class EditorDropHandler extends StatelessWidget {
@@ -38,8 +41,13 @@ class EditorDropHandler extends StatelessWidget {
3841
Widget build(BuildContext context) {
3942
final childWidget = Consumer<EditorDropManagerState>(
4043
builder: (context, dropState, _) => DragTarget<ViewPB>(
41-
onLeave: (_) => editorState.selectionService.removeDropTarget(),
44+
onLeave: (_) {
45+
editorState.selectionService.removeDropTarget();
46+
disableAutoScrollWhenDragging = false;
47+
},
4248
onMove: (details) {
49+
disableAutoScrollWhenDragging = true;
50+
4351
if (details.data.id == viewId) {
4452
return;
4553
}

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/drag_to_reorder/util.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ bool shouldIgnoreDragTarget({
140140
}
141141

142142
final targetNode = editorState.getNodeAtPath(targetPath);
143-
if (targetNode != null && targetNode.isInTable) {
143+
if (targetNode != null &&
144+
targetNode.isInTable &&
145+
targetNode.type != SimpleTableBlockKeys.type) {
144146
return true;
145147
}
146148

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/drag_to_reorder/visual_drag_area.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class VisualDragArea extends StatelessWidget {
1616
final DragAreaBuilderData data;
1717
final Node dragNode;
1818
final EditorState editorState;
19+
1920
@override
2021
Widget build(BuildContext context) {
2122
final targetNode = data.targetNode;

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,10 @@ class _CalloutBlockComponentWidgetState
258258
placeholderText: placeholderText,
259259
textAlign: alignment?.toTextAlign ?? textAlign,
260260
textSpanDecorator: (textSpan) => textSpan.updateTextStyle(
261-
textStyle,
261+
textStyleWithTextSpan(textSpan: textSpan),
262262
),
263263
placeholderTextSpanDecorator: (textSpan) => textSpan.updateTextStyle(
264-
placeholderTextStyle,
264+
placeholderTextStyleWithTextSpan(textSpan: textSpan),
265265
),
266266
textDirection: textDirection,
267267
cursorColor: editorState.editorStyle.cursorColor,

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/simple_table/simple_table_widgets/simple_table_more_action_popup.dart

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,16 @@ class _SimpleTableMoreActionPopupState
3131

3232
RenderBox? get renderBox => context.findRenderObject() as RenderBox?;
3333

34+
late final simpleTableContext = context.read<SimpleTableContext>();
35+
Node? tableNode;
36+
Node? tableCellNode;
37+
3438
@override
3539
void initState() {
3640
super.initState();
3741

38-
final tableCellNode =
39-
context.read<SimpleTableContext>().hoveringTableCell.value;
42+
tableCellNode = context.read<SimpleTableContext>().hoveringTableCell.value;
43+
tableNode = tableCellNode?.parentTableNode;
4044
gestureInterceptor = SelectionGestureInterceptor(
4145
key: 'simple_table_more_action_popup_interceptor_${tableCellNode?.id}',
4246
canTap: (details) => !_isTapInBounds(details.globalPosition),
@@ -59,17 +63,16 @@ class _SimpleTableMoreActionPopupState
5963

6064
@override
6165
Widget build(BuildContext context) {
62-
final simpleTableContext = context.read<SimpleTableContext>();
63-
final tableCellNode = simpleTableContext.hoveringTableCell.value;
64-
final tableNode = tableCellNode?.parentTableNode;
65-
6666
if (tableNode == null) {
6767
return const SizedBox.shrink();
6868
}
6969

7070
return AppFlowyPopover(
7171
onOpen: () => _onOpen(tableCellNode: tableCellNode),
7272
onClose: () => _onClose(),
73+
canClose: () async {
74+
return true;
75+
},
7376
direction: widget.type == SimpleTableMoreActionType.row
7477
? PopoverDirection.bottomWithCenterAligned
7578
: PopoverDirection.bottomWithLeftAligned,
@@ -81,7 +84,7 @@ class _SimpleTableMoreActionPopupState
8184
child: SimpleTableDraggableReorderButton(
8285
editorState: editorState,
8386
simpleTableContext: simpleTableContext,
84-
node: tableNode,
87+
node: tableNode!,
8588
index: widget.index,
8689
isShowingMenu: widget.isShowingMenu,
8790
type: widget.type,

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/sub_page/sub_page_block_component.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ class SubPageBlockComponentState extends State<SubPageBlockComponent>
200200
return const SizedBox.shrink();
201201
}
202202

203+
final textStyle = textStyleWithTextSpan();
204+
203205
Widget child = Padding(
204206
padding: const EdgeInsets.symmetric(vertical: 2),
205207
child: MouseRegion(

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,9 @@ class _ToggleListBlockComponentWidgetState
312312
placeholderText: placeholderText,
313313
lineHeight: 1.5,
314314
textSpanDecorator: (textSpan) {
315-
var result = textSpan.updateTextStyle(textStyle);
315+
var result = textSpan.updateTextStyle(
316+
textStyleWithTextSpan(textSpan: textSpan),
317+
);
316318
if (level != null) {
317319
result = result.updateTextStyle(
318320
widget.textStyleBuilder?.call(level),
@@ -321,13 +323,17 @@ class _ToggleListBlockComponentWidgetState
321323
return result;
322324
},
323325
placeholderTextSpanDecorator: (textSpan) {
324-
var result = textSpan.updateTextStyle(textStyle);
326+
var result = textSpan.updateTextStyle(
327+
textStyleWithTextSpan(textSpan: textSpan),
328+
);
325329
if (level != null && widget.textStyleBuilder != null) {
326330
result = result.updateTextStyle(
327331
widget.textStyleBuilder?.call(level),
328332
);
329333
}
330-
return result.updateTextStyle(placeholderTextStyle);
334+
return result.updateTextStyle(
335+
placeholderTextStyleWithTextSpan(textSpan: textSpan),
336+
);
331337
},
332338
textDirection: textDirection,
333339
textAlign: alignment?.toTextAlign ?? textAlign,

frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/date_reference.dart

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,22 +138,36 @@ class DateReferenceService extends InlineActionsDelegate {
138138
final tomorrow = today.add(const Duration(days: 1));
139139
final yesterday = today.subtract(const Duration(days: 1));
140140

141-
_allOptions = [
142-
_itemFromDate(
141+
late InlineActionsMenuItem todayItem;
142+
late InlineActionsMenuItem tomorrowItem;
143+
late InlineActionsMenuItem yesterdayItem;
144+
145+
try {
146+
todayItem = _itemFromDate(
143147
today,
144148
LocaleKeys.relativeDates_today.tr(),
145149
[DateFormat.yMd(_locale).format(today)],
146-
),
147-
_itemFromDate(
150+
);
151+
tomorrowItem = _itemFromDate(
148152
tomorrow,
149153
LocaleKeys.relativeDates_tomorrow.tr(),
150154
[DateFormat.yMd(_locale).format(tomorrow)],
151-
),
152-
_itemFromDate(
155+
);
156+
yesterdayItem = _itemFromDate(
153157
yesterday,
154158
LocaleKeys.relativeDates_yesterday.tr(),
155159
[DateFormat.yMd(_locale).format(yesterday)],
156-
),
160+
);
161+
} catch (e) {
162+
todayItem = _itemFromDate(today);
163+
tomorrowItem = _itemFromDate(tomorrow);
164+
yesterdayItem = _itemFromDate(yesterday);
165+
}
166+
167+
_allOptions = [
168+
todayItem,
169+
tomorrowItem,
170+
yesterdayItem,
157171
];
158172
}
159173

@@ -173,7 +187,17 @@ class DateReferenceService extends InlineActionsDelegate {
173187
String? label,
174188
List<String>? keywords,
175189
]) {
176-
final labelStr = label ?? DateFormat.yMd(_locale).format(date);
190+
late String labelStr;
191+
if (label != null) {
192+
labelStr = label;
193+
} else {
194+
try {
195+
labelStr = DateFormat.yMd(_locale).format(date);
196+
} catch (e) {
197+
// fallback to en-US
198+
labelStr = DateFormat.yMd('en-US').format(date);
199+
}
200+
}
177201

178202
return InlineActionsMenuItem(
179203
label: labelStr.capitalize(),

0 commit comments

Comments
 (0)