From b65b4796d2d3da694d2332b9220c0f59bd803369 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 26 Mar 2022 21:03:54 +0800 Subject: [PATCH] fix: add event after bloc close --- .../lib/startup/tasks/app_widget.dart | 2 +- .../grid/cell_bloc/checkbox_cell_bloc.dart | 2 - .../grid/cell_bloc/text_cell_bloc.dart | 15 ++-- .../application/grid/row/row_bloc.dart | 15 ++-- .../application/grid/row/row_service.dart | 2 +- .../src/widgets/content/cell_builder.dart | 21 +++-- .../grid/src/widgets/content/grid_row.dart | 85 ++++++++++++------- .../grid/src/widgets/content/text_cell.dart | 15 ++-- 8 files changed, 91 insertions(+), 66 deletions(-) diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart index 78672193da..9f5493b256 100644 --- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart @@ -112,7 +112,7 @@ class ApplicationBlocObserver extends BlocObserver { // ignore: unnecessary_overrides void onTransition(Bloc bloc, Transition transition) { // Log.debug("[current]: ${transition.currentState} \n\n[next]: ${transition.nextState}"); - Log.debug("${transition.nextState}"); + // Log.debug("${transition.nextState}"); super.onTransition(bloc, transition); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 3e3c1b37bc..3609f39de7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -15,8 +15,6 @@ class CheckboxCellBloc extends Bloc { required this.service, required FutureCellData cellData, }) : super(CheckboxCellState.initial()) { - cellData.then((a) {}); - on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index 73c2e8e03d..985fad03be 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -12,13 +12,7 @@ class TextCellBloc extends Bloc { TextCellBloc({ required this.service, required FutureCellData cellData, - }) : super(TextCellState.initial()) { - cellData.then((cellData) { - if (cellData != null) { - add(TextCellEvent.didReceiveCellData(cellData)); - } - }); - + }) : super(TextCellState.initial(cellData)) { on( (event, emit) async { await event.map( @@ -69,8 +63,11 @@ class TextCellEvent with _$TextCellEvent { class TextCellState with _$TextCellState { const factory TextCellState({ required String content, - GridCellData? cellData, + required FutureCellData cellData, }) = _TextCellState; - factory TextCellState.initial() => const TextCellState(content: ""); + factory TextCellState.initial(FutureCellData cellData) => TextCellState( + content: cellData?.cell?.content ?? "", + cellData: cellData, + ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart index ba6b64f602..2bb78799f0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart @@ -50,12 +50,11 @@ class RowBloc extends Bloc { emit(state.copyWith(fields: value.fields)); add(const RowEvent.didUpdateCell()); }, - didUpdateCell: (_DidUpdateCell value) { - final Future cellDataMap = state.row.then( - (someRow) => someRow.fold( - () => HashMap.identity(), - (row) => _makeCellDatas(row), - ), + didUpdateCell: (_DidUpdateCell value) async { + final optionRow = await state.row; + final CellDataMap cellDataMap = optionRow.fold( + () => HashMap.identity(), + (row) => _makeCellDatas(row), ); emit(state.copyWith(cellDataMap: cellDataMap)); }, @@ -147,7 +146,7 @@ class RowState with _$RowState { required double rowHeight, required List fields, required Future> row, - required Future cellDataMap, + required CellDataMap? cellDataMap, }) = _RowState; factory RowState.initial(GridRowData data) => RowState( @@ -156,6 +155,6 @@ class RowState with _$RowState { rowHeight: data.height, fields: data.fields, row: Future(() => none()), - cellDataMap: Future(() => CellDataMap.identity()), + cellDataMap: null, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 7c77c0de64..d30a22b7d0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -29,7 +29,7 @@ class RowService { } } -typedef FutureCellData = Future; +typedef FutureCellData = GridCellData?; class GridCellData extends Equatable { final String gridId; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index fc9eb9b80b..856338aea4 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; @@ -7,20 +8,24 @@ import 'number_cell.dart'; import 'selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(FieldType fieldType, FutureCellData cellData) { - switch (fieldType) { +Widget buildGridCell(String rowId, Field field, FutureCellData cellData) { + if (cellData == null) { + return const SizedBox(); + } + final key = ValueKey(field.id + rowId); + switch (field.fieldType) { case FieldType.Checkbox: - return CheckboxCell(cellData: cellData, key: ObjectKey(cellData)); + return CheckboxCell(cellData: cellData, key: key); case FieldType.DateTime: - return DateCell(cellData: cellData, key: ObjectKey(cellData)); + return DateCell(cellData: cellData, key: key); case FieldType.MultiSelect: - return MultiSelectCell(cellData: cellData, key: ObjectKey(cellData)); + return MultiSelectCell(cellData: cellData, key: key); case FieldType.Number: - return NumberCell(cellData: cellData, key: ObjectKey(cellData)); + return NumberCell(cellData: cellData, key: key); case FieldType.RichText: - return GridTextCell(cellData: cellData, key: ObjectKey(cellData)); + return GridTextCell(cellData: cellData, key: key); case FieldType.SingleSelect: - return SingleSelectCell(cellData: cellData, key: ObjectKey(cellData)); + return SingleSelectCell(cellData: cellData, key: key); default: throw UnimplementedError; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 735143a35a..b8834cd213 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -4,38 +4,61 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; -class GridRowWidget extends StatelessWidget { +class GridRowWidget extends StatefulWidget { final GridRowData data; const GridRowWidget({required this.data, Key? key}) : super(key: key); + @override + State createState() => _GridRowWidgetState(); +} + +class _GridRowWidgetState extends State { + late RowBloc _rowBloc; + + @override + void initState() { + _rowBloc = getIt(param1: widget.data)..add(const RowEvent.initial()); + super.initState(); + } + @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(param1: data)..add(const RowEvent.initial()), - child: BlocBuilder( - buildWhen: (p, c) => p.rowHeight != c.rowHeight, - builder: (context, state) { - return SizedBox( - height: state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: const [ - _RowLeading(), - _RowCells(), - _RowTrailing(), - ], - ), - ); - }, + return BlocProvider.value( + value: _rowBloc, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), + onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: _rowBloc.state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: const [ + _RowLeading(), + _RowCells(), + _RowTrailing(), + ], + ), + ); + }, + ), ), ); } + + @override + Future dispose() async { + _rowBloc.close(); + super.dispose(); + } } class _RowLeading extends StatelessWidget { @@ -92,18 +115,20 @@ class _RowCells extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder( + buildWhen: (previous, current) => previous.cellDataMap != current.cellDataMap, builder: (context, state) { - return Row(children: [ - ...state.fields.map( - (field) { - final cellData = state.cellDataMap.then((fut) => fut[field.id]); - return CellContainer( - width: field.width.toDouble(), - child: buildGridCell(field.fieldType, cellData), - ); - }, - ), - ]); + final children = state.fields + .map((field) => CellContainer( + width: field.width.toDouble(), + child: buildGridCell( + state.rowId, + field, + state.cellDataMap?[field.id], + ), + )) + .toList(); + + return Row(children: children); }, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 0a8ea79771..e8c571bded 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -22,12 +22,12 @@ class _GridTextCellState extends State { late TextEditingController _controller; Timer? _delayOperation; final _focusNode = FocusNode(); - TextCellBloc? _cellBloc; + late TextCellBloc _cellBloc; @override void initState() { _cellBloc = getIt(param1: widget.cellData); - _controller = TextEditingController(text: _cellBloc!.state.content); + _controller = TextEditingController(text: _cellBloc.state.content); _focusNode.addListener(save); super.initState(); } @@ -35,7 +35,7 @@ class _GridTextCellState extends State { @override Widget build(BuildContext context) { return BlocProvider.value( - value: _cellBloc!, + value: _cellBloc, child: BlocConsumer( listener: (context, state) { if (_controller.text != state.content) { @@ -71,8 +71,7 @@ class _GridTextCellState extends State { @override Future dispose() async { - _cellBloc?.close(); - _cellBloc = null; + _cellBloc.close(); _focusNode.removeListener(save); _focusNode.dispose(); super.dispose(); @@ -80,8 +79,10 @@ class _GridTextCellState extends State { Future save() async { _delayOperation?.cancel(); - _delayOperation = Timer(const Duration(seconds: 2), () { - _cellBloc?.add(TextCellEvent.updateText(_controller.text)); + _delayOperation = Timer(const Duration(milliseconds: 300), () { + if (_cellBloc.isClosed == false) { + _cellBloc.add(TextCellEvent.updateText(_controller.text)); + } }); // and later, before the timer goes off... }