fix: add event after bloc close

This commit is contained in:
appflowy 2022-03-26 21:03:54 +08:00
parent 16598650ff
commit b65b4796d2
8 changed files with 91 additions and 66 deletions

View File

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

View File

@ -15,8 +15,6 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
required this.service,
required FutureCellData cellData,
}) : super(CheckboxCellState.initial()) {
cellData.then((a) {});
on<CheckboxCellEvent>(
(event, emit) async {
await event.map(

View File

@ -12,13 +12,7 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
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<TextCellEvent>(
(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,
);
}

View File

@ -50,12 +50,11 @@ class RowBloc extends Bloc<RowEvent, RowState> {
emit(state.copyWith(fields: value.fields));
add(const RowEvent.didUpdateCell());
},
didUpdateCell: (_DidUpdateCell value) {
final Future<CellDataMap> 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<Field> fields,
required Future<Option<Row>> row,
required Future<CellDataMap> 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,
);
}

View File

@ -29,7 +29,7 @@ class RowService {
}
}
typedef FutureCellData = Future<GridCellData?>;
typedef FutureCellData = GridCellData?;
class GridCellData extends Equatable {
final String gridId;

View File

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

View File

@ -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<GridRowWidget> createState() => _GridRowWidgetState();
}
class _GridRowWidgetState extends State<GridRowWidget> {
late RowBloc _rowBloc;
@override
void initState() {
_rowBloc = getIt<RowBloc>(param1: widget.data)..add(const RowEvent.initial());
super.initState();
}
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => getIt<RowBloc>(param1: data)..add(const RowEvent.initial()),
child: BlocBuilder<RowBloc, RowState>(
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<RowBloc, RowState>(
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<void> 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<RowBloc, RowState>(
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);
},
);
}

View File

@ -22,12 +22,12 @@ class _GridTextCellState extends State<GridTextCell> {
late TextEditingController _controller;
Timer? _delayOperation;
final _focusNode = FocusNode();
TextCellBloc? _cellBloc;
late TextCellBloc _cellBloc;
@override
void initState() {
_cellBloc = getIt<TextCellBloc>(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<GridTextCell> {
@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc!,
value: _cellBloc,
child: BlocConsumer<TextCellBloc, TextCellState>(
listener: (context, state) {
if (_controller.text != state.content) {
@ -71,8 +71,7 @@ class _GridTextCellState extends State<GridTextCell> {
@override
Future<void> dispose() async {
_cellBloc?.close();
_cellBloc = null;
_cellBloc.close();
_focusNode.removeListener(save);
_focusNode.dispose();
super.dispose();
@ -80,8 +79,10 @@ class _GridTextCellState extends State<GridTextCell> {
Future<void> 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...
}