diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart index 3779b4b418..19da67e557 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart @@ -1,3 +1,4 @@ +import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -6,27 +7,32 @@ import 'package:dartz/dartz.dart'; part 'field_editor_bloc.freezed.dart'; class FieldEditorBloc extends Bloc { + final TypeOptionDataController dataController; + FieldEditorBloc({ required String gridId, required String fieldName, - required IFieldTypeOptionLoader fieldContextLoader, - }) : super(FieldEditorState.initial(gridId, fieldName, fieldContextLoader)) { + required IFieldTypeOptionLoader loader, + }) : dataController = TypeOptionDataController(gridId: gridId, loader: loader), + super(FieldEditorState.initial(gridId, fieldName)) { on( (event, emit) async { await event.when( initial: () async { - final fieldContext = GridFieldContext(gridId: gridId, loader: fieldContextLoader); - await fieldContext.loadData().then((result) { - result.fold( - (l) => emit(state.copyWith(fieldContext: Some(fieldContext), name: fieldContext.field.name)), - (r) => null, - ); + dataController.addFieldListener((field) { + if (!isClosed) { + add(FieldEditorEvent.didReceiveFieldChanged(field)); + } }); + await dataController.loadData(); }, updateName: (name) { - state.fieldContext.fold(() => null, (fieldContext) => fieldContext.fieldName = name); + dataController.fieldName = name; emit(state.copyWith(name: name)); }, + didReceiveFieldChanged: (Field field) { + emit(state.copyWith(field: Some(field))); + }, ); }, ); @@ -42,6 +48,7 @@ class FieldEditorBloc extends Bloc { class FieldEditorEvent with _$FieldEditorEvent { const factory FieldEditorEvent.initial() = _InitialField; const factory FieldEditorEvent.updateName(String name) = _UpdateName; + const factory FieldEditorEvent.didReceiveFieldChanged(Field field) = _DidReceiveFieldChanged; } @freezed @@ -50,13 +57,17 @@ class FieldEditorState with _$FieldEditorState { required String gridId, required String errorText, required String name, - required Option fieldContext, + required Option field, }) = _FieldEditorState; - factory FieldEditorState.initial(String gridId, String fieldName, IFieldTypeOptionLoader loader) => FieldEditorState( + factory FieldEditorState.initial( + String gridId, + String fieldName, + ) => + FieldEditorState( gridId: gridId, - fieldContext: none(), errorText: '', + field: none(), name: fieldName, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index e8e09a725b..de5b6adcb0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -1,4 +1,5 @@ import 'package:dartz/dartz.dart'; +import 'package:flowy_infra/notifier.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; @@ -193,14 +194,14 @@ class FieldTypeOptionLoader extends IFieldTypeOptionLoader { } } -class GridFieldContext { +class TypeOptionDataController { final String gridId; final IFieldTypeOptionLoader _loader; late FieldTypeOptionData _data; - ValueNotifier? _fieldNotifier; + final PublishNotifier _fieldNotifier = PublishNotifier(); - GridFieldContext({ + TypeOptionDataController({ required this.gridId, required IFieldTypeOptionLoader loader, }) : _loader = loader; @@ -211,13 +212,7 @@ class GridFieldContext { (data) { data.freeze(); _data = data; - - if (_fieldNotifier == null) { - _fieldNotifier = ValueNotifier(data.field_2); - } else { - _fieldNotifier?.value = data.field_2; - } - + _fieldNotifier.value = data.field_2; return left(unit); }, (err) { @@ -260,9 +255,7 @@ class GridFieldContext { } }); - if (_data.field_2 != _fieldNotifier?.value) { - _fieldNotifier?.value = _data.field_2; - } + _fieldNotifier.value = _data.field_2; FieldService.insertField( gridId: gridId, @@ -292,11 +285,11 @@ class GridFieldContext { callback(field); } - _fieldNotifier?.addListener(listener); + _fieldNotifier.addListener(listener); return listener; } void removeFieldListener(void Function() listener) { - _fieldNotifier?.removeListener(listener); + _fieldNotifier.removeListener(listener); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_type_option_edit_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_type_option_edit_bloc.dart index c92ad41d56..b9407ac2ad 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_type_option_edit_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_type_option_edit_bloc.dart @@ -8,17 +8,17 @@ import 'field_service.dart'; part 'field_type_option_edit_bloc.freezed.dart'; class FieldTypeOptionEditBloc extends Bloc { - final GridFieldContext _fieldContext; + final TypeOptionDataController _dataController; void Function()? _fieldListenFn; - FieldTypeOptionEditBloc(GridFieldContext fieldContext) - : _fieldContext = fieldContext, - super(FieldTypeOptionEditState.initial(fieldContext)) { + FieldTypeOptionEditBloc(TypeOptionDataController dataController) + : _dataController = dataController, + super(FieldTypeOptionEditState.initial(dataController)) { on( (event, emit) async { event.when( initial: () { - _fieldListenFn = fieldContext.addFieldListener((field) { + _fieldListenFn = dataController.addFieldListener((field) { add(FieldTypeOptionEditEvent.didReceiveFieldUpdated(field)); }); }, @@ -33,7 +33,7 @@ class FieldTypeOptionEditBloc extends Bloc close() async { if (_fieldListenFn != null) { - _fieldContext.removeFieldListener(_fieldListenFn!); + _dataController.removeFieldListener(_fieldListenFn!); } return super.close(); } @@ -51,7 +51,7 @@ class FieldTypeOptionEditState with _$FieldTypeOptionEditState { required Field field, }) = _FieldTypeOptionEditState; - factory FieldTypeOptionEditState.initial(GridFieldContext fieldContext) => FieldTypeOptionEditState( + factory FieldTypeOptionEditState.initial(TypeOptionDataController fieldContext) => FieldTypeOptionEditState( field: fieldContext.field, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart index eae1765396..0d9d75d4c7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart @@ -13,12 +13,12 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext Function(SelectOption) get deleteOption { diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart index 16e686fb44..b2b4581d96 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart @@ -13,12 +13,12 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext Function(SelectOption) get deleteOption { diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart index 05ca9e9aa1..c7c86ae661 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart @@ -39,30 +39,30 @@ abstract class TypeOptionDataParser { class TypeOptionWidgetContext { T? _typeOptionObject; - final GridFieldContext _fieldContext; + final TypeOptionDataController _dataController; final TypeOptionDataParser dataParser; TypeOptionWidgetContext({ required this.dataParser, - required GridFieldContext fieldContext, - }) : _fieldContext = fieldContext; + required TypeOptionDataController dataController, + }) : _dataController = dataController; - String get gridId => _fieldContext.gridId; + String get gridId => _dataController.gridId; - Field get field => _fieldContext.field; + Field get field => _dataController.field; T get typeOption { if (_typeOptionObject != null) { return _typeOptionObject!; } - final T object = dataParser.fromBuffer(_fieldContext.typeOptionData); + final T object = dataParser.fromBuffer(_dataController.typeOptionData); _typeOptionObject = object; return object; } set typeOption(T typeOption) { - _fieldContext.typeOptionData = typeOption.writeToBuffer(); + _dataController.typeOptionData = typeOption.writeToBuffer(); _typeOptionObject = typeOption; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart index 2ace435bf3..266ec5a619 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart @@ -65,7 +65,7 @@ class GridFieldCell extends StatelessWidget { FieldEditor( gridId: state.gridId, fieldName: field.name, - contextLoader: FieldTypeOptionLoader( + typeOptionLoader: FieldTypeOptionLoader( gridId: state.gridId, field: field, ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart index d3345b5b6f..3a857a9fb4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart @@ -14,11 +14,11 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate { final String gridId; final String fieldName; - final IFieldTypeOptionLoader contextLoader; + final IFieldTypeOptionLoader typeOptionLoader; const FieldEditor({ required this.gridId, required this.fieldName, - required this.contextLoader, + required this.typeOptionLoader, Key? key, }) : super(key: key); @@ -28,7 +28,7 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate { create: (context) => FieldEditorBloc( gridId: gridId, fieldName: fieldName, - fieldContextLoader: contextLoader, + loader: typeOptionLoader, )..add(const FieldEditorEvent.initial()), child: BlocBuilder( buildWhen: (p, c) => false, @@ -80,11 +80,14 @@ class _FieldTypeOptionCell extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder( - buildWhen: (p, c) => p.fieldContext != c.fieldContext, + buildWhen: (p, c) => p.field != c.field, builder: (context, state) { - return state.fieldContext.fold( + return state.field.fold( () => const SizedBox(), - (fieldContext) => FieldTypeOptionEditor(fieldContext: fieldContext), + (fieldContext) { + final dataController = context.read().dataController; + return FieldTypeOptionEditor(dataController: dataController); + }, ); }, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart index bca9b8e2f7..60592d1032 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart @@ -22,10 +22,10 @@ typedef SwitchToFieldCallback = Future> ); class FieldTypeOptionEditor extends StatefulWidget { - final GridFieldContext fieldContext; + final TypeOptionDataController dataController; const FieldTypeOptionEditor({ - required this.fieldContext, + required this.dataController, Key? key, }) : super(key: key); @@ -39,10 +39,11 @@ class _FieldTypeOptionEditorState extends State { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => FieldTypeOptionEditBloc(widget.fieldContext)..add(const FieldTypeOptionEditEvent.initial()), + create: (context) => + FieldTypeOptionEditBloc(widget.dataController)..add(const FieldTypeOptionEditEvent.initial()), child: BlocBuilder( builder: (context, state) { - List children = [_switchFieldTypeButton(context, widget.fieldContext.field)]; + List children = [_switchFieldTypeButton(context, widget.dataController.field)]; final typeOptionWidget = _typeOptionWidget(context: context, state: state); if (typeOptionWidget != null) { @@ -68,7 +69,7 @@ class _FieldTypeOptionEditorState extends State { hoverColor: theme.hover, onTap: () { final list = FieldTypeList(onSelectField: (newFieldType) { - widget.fieldContext.switchToField(newFieldType); + widget.dataController.switchToField(newFieldType); }); _showOverlay(context, list); }, @@ -89,7 +90,7 @@ class _FieldTypeOptionEditorState extends State { return makeTypeOptionWidget( context: context, - fieldContext: widget.fieldContext, + dataController: widget.dataController, overlayDelegate: overlayDelegate, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart index c63bd37d2e..2240d7f6aa 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart @@ -151,7 +151,7 @@ class CreateFieldButton extends StatelessWidget { onTap: () => FieldEditor( gridId: gridId, fieldName: "", - contextLoader: NewFieldTypeOptionLoader(gridId: gridId), + typeOptionLoader: NewFieldTypeOptionLoader(gridId: gridId), ).show(context), leftIcon: svgWidget("home/add"), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart index f63edbac14..63fa761d98 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart @@ -36,27 +36,27 @@ abstract class TypeOptionWidgetBuilder { Widget? makeTypeOptionWidget({ required BuildContext context, - required GridFieldContext fieldContext, + required TypeOptionDataController dataController, required TypeOptionOverlayDelegate overlayDelegate, }) { - final builder = makeTypeOptionWidgetBuilder(fieldContext, overlayDelegate); + final builder = makeTypeOptionWidgetBuilder(dataController, overlayDelegate); return builder.build(context); } TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( - GridFieldContext fieldContext, + TypeOptionDataController dataController, TypeOptionOverlayDelegate overlayDelegate, ) { - switch (fieldContext.field.fieldType) { + switch (dataController.field.fieldType) { case FieldType.Checkbox: final context = CheckboxTypeOptionContext( - fieldContext: fieldContext, + dataController: dataController, dataParser: CheckboxTypeOptionWidgetDataParser(), ); return CheckboxTypeOptionWidgetBuilder(context); case FieldType.DateTime: final context = DateTypeOptionContext( - fieldContext: fieldContext, + dataController: dataController, dataParser: DateTypeOptionDataParser(), ); return DateTypeOptionWidgetBuilder( @@ -65,7 +65,7 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( ); case FieldType.SingleSelect: final context = SingleSelectTypeOptionContext( - fieldContext: fieldContext, + fieldContext: dataController, dataBuilder: SingleSelectTypeOptionWidgetDataParser(), ); return SingleSelectTypeOptionWidgetBuilder( @@ -74,7 +74,7 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( ); case FieldType.MultiSelect: final context = MultiSelectTypeOptionContext( - fieldContext: fieldContext, + dataController: dataController, dataBuilder: MultiSelectTypeOptionWidgetDataParser(), ); return MultiSelectTypeOptionWidgetBuilder( @@ -83,7 +83,7 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( ); case FieldType.Number: final context = NumberTypeOptionContext( - fieldContext: fieldContext, + dataController: dataController, dataParser: NumberTypeOptionWidgetDataParser(), ); return NumberTypeOptionWidgetBuilder( @@ -92,14 +92,14 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( ); case FieldType.RichText: final context = RichTextTypeOptionContext( - fieldContext: fieldContext, + dataController: dataController, dataParser: RichTextTypeOptionWidgetDataParser(), ); return RichTextTypeOptionWidgetBuilder(context); case FieldType.URL: final context = URLTypeOptionContext( - fieldContext: fieldContext, + dataController: dataController, dataParser: URLTypeOptionWidgetDataParser(), ); return URLTypeOptionWidgetBuilder(context); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart index b10eeecb2c..4449ea6770 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart @@ -183,7 +183,7 @@ class _RowDetailCell extends StatelessWidget { FieldEditor( gridId: cellId.gridId, fieldName: cellId.field.name, - contextLoader: FieldTypeOptionLoader( + typeOptionLoader: FieldTypeOptionLoader( gridId: cellId.gridId, field: cellId.field, ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart index ac28ce9dbc..99d70e93c7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart @@ -116,7 +116,7 @@ class _GridPropertyCell extends StatelessWidget { FieldEditor( gridId: gridId, fieldName: field.name, - contextLoader: FieldTypeOptionLoader(gridId: gridId, field: field), + typeOptionLoader: FieldTypeOptionLoader(gridId: gridId, field: field), ).show(context, anchorDirection: AnchorDirection.bottomRight); }, );