ソースを参照

chore: optimize rebuild column

appflowy 2 年 前
コミット
6e0a191be1

+ 10 - 5
frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

@@ -88,12 +88,14 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
           didReceiveGridUpdate: (GridPB grid) {
             emit(state.copyWith(grid: Some(grid)));
           },
-          didReceiveRows: (List<RowInfo> rowInfos) {
-            emit(state.copyWith(rowInfos: rowInfos));
-          },
           didReceiveError: (FlowyError error) {
             emit(state.copyWith(noneOrError: some(error)));
           },
+          didReceiveGroups: (List<GroupPB> groups) {
+            emit(state.copyWith(
+              groupIds: groups.map((group) => group.groupId).toList(),
+            ));
+          },
         );
       },
     );
@@ -170,6 +172,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
 
         boardController.addColumns(columns);
         initializeGroups(groups);
+        add(BoardEvent.didReceiveGroups(groups));
       },
       onDeletedGroup: (groupIds) {
         //
@@ -223,6 +226,8 @@ class BoardEvent with _$BoardEvent {
   const factory BoardEvent.didReceiveGridUpdate(
     GridPB grid,
   ) = _DidReceiveGridUpdate;
+  const factory BoardEvent.didReceiveGroups(List<GroupPB> groups) =
+      _DidReceiveGroups;
 }
 
 @freezed
@@ -230,16 +235,16 @@ class BoardState with _$BoardState {
   const factory BoardState({
     required String gridId,
     required Option<GridPB> grid,
+    required List<String> groupIds,
     required Option<RowPB> editingRow,
-    required List<RowInfo> rowInfos,
     required GridLoadingState loadingState,
     required Option<FlowyError> noneOrError,
   }) = _BoardState;
 
   factory BoardState.initial(String gridId) => BoardState(
-        rowInfos: [],
         grid: none(),
         gridId: gridId,
+        groupIds: [],
         editingRow: none(),
         noneOrError: none(),
         loadingState: const _Loading(),

+ 26 - 5
frontend/app_flowy/lib/plugins/board/presentation/board_page.dart

@@ -32,13 +32,15 @@ class BoardPage extends StatelessWidget {
       create: (context) =>
           BoardBloc(view: view)..add(const BoardEvent.initial()),
       child: BlocBuilder<BoardBloc, BoardState>(
+        buildWhen: (previous, current) =>
+            previous.loadingState != current.loadingState,
         builder: (context, state) {
           return state.loadingState.map(
             loading: (_) =>
                 const Center(child: CircularProgressIndicator.adaptive()),
             finish: (result) {
               return result.successOrFail.fold(
-                (_) => BoardContent(),
+                (_) => const BoardContent(),
                 (err) => FlowyErrorPage(err.toString()),
               );
             },
@@ -49,23 +51,36 @@ class BoardPage extends StatelessWidget {
   }
 }
 
-class BoardContent extends StatelessWidget {
+class BoardContent extends StatefulWidget {
+  const BoardContent({Key? key}) : super(key: key);
+
+  @override
+  State<BoardContent> createState() => _BoardContentState();
+}
+
+class _BoardContentState extends State<BoardContent> {
+  late ScrollController scrollController;
   final config = AFBoardConfig(
     columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
   );
 
-  BoardContent({Key? key}) : super(key: key);
+  @override
+  void initState() {
+    scrollController = ScrollController();
+    super.initState();
+  }
 
   @override
   Widget build(BuildContext context) {
     return BlocBuilder<BoardBloc, BoardState>(
+      buildWhen: (previous, current) => previous.groupIds != current.groupIds,
       builder: (context, state) {
         return Container(
           color: Colors.white,
           child: Padding(
             padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
             child: AFBoard(
-              scrollController: ScrollController(),
+              scrollController: scrollController,
               dataController: context.read<BoardBloc>().boardController,
               headerBuilder: _buildHeader,
               footBuilder: _buildFooter,
@@ -85,6 +100,12 @@ class BoardContent extends StatelessWidget {
     );
   }
 
+  @override
+  void dispose() {
+    scrollController.dispose();
+    super.dispose();
+  }
+
   Widget _buildHeader(
       BuildContext context, AFBoardColumnHeaderData headerData) {
     return AppFlowyColumnHeader(
@@ -159,7 +180,7 @@ class BoardContent extends StatelessWidget {
         );
 
     return AppFlowyColumnItemCard(
-      key: ObjectKey(columnItem),
+      key: ValueKey(columnItem.id),
       margin: config.cardPadding,
       decoration: _makeBoxDecoration(context),
       child: BoardCard(

+ 2 - 2
frontend/app_flowy/packages/appflowy_board/example/lib/multi_board_list_example.dart

@@ -114,7 +114,7 @@ class _MultiBoardListExampleState extends State<MultiBoardListExample> {
       return Align(
         alignment: Alignment.centerLeft,
         child: Padding(
-          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 60),
+          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30),
           child: Text(item.s),
         ),
       );
@@ -124,7 +124,7 @@ class _MultiBoardListExampleState extends State<MultiBoardListExample> {
       return Align(
         alignment: Alignment.centerLeft,
         child: Padding(
-          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 60),
+          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
           child: Column(
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [

+ 1 - 1
frontend/app_flowy/packages/appflowy_board/lib/src/utils/log.dart

@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
 const DART_LOG = "Dart_LOG";
 
 class Log {
-  static const enableLog = false;
+  static const enableLog = true;
 
   static void info(String? message) {
     if (enableLog) {

+ 7 - 6
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board.dart

@@ -75,7 +75,7 @@ class AFBoard extends StatelessWidget {
       value: dataController,
       child: Consumer<AFBoardDataController>(
         builder: (context, notifier, child) {
-          return BoardContent(
+          return AFBoardContent(
             config: config,
             dataController: dataController,
             scrollController: scrollController,
@@ -94,7 +94,7 @@ class AFBoard extends StatelessWidget {
   }
 }
 
-class BoardContent extends StatefulWidget {
+class AFBoardContent extends StatefulWidget {
   final ScrollController? scrollController;
   final OnDragStarted? onDragStarted;
   final OnReorder onReorder;
@@ -118,7 +118,7 @@ class BoardContent extends StatefulWidget {
 
   final BoardPhantomController phantomController;
 
-  const BoardContent({
+  const AFBoardContent({
     required this.config,
     required this.onReorder,
     required this.delegate,
@@ -137,12 +137,12 @@ class BoardContent extends StatefulWidget {
         super(key: key);
 
   @override
-  State<BoardContent> createState() => _BoardContentState();
+  State<AFBoardContent> createState() => _AFBoardContentState();
 }
 
-class _BoardContentState extends State<BoardContent> {
+class _AFBoardContentState extends State<AFBoardContent> {
   final GlobalKey _columnContainerOverlayKey =
-      GlobalKey(debugLabel: '$BoardContent overlay key');
+      GlobalKey(debugLabel: '$AFBoardContent overlay key');
   late BoardOverlayEntry _overlayEntry;
 
   @override
@@ -215,6 +215,7 @@ class _BoardContentState extends State<BoardContent> {
           child: Consumer<AFBoardColumnDataController>(
             builder: (context, value, child) {
               final boardColumn = AFBoardColumnWidget(
+                key: ValueKey(columnData.id),
                 margin: _marginFromIndex(columnIndex),
                 itemMargin: widget.config.columnItemPadding,
                 headerBuilder: _buildHeader,

+ 2 - 7
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_column/board_column.dart

@@ -88,9 +88,7 @@ class AFBoardColumnWidget extends StatefulWidget {
 
   final Color backgroundColor;
 
-  final GlobalKey columnGlobalKey = GlobalKey();
-
-  AFBoardColumnWidget({
+  const AFBoardColumnWidget({
     Key? key,
     this.headerBuilder,
     this.footBuilder,
@@ -140,7 +138,7 @@ class _AFBoardColumnWidgetState extends State<AFBoardColumnWidget> {
         );
 
         Widget reorderFlex = ReorderFlex(
-          key: widget.columnGlobalKey,
+          key: widget.key,
           scrollController: widget.scrollController,
           config: widget.config,
           onDragStarted: (index) {
@@ -163,9 +161,6 @@ class _AFBoardColumnWidgetState extends State<AFBoardColumnWidget> {
           children: children,
         );
 
-        // reorderFlex =
-        //     KeyedSubtree(key: widget.columnGlobalKey, child: reorderFlex);
-
         return Container(
           margin: widget.margin,
           clipBehavior: Clip.hardEdge,

+ 0 - 1
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_data.dart

@@ -196,7 +196,6 @@ class AFBoardDataController extends ChangeNotifier
     final index =
         columnDataController.items.indexWhere((item) => item.isPhantom);
 
-    assert(index != -1);
     if (index != -1) {
       if (index != newIndex) {
         Log.trace(