Selaa lähdekoodia

fix: reduce rebuild while editing text field

appflowy 2 vuotta sitten
vanhempi
commit
86e2091ccf

+ 0 - 1
frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

@@ -99,7 +99,6 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
             ));
           },
           endEditRow: (rowId) {
-            assert(state.editingRow.isSome());
             state.editingRow.fold(() => null, (editingRow) {
               assert(editingRow.row.id == rowId);
               emit(state.copyWith(editingRow: none()));

+ 13 - 12
frontend/app_flowy/lib/plugins/board/application/card/card_bloc.dart

@@ -77,7 +77,7 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
   }
 }
 
-UnmodifiableListView<BoardCellEquatable> _makeCells(
+List<BoardCellEquatable> _makeCells(
     String groupFieldId, GridCellMap originalCellMap) {
   List<BoardCellEquatable> cells = [];
   for (final entry in originalCellMap.entries) {
@@ -86,14 +86,14 @@ UnmodifiableListView<BoardCellEquatable> _makeCells(
       cells.add(BoardCellEquatable(entry.value));
     }
   }
-  return UnmodifiableListView(cells);
+  return cells;
 }
 
 @freezed
 class BoardCardEvent with _$BoardCardEvent {
   const factory BoardCardEvent.initial() = _InitialRow;
   const factory BoardCardEvent.didReceiveCells(
-    UnmodifiableListView<BoardCellEquatable> cells,
+    List<BoardCellEquatable> cells,
     RowsChangedReason reason,
   ) = _DidReceiveCells;
 }
@@ -102,12 +102,11 @@ class BoardCardEvent with _$BoardCardEvent {
 class BoardCardState with _$BoardCardState {
   const factory BoardCardState({
     required RowPB rowPB,
-    required UnmodifiableListView<BoardCellEquatable> cells,
+    required List<BoardCellEquatable> cells,
     RowsChangedReason? changeReason,
   }) = _BoardCardState;
 
-  factory BoardCardState.initial(
-          RowPB rowPB, UnmodifiableListView<BoardCellEquatable> cells) =>
+  factory BoardCardState.initial(RowPB rowPB, List<BoardCellEquatable> cells) =>
       BoardCardState(
         rowPB: rowPB,
         cells: cells,
@@ -120,10 +119,12 @@ class BoardCellEquatable extends Equatable {
   const BoardCellEquatable(this.identifier);
 
   @override
-  List<Object?> get props => [
-        identifier.fieldContext.id,
-        identifier.fieldContext.fieldType,
-        identifier.fieldContext.visibility,
-        identifier.fieldContext.width,
-      ];
+  List<Object?> get props {
+    return [
+      identifier.fieldContext.id,
+      identifier.fieldContext.fieldType,
+      identifier.fieldContext.visibility,
+      identifier.fieldContext.width,
+    ];
+  }
 }

+ 9 - 1
frontend/app_flowy/lib/plugins/board/presentation/board_page.dart

@@ -63,6 +63,7 @@ class BoardContent extends StatefulWidget {
 
 class _BoardContentState extends State<BoardContent> {
   late AppFlowyBoardScrollController scrollManager;
+  final Map<String, ValueKey> cardKeysCache = {};
 
   final config = AppFlowyBoardConfig(
     groupBackgroundColor: HexColor.fromHex('#F7F8FC'),
@@ -239,8 +240,15 @@ class _BoardContentState extends State<BoardContent> {
       },
     );
 
+    ValueKey? key = cardKeysCache[columnItem.id];
+    if (key == null) {
+      final newKey = ValueKey(columnItem.id);
+      cardKeysCache[columnItem.id] = newKey;
+      key = newKey;
+    }
+
     return AppFlowyGroupCard(
-      key: ValueKey(columnItem.id),
+      key: key,
       margin: config.cardPadding,
       decoration: _makeBoxDecoration(context),
       child: BoardCard(

+ 37 - 18
frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart

@@ -56,7 +56,11 @@ class _BoardTextCellState extends State<BoardTextCell> {
         }
       }
     });
+    _bindEditableNotifier();
+    super.initState();
+  }
 
+  void _bindEditableNotifier() {
     widget.editableNotifier?.becomeFirstResponder.addListener(() {
       if (!mounted) return;
       WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -69,8 +73,12 @@ class _BoardTextCellState extends State<BoardTextCell> {
       if (!mounted) return;
       _cellBloc.add(const BoardTextCellEvent.enableEdit(false));
     });
+  }
 
-    super.initState();
+  @override
+  void didUpdateWidget(covariant BoardTextCell oldWidget) {
+    _bindEditableNotifier();
+    super.didUpdateWidget(oldWidget);
   }
 
   @override
@@ -84,6 +92,15 @@ class _BoardTextCellState extends State<BoardTextCell> {
           }
         },
         child: BlocBuilder<BoardTextCellBloc, BoardTextCellState>(
+          buildWhen: (previous, current) {
+            if (previous.content != current.content &&
+                _controller.text == current.content &&
+                current.enableEdit) {
+              return false;
+            }
+
+            return previous != current;
+          },
           builder: (context, state) {
             if (state.content.isEmpty &&
                 state.enableEdit == false &&
@@ -127,24 +144,26 @@ class _BoardTextCellState extends State<BoardTextCell> {
   }
 
   Widget _buildTextField() {
-    return TextField(
-      controller: _controller,
-      focusNode: focusNode,
-      onChanged: (value) => focusChanged(),
-      onEditingComplete: () => focusNode.unfocus(),
-      maxLines: 1,
-      style: const TextStyle(
-        fontSize: 14,
-        fontWeight: FontWeight.w500,
-        fontFamily: 'Mulish',
-      ),
-      decoration: InputDecoration(
-        // Magic number 4 makes the textField take up the same space as FlowyText
-        contentPadding: EdgeInsets.symmetric(
-          vertical: BoardSizes.cardCellVPadding + 4,
+    return IntrinsicHeight(
+      child: TextField(
+        controller: _controller,
+        focusNode: focusNode,
+        onChanged: (value) => focusChanged(),
+        onEditingComplete: () => focusNode.unfocus(),
+        maxLines: null,
+        style: const TextStyle(
+          fontSize: 14,
+          fontWeight: FontWeight.w500,
+          fontFamily: 'Mulish',
+        ),
+        decoration: InputDecoration(
+          // Magic number 4 makes the textField take up the same space as FlowyText
+          contentPadding: EdgeInsets.symmetric(
+            vertical: BoardSizes.cardCellVPadding + 4,
+          ),
+          border: InputBorder.none,
+          isDense: true,
         ),
-        border: InputBorder.none,
-        isDense: true,
       ),
     );
   }

+ 5 - 1
frontend/app_flowy/lib/plugins/board/presentation/card/card.dart

@@ -5,6 +5,7 @@ import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_action_sheet
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
+import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'board_cell.dart';
@@ -56,7 +57,10 @@ class _BoardCardState extends State<BoardCard> {
       value: _cardBloc,
       child: BlocBuilder<BoardCardBloc, BoardCardState>(
         buildWhen: (previous, current) {
-          return previous.cells != current.cells;
+          if (previous.cells.length != current.cells.length) {
+            return true;
+          }
+          return !listEquals(previous.cells, current.cells);
         },
         builder: (context, state) {
           return BoardCardContainer(