chore: hide edit button when start editing

This commit is contained in:
appflowy 2022-09-07 11:33:42 +08:00
parent 951206db71
commit 29e7e01146
5 changed files with 69 additions and 30 deletions

View File

@ -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,
);
}

View File

@ -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();

View File

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

View File

@ -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();

View File

@ -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(