Explorar o código

chore: hide edit button when start editing

appflowy %!s(int64=2) %!d(string=hai) anos
pai
achega
29e7e01146

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

@@ -7,7 +7,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';
-
 import 'card_data_controller.dart';
 
 part 'card_bloc.freezed.dart';
@@ -21,6 +20,7 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
     required this.groupFieldId,
     required String gridId,
     required CardDataController dataController,
+    required bool isEditing,
   })  : _rowService = RowFFIService(
           gridId: gridId,
           blockId: dataController.rowPB.blockId,
@@ -30,6 +30,7 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
           BoardCardState.initial(
             dataController.rowPB,
             _makeCells(groupFieldId, dataController.loadData()),
+            isEditing,
           ),
         ) {
     on<BoardCardEvent>(
@@ -44,6 +45,9 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
               changeReason: reason,
             ));
           },
+          setIsEditing: (bool isEditing) {
+            emit(state.copyWith(isEditing: isEditing));
+          },
         );
       },
     );
@@ -92,6 +96,7 @@ List<BoardCellEquatable> _makeCells(
 @freezed
 class BoardCardEvent with _$BoardCardEvent {
   const factory BoardCardEvent.initial() = _InitialRow;
+  const factory BoardCardEvent.setIsEditing(bool isEditing) = _IsEditing;
   const factory BoardCardEvent.didReceiveCells(
     List<BoardCellEquatable> cells,
     RowsChangedReason reason,
@@ -103,13 +108,19 @@ class BoardCardState with _$BoardCardState {
   const factory BoardCardState({
     required RowPB rowPB,
     required List<BoardCellEquatable> cells,
+    required bool isEditing,
     RowsChangedReason? changeReason,
   }) = _BoardCardState;
 
-  factory BoardCardState.initial(RowPB rowPB, List<BoardCellEquatable> cells) =>
+  factory BoardCardState.initial(
+    RowPB rowPB,
+    List<BoardCellEquatable> cells,
+    bool isEditing,
+  ) =>
       BoardCardState(
         rowPB: rowPB,
         cells: cells,
+        isEditing: isEditing,
       );
 }
 

+ 24 - 15
frontend/app_flowy/lib/plugins/board/presentation/card/board_cell.dart

@@ -1,5 +1,4 @@
 import 'package:app_flowy/plugins/grid/application/prelude.dart';
-import 'package:flowy_infra/notifier.dart';
 import 'package:flutter/material.dart';
 
 abstract class FocusableBoardCell {
@@ -7,47 +6,57 @@ abstract class FocusableBoardCell {
 }
 
 class EditableCellNotifier {
-  final Notifier becomeFirstResponder = Notifier();
-
-  final Notifier resignFirstResponder = Notifier();
-
   final ValueNotifier<bool> isCellEditing;
 
   EditableCellNotifier({bool isEditing = false})
       : isCellEditing = ValueNotifier(isEditing);
 
   void dispose() {
-    becomeFirstResponder.dispose();
-    resignFirstResponder.dispose();
     isCellEditing.dispose();
   }
 }
 
 class EditableRowNotifier {
   final Map<EditableCellId, EditableCellNotifier> _cells = {};
+  final ValueNotifier<bool> isEditing;
+
+  EditableRowNotifier({required bool isEditing})
+      : isEditing = ValueNotifier(isEditing);
 
   void insertCell(
     GridCellIdentifier cellIdentifier,
     EditableCellNotifier notifier,
   ) {
+    assert(
+      _cells.values.isEmpty,
+      'Only one cell can receive the notification',
+    );
     final id = EditableCellId.from(cellIdentifier);
     _cells[id]?.dispose();
 
-    notifier.isCellEditing.addListener(() {});
+    notifier.isCellEditing.addListener(() {
+      isEditing.value = notifier.isCellEditing.value;
+    });
 
     _cells[EditableCellId.from(cellIdentifier)] = notifier;
   }
 
   void becomeFirstResponder() {
-    for (final notifier in _cells.values) {
-      notifier.becomeFirstResponder.notify();
-    }
+    if (_cells.values.isEmpty) return;
+    assert(
+      _cells.values.length == 1,
+      'Only one cell can receive the notification',
+    );
+    _cells.values.first.isCellEditing.value = true;
   }
 
   void resignFirstResponder() {
-    for (final notifier in _cells.values) {
-      notifier.resignFirstResponder.notify();
-    }
+    if (_cells.values.isEmpty) return;
+    assert(
+      _cells.values.length == 1,
+      'Only one cell can receive the notification',
+    );
+    _cells.values.first.isCellEditing.value = false;
   }
 
   void clear() {
@@ -59,7 +68,7 @@ class EditableRowNotifier {
 
   void dispose() {
     for (final notifier in _cells.values) {
-      notifier.resignFirstResponder.notify();
+      notifier.dispose();
     }
 
     _cells.clear();

+ 8 - 9
frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart

@@ -54,17 +54,16 @@ class _BoardTextCellState extends State<BoardTextCell> {
   }
 
   void _bindEditableNotifier() {
-    widget.editableNotifier?.becomeFirstResponder.addListener(() {
+    widget.editableNotifier?.isCellEditing.addListener(() {
       if (!mounted) return;
-      WidgetsBinding.instance.addPostFrameCallback((_) {
-        focusNode.requestFocus();
-      });
-      _cellBloc.add(const BoardTextCellEvent.enableEdit(true));
-    });
 
-    widget.editableNotifier?.resignFirstResponder.addListener(() {
-      if (!mounted) return;
-      _cellBloc.add(const BoardTextCellEvent.enableEdit(false));
+      final isEditing = widget.editableNotifier?.isCellEditing.value ?? false;
+      if (isEditing) {
+        WidgetsBinding.instance.addPostFrameCallback((_) {
+          focusNode.requestFocus();
+        });
+      }
+      _cellBloc.add(BoardTextCellEvent.enableEdit(isEditing));
     });
   }
 

+ 16 - 3
frontend/app_flowy/lib/plugins/board/presentation/card/card.dart

@@ -42,12 +42,19 @@ class _BoardCardState extends State<BoardCard> {
 
   @override
   void initState() {
-    rowNotifier = EditableRowNotifier();
+    rowNotifier = EditableRowNotifier(isEditing: widget.isEditing);
     _cardBloc = BoardCardBloc(
       gridId: widget.gridId,
       groupFieldId: widget.fieldId,
       dataController: widget.dataController,
+      isEditing: widget.isEditing,
     )..add(const BoardCardEvent.initial());
+
+    rowNotifier.isEditing.addListener(() {
+      if (!mounted) return;
+      _cardBloc.add(BoardCardEvent.setIsEditing(rowNotifier.isEditing.value));
+    });
+
     super.initState();
   }
 
@@ -57,13 +64,15 @@ class _BoardCardState extends State<BoardCard> {
       value: _cardBloc,
       child: BlocBuilder<BoardCardBloc, BoardCardState>(
         buildWhen: (previous, current) {
-          if (previous.cells.length != current.cells.length) {
+          if (previous.cells.length != current.cells.length ||
+              previous.isEditing != current.isEditing) {
             return true;
           }
           return !listEquals(previous.cells, current.cells);
         },
         builder: (context, state) {
           return BoardCardContainer(
+            buildAccessoryWhen: () => state.isEditing == false,
             accessoryBuilder: (context) {
               return [
                 _CardEditOption(
@@ -98,7 +107,11 @@ class _BoardCardState extends State<BoardCard> {
       (int index, GridCellIdentifier cellId) {
         EditableCellNotifier cellNotifier;
         if (index == 0) {
-          cellNotifier = EditableCellNotifier(isEditing: widget.isEditing);
+          // Only use the first cell to receive user's input when click the edit
+          // button
+          cellNotifier = EditableCellNotifier(
+            isEditing: rowNotifier.isEditing.value,
+          );
           rowNotifier.insertCell(cellId, cellNotifier);
         } else {
           cellNotifier = EditableCellNotifier();

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

@@ -7,11 +7,13 @@ import 'package:styled_widget/styled_widget.dart';
 class BoardCardContainer extends StatelessWidget {
   final Widget child;
   final CardAccessoryBuilder? accessoryBuilder;
+  final bool Function()? buildAccessoryWhen;
   final void Function(BuildContext) onTap;
   const BoardCardContainer({
     required this.child,
     required this.onTap,
     this.accessoryBuilder,
+    this.buildAccessoryWhen,
     Key? key,
   }) : super(key: key);
 
@@ -22,7 +24,12 @@ class BoardCardContainer extends StatelessWidget {
       child: Consumer<_CardContainerNotifier>(
         builder: (context, notifier, _) {
           Widget container = Center(child: child);
-          if (accessoryBuilder != null) {
+          bool shouldBuildAccessory = true;
+          if (buildAccessoryWhen != null) {
+            shouldBuildAccessory = buildAccessoryWhen!.call();
+          }
+
+          if (accessoryBuilder != null && shouldBuildAccessory) {
             final accessories = accessoryBuilder!(context);
             if (accessories.isNotEmpty) {
               container = _CardEnterRegion(