refactor: cell context builder

This commit is contained in:
appflowy 2022-04-27 13:31:54 +08:00
parent 70abe546a1
commit d0b4abb0c8
7 changed files with 84 additions and 66 deletions

View File

@ -1,7 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@ -10,13 +12,52 @@ import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
import 'package:equatable/equatable.dart';
part 'cell_service.freezed.dart'; part 'cell_service.freezed.dart';
typedef GridDefaultCellContext = GridCellContext<Cell>; typedef GridDefaultCellContext = GridCellContext<Cell>;
typedef GridSelectOptionCellContext = GridCellContext<SelectOptionContext>; typedef GridSelectOptionCellContext = GridCellContext<SelectOptionContext>;
class GridCellContextBuilder {
final GridCellCache _cellCache;
final GridCell _gridCell;
GridCellContextBuilder({
required GridCellCache cellCache,
required GridCell gridCell,
}) : _cellCache = cellCache,
_gridCell = gridCell;
GridCellContext build() {
switch (_gridCell.field.fieldType) {
case FieldType.Checkbox:
case FieldType.DateTime:
case FieldType.Number:
return GridDefaultCellContext(
gridCell: _gridCell,
cellCache: _cellCache,
cellDataLoader: DefaultCellDataLoader(gridCell: _gridCell, reloadOnCellChanged: true),
);
case FieldType.RichText:
return GridDefaultCellContext(
gridCell: _gridCell,
cellCache: _cellCache,
cellDataLoader: DefaultCellDataLoader(gridCell: _gridCell),
);
case FieldType.MultiSelect:
case FieldType.SingleSelect:
return GridSelectOptionCellContext(
gridCell: _gridCell,
cellCache: _cellCache,
cellDataLoader: SelectOptionCellDataLoader(gridCell: _gridCell),
);
default:
throw UnimplementedError;
}
}
}
// ignore: must_be_immutable // ignore: must_be_immutable
class GridCellContext<T> extends Equatable { class GridCellContext<T> extends Equatable {
final GridCell gridCell; final GridCell gridCell;

View File

@ -1,5 +1,4 @@
import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart';
import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -12,49 +11,22 @@ import 'text_cell.dart';
GridCellWidget buildGridCellWidget(GridCell gridCell, GridCellCache cellCache, {GridCellStyle? style}) { GridCellWidget buildGridCellWidget(GridCell gridCell, GridCellCache cellCache, {GridCellStyle? style}) {
final key = ValueKey(gridCell.rowId + gridCell.field.id); final key = ValueKey(gridCell.rowId + gridCell.field.id);
final cellContext = makeCellContext(gridCell, cellCache); final cellContextBuilder = GridCellContextBuilder(gridCell: gridCell, cellCache: cellCache);
switch (gridCell.field.fieldType) { switch (gridCell.field.fieldType) {
case FieldType.Checkbox: case FieldType.Checkbox:
return CheckboxCell(cellContext: cellContext, key: key); return CheckboxCell(cellContextBuilder: cellContextBuilder, key: key);
case FieldType.DateTime: case FieldType.DateTime:
return DateCell(cellContext: cellContext, key: key); return DateCell(cellContextBuilder: cellContextBuilder, key: key);
case FieldType.MultiSelect:
return MultiSelectCell(cellContext: cellContext as GridSelectOptionCellContext, style: style, key: key);
case FieldType.Number:
return NumberCell(cellContext: cellContext, key: key);
case FieldType.RichText:
return GridTextCell(cellContext: cellContext, style: style, key: key);
case FieldType.SingleSelect: case FieldType.SingleSelect:
return SingleSelectCell(cellContext: cellContext as GridSelectOptionCellContext, style: style, key: key); return SingleSelectCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
default: case FieldType.MultiSelect:
throw UnimplementedError; return MultiSelectCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
} case FieldType.Number:
} return NumberCell(cellContextBuilder: cellContextBuilder, key: key);
case FieldType.RichText:
return GridTextCell(cellContextBuilder: cellContextBuilder, style: style, key: key);
GridCellContext makeCellContext(GridCell gridCell, GridCellCache cellCache) {
switch (gridCell.field.fieldType) {
case FieldType.Checkbox:
case FieldType.DateTime:
case FieldType.Number:
return GridDefaultCellContext(
gridCell: gridCell,
cellCache: cellCache,
cellDataLoader: DefaultCellDataLoader(gridCell: gridCell, reloadOnCellChanged: true),
);
case FieldType.RichText:
return GridDefaultCellContext(
gridCell: gridCell,
cellCache: cellCache,
cellDataLoader: DefaultCellDataLoader(gridCell: gridCell),
);
case FieldType.MultiSelect:
case FieldType.SingleSelect:
return GridSelectOptionCellContext(
gridCell: gridCell,
cellCache: cellCache,
cellDataLoader: SelectOptionCellDataLoader(gridCell: gridCell),
);
default: default:
throw UnimplementedError; throw UnimplementedError;
} }

View File

@ -7,10 +7,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'cell_builder.dart'; import 'cell_builder.dart';
class CheckboxCell extends GridCellWidget { class CheckboxCell extends GridCellWidget {
final GridCellContext cellContext; final GridCellContextBuilder cellContextBuilder;
CheckboxCell({ CheckboxCell({
required this.cellContext, required this.cellContextBuilder,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -23,7 +22,8 @@ class _CheckboxCellState extends State<CheckboxCell> {
@override @override
void initState() { void initState() {
_cellBloc = getIt<CheckboxCellBloc>(param1: widget.cellContext)..add(const CheckboxCellEvent.initial()); final cellContext = widget.cellContextBuilder.build();
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
super.initState(); super.initState();
} }

View File

@ -14,10 +14,10 @@ abstract class GridCellDelegate {
} }
class DateCell extends GridCellWidget { class DateCell extends GridCellWidget {
final GridCellContext cellContext; final GridCellContextBuilder cellContextBuilder;
DateCell({ DateCell({
required this.cellContext, required this.cellContextBuilder,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -30,7 +30,8 @@ class _DateCellState extends State<DateCell> {
@override @override
void initState() { void initState() {
_cellBloc = getIt<DateCellBloc>(param1: widget.cellContext)..add(const DateCellEvent.initial()); final cellContext = widget.cellContextBuilder.build();
_cellBloc = getIt<DateCellBloc>(param1: cellContext)..add(const DateCellEvent.initial());
super.initState(); super.initState();
} }

View File

@ -8,10 +8,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'cell_builder.dart'; import 'cell_builder.dart';
class NumberCell extends GridCellWidget { class NumberCell extends GridCellWidget {
final GridCellContext cellContext; final GridCellContextBuilder cellContextBuilder;
NumberCell({ NumberCell({
required this.cellContext, required this.cellContextBuilder,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -27,7 +27,8 @@ class _NumberCellState extends State<NumberCell> {
@override @override
void initState() { void initState() {
_cellBloc = getIt<NumberCellBloc>(param1: widget.cellContext)..add(const NumberCellEvent.initial()); final cellContext = widget.cellContextBuilder.build();
_cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
_controller = TextEditingController(text: _cellBloc.state.content); _controller = TextEditingController(text: _cellBloc.state.content);
_focusNode = FocusNode(); _focusNode = FocusNode();
_focusNode.addListener(() { _focusNode.addListener(() {

View File

@ -20,11 +20,11 @@ class SelectOptionCellStyle extends GridCellStyle {
} }
class SingleSelectCell extends GridCellWidget { class SingleSelectCell extends GridCellWidget {
final GridSelectOptionCellContext cellContext; final GridCellContextBuilder cellContextBuilder;
late final SelectOptionCellStyle? cellStyle; late final SelectOptionCellStyle? cellStyle;
SingleSelectCell({ SingleSelectCell({
required this.cellContext, required this.cellContextBuilder,
GridCellStyle? style, GridCellStyle? style,
Key? key, Key? key,
}) : super(key: key) { }) : super(key: key) {
@ -45,7 +45,8 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
@override @override
void initState() { void initState() {
// Log.trace("init widget $hashCode"); // Log.trace("init widget $hashCode");
_cellBloc = getIt<SelectionCellBloc>(param1: widget.cellContext)..add(const SelectionCellEvent.initial()); final cellContext = _buildCellContext();
_cellBloc = getIt<SelectionCellBloc>(param1: cellContext)..add(const SelectionCellEvent.initial());
super.initState(); super.initState();
} }
@ -69,7 +70,7 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
widget.onFocus.value = true; widget.onFocus.value = true;
SelectOptionCellEditor.show( SelectOptionCellEditor.show(
context, context,
widget.cellContext.clone(), _buildCellContext(),
() => widget.onFocus.value = false, () => widget.onFocus.value = false,
); );
}, },
@ -81,12 +82,8 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
); );
} }
@override GridSelectOptionCellContext _buildCellContext() {
void didUpdateWidget(covariant SingleSelectCell oldWidget) { return widget.cellContextBuilder.build() as GridSelectOptionCellContext;
if (oldWidget.cellContext != widget.cellContext) {
// Log.trace("did update widget $hashCode");
}
super.didUpdateWidget(oldWidget);
} }
@override @override
@ -99,11 +96,11 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
//---------------------------------------------------------------- //----------------------------------------------------------------
class MultiSelectCell extends GridCellWidget { class MultiSelectCell extends GridCellWidget {
final GridSelectOptionCellContext cellContext; final GridCellContextBuilder cellContextBuilder;
late final SelectOptionCellStyle? cellStyle; late final SelectOptionCellStyle? cellStyle;
MultiSelectCell({ MultiSelectCell({
required this.cellContext, required this.cellContextBuilder,
GridCellStyle? style, GridCellStyle? style,
Key? key, Key? key,
}) : super(key: key) { }) : super(key: key) {
@ -123,7 +120,8 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
@override @override
void initState() { void initState() {
_cellBloc = getIt<SelectionCellBloc>(param1: widget.cellContext)..add(const SelectionCellEvent.initial()); final cellContext = _buildCellContext();
_cellBloc = getIt<SelectionCellBloc>(param1: cellContext)..add(const SelectionCellEvent.initial());
super.initState(); super.initState();
} }
@ -145,7 +143,7 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
widget.onFocus.value = true; widget.onFocus.value = true;
SelectOptionCellEditor.show( SelectOptionCellEditor.show(
context, context,
widget.cellContext, _buildCellContext(),
() => widget.onFocus.value = false, () => widget.onFocus.value = false,
); );
}, },
@ -162,4 +160,8 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
_cellBloc.close(); _cellBloc.close();
super.dispose(); super.dispose();
} }
GridSelectOptionCellContext _buildCellContext() {
return widget.cellContextBuilder.build() as GridSelectOptionCellContext;
}
} }

View File

@ -14,10 +14,10 @@ class GridTextCellStyle extends GridCellStyle {
} }
class GridTextCell extends GridCellWidget { class GridTextCell extends GridCellWidget {
final GridCellContext cellContext; final GridCellContextBuilder cellContextBuilder;
late final GridTextCellStyle? cellStyle; late final GridTextCellStyle? cellStyle;
GridTextCell({ GridTextCell({
required this.cellContext, required this.cellContextBuilder,
GridCellStyle? style, GridCellStyle? style,
Key? key, Key? key,
}) : super(key: key) { }) : super(key: key) {
@ -41,7 +41,8 @@ class _GridTextCellState extends State<GridTextCell> {
@override @override
void initState() { void initState() {
_cellBloc = getIt<TextCellBloc>(param1: widget.cellContext); final cellContext = widget.cellContextBuilder.build();
_cellBloc = getIt<TextCellBloc>(param1: cellContext);
_cellBloc.add(const TextCellEvent.initial()); _cellBloc.add(const TextCellEvent.initial());
_controller = TextEditingController(text: _cellBloc.state.content); _controller = TextEditingController(text: _cellBloc.state.content);
_focusNode = FocusNode(); _focusNode = FocusNode();