diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 58ad1cf9cc..2b37642f39 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -172,7 +172,7 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam<FieldEditorBloc, String, FieldContextLoader>( + getIt.registerFactoryParam<FieldEditorBloc, String, EditFieldContextLoader>( (gridId, fieldLoader) => FieldEditorBloc( service: FieldService(gridId: gridId), fieldLoader: fieldLoader, 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 dd27f66070..c38713862e 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 @@ -11,11 +11,11 @@ part 'field_editor_bloc.freezed.dart'; class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> { final FieldService service; - final FieldContextLoader _loader; + final EditFieldContextLoader _loader; FieldEditorBloc({ required this.service, - required FieldContextLoader fieldLoader, + required EditFieldContextLoader fieldLoader, }) : _loader = fieldLoader, super(FieldEditorState.initial(service.gridId)) { on<FieldEditorEvent>( 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 3ea1c46062..2336c4f340 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 @@ -112,11 +112,13 @@ class GridFieldCellContext extends Equatable { List<Object> get props => [field.id]; } -abstract class FieldContextLoader { +abstract class EditFieldContextLoader { Future<Either<EditFieldContext, FlowyError>> load(); + + Future<Either<EditFieldContext, FlowyError>> switchToField(String fieldId, FieldType fieldType); } -class NewFieldContextLoader extends FieldContextLoader { +class NewFieldContextLoader extends EditFieldContextLoader { final String gridId; NewFieldContextLoader({ required this.gridId, @@ -130,9 +132,18 @@ class NewFieldContextLoader extends FieldContextLoader { return GridEventGetEditFieldContext(payload).send(); } + + @override + Future<Either<EditFieldContext, FlowyError>> switchToField(String fieldId, FieldType fieldType) { + final payload = GetEditFieldContextPayload.create() + ..gridId = gridId + ..fieldType = fieldType; + + return GridEventGetEditFieldContext(payload).send(); + } } -class FieldContextLoaderAdaptor extends FieldContextLoader { +class FieldContextLoaderAdaptor extends EditFieldContextLoader { final String gridId; final Field field; @@ -150,4 +161,10 @@ class FieldContextLoaderAdaptor extends FieldContextLoader { return GridEventGetEditFieldContext(payload).send(); } + + @override + Future<Either<EditFieldContext, FlowyError>> switchToField(String fieldId, FieldType fieldType) async { + final fieldService = FieldService(gridId: gridId); + return fieldService.switchToField(fieldId, fieldType); + } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart index 802b39d95a..082c0decf4 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart @@ -1,11 +1,8 @@ import 'dart:typed_data'; -import 'package:flowy_sdk/log.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_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'field_service.dart'; part 'field_switch_bloc.freezed.dart'; @@ -15,15 +12,10 @@ class FieldSwitcherBloc extends Bloc<FieldSwitchEvent, FieldSwitchState> { (event, emit) async { await event.map( toFieldType: (_ToFieldType value) async { - final fieldService = FieldService(gridId: state.gridId); - final result = await fieldService.switchToField(state.field.id, value.fieldType); - result.fold( - (newEditContext) { - final typeOptionData = Uint8List.fromList(newEditContext.typeOptionData); - emit(state.copyWith(field: newEditContext.gridField, typeOptionData: typeOptionData)); - }, - (err) => Log.error(err), - ); + emit(state.copyWith( + field: value.field, + typeOptionData: Uint8List.fromList(value.typeOptionData), + )); }, didUpdateTypeOptionData: (_DidUpdateTypeOptionData value) { emit(state.copyWith(typeOptionData: value.typeOptionData)); @@ -41,7 +33,7 @@ class FieldSwitcherBloc extends Bloc<FieldSwitchEvent, FieldSwitchState> { @freezed class FieldSwitchEvent with _$FieldSwitchEvent { - const factory FieldSwitchEvent.toFieldType(FieldType fieldType) = _ToFieldType; + const factory FieldSwitchEvent.toFieldType(Field field, List<int> typeOptionData) = _ToFieldType; const factory FieldSwitchEvent.didUpdateTypeOptionData(Uint8List typeOptionData) = _DidUpdateTypeOptionData; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart index ae10505bc7..4145e23804 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_header_bloc.dart @@ -11,12 +11,12 @@ part 'grid_header_bloc.freezed.dart'; class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> { final FieldService service; - final GridFieldsListener fieldListener; + final GridFieldsListener _fieldListener; GridHeaderBloc({ required GridHeaderData data, required this.service, - }) : fieldListener = GridFieldsListener(gridId: data.gridId), + }) : _fieldListener = GridFieldsListener(gridId: data.gridId), super(GridHeaderState.initial(data.fields)) { on<GridHeaderEvent>( (event, emit) async { @@ -36,19 +36,19 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> { } Future<void> _startListening() async { - fieldListener.updateFieldsNotifier.addPublishListener((result) { + _fieldListener.updateFieldsNotifier.addPublishListener((result) { result.fold( (fields) => add(GridHeaderEvent.didReceiveFieldUpdate(fields)), (err) => Log.error(err), ); }); - fieldListener.start(); + _fieldListener.start(); } @override Future<void> close() async { - await fieldListener.stop(); + await _fieldListener.stop(); return super.close(); } } 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 3c29d82d46..418cb23e88 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 @@ -52,7 +52,7 @@ class RowBloc extends Bloc<RowEvent, RowState> { } void _handleRowUpdate(_DidUpdateRow value, Emitter<RowState> emit) { - final CellDataMap cellDataMap = _makeCellDatas(value.row); + final CellDataMap cellDataMap = _makeCellDatas(value.row, state.fields); emit(state.copyWith( row: Future(() => Some(value.row)), cellDataMap: Some(cellDataMap), @@ -63,7 +63,7 @@ class RowBloc extends Bloc<RowEvent, RowState> { final optionRow = await state.row; final CellDataMap cellDataMap = optionRow.fold( () => CellDataMap.identity(), - (row) => _makeCellDatas(row), + (row) => _makeCellDatas(row, value.fields), ); emit(state.copyWith( @@ -107,9 +107,9 @@ class RowBloc extends Bloc<RowEvent, RowState> { }); } - CellDataMap _makeCellDatas(Row row) { + CellDataMap _makeCellDatas(Row row, List<Field> fields) { var map = CellDataMap.new(); - for (final field in state.fields) { + for (final field in fields) { if (field.visibility) { map[field.id] = CellData( rowId: row.id, 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 d568829558..3a41ee938b 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 @@ -5,6 +5,7 @@ import 'package:app_flowy/workspace/application/grid/field/field_switch_bloc.dar import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_name_input.dart'; @@ -13,7 +14,7 @@ import 'field_switcher.dart'; class FieldEditor extends FlowyOverlayDelegate { final String gridId; final FieldEditorBloc _fieldEditorBloc; - final FieldContextLoader? fieldContextLoader; + final EditFieldContextLoader fieldContextLoader; FieldEditor({ required this.gridId, required this.fieldContextLoader, @@ -29,7 +30,7 @@ class FieldEditor extends FlowyOverlayDelegate { FlowyOverlay.of(context).remove(identifier()); FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( - child: _FieldEditorWidget(_fieldEditorBloc), + child: _FieldEditorWidget(_fieldEditorBloc, fieldContextLoader), constraints: BoxConstraints.loose(const Size(220, 400)), ), identifier: identifier(), @@ -55,7 +56,8 @@ class FieldEditor extends FlowyOverlayDelegate { class _FieldEditorWidget extends StatelessWidget { final FieldEditorBloc editorBloc; - const _FieldEditorWidget(this.editorBloc, {Key? key}) : super(key: key); + final EditFieldContextLoader fieldContextLoader; + const _FieldEditorWidget(this.editorBloc, this.fieldContextLoader, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -72,7 +74,7 @@ class _FieldEditorWidget extends StatelessWidget { const VSpace(10), const _FieldNameTextField(), const VSpace(10), - _FieldSwitcher(SwitchFieldContext(state.gridId, field, state.typeOptionData)), + _renderSwitchButton(context, field, state), ], ), ); @@ -80,16 +82,13 @@ class _FieldEditorWidget extends StatelessWidget { ), ); } -} -class _FieldSwitcher extends StatelessWidget { - final SwitchFieldContext switchContext; - const _FieldSwitcher(this.switchContext, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { + Widget _renderSwitchButton(BuildContext context, Field field, FieldEditorState state) { return FieldSwitcher( - switchContext: switchContext, + switchContext: SwitchFieldContext(state.gridId, field, state.typeOptionData), + onSwitchToField: (fieldId, fieldType) { + return fieldContextLoader.switchToField(fieldId, fieldType); + }, onUpdated: (field, typeOptionData) { context.read<FieldEditorBloc>().add(FieldEditorEvent.switchField(field, typeOptionData)); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart index 63816c7d74..decaaec611 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart @@ -7,6 +7,8 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.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:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart'; @@ -17,20 +19,26 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; import 'field_type_extension.dart'; - +import 'package:dartz/dartz.dart' show Either; import 'type_option/multi_select.dart'; import 'type_option/number.dart'; import 'type_option/single_select.dart'; typedef UpdateFieldCallback = void Function(Field, Uint8List); +typedef SwitchToFieldCallback = Future<Either<EditFieldContext, FlowyError>> Function( + String fieldId, + FieldType fieldType, +); class FieldSwitcher extends StatefulWidget { final SwitchFieldContext switchContext; final UpdateFieldCallback onUpdated; + final SwitchToFieldCallback onSwitchToField; const FieldSwitcher({ required this.switchContext, required this.onUpdated, + required this.onSwitchToField, Key? key, }) : super(key: key); @@ -79,8 +87,20 @@ class _FieldSwitcherState extends State<FieldSwitcher> { padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), hoverColor: theme.hover, onTap: () { - final list = FieldTypeList(onSelectField: (fieldType) { - context.read<FieldSwitcherBloc>().add(FieldSwitchEvent.toFieldType(fieldType)); + final list = FieldTypeList(onSelectField: (newFieldType) { + widget.onSwitchToField(field.id, newFieldType).then((result) { + result.fold( + (editFieldContext) { + context.read<FieldSwitcherBloc>().add( + FieldSwitchEvent.toFieldType( + editFieldContext.gridField, + editFieldContext.typeOptionData, + ), + ); + }, + (err) => Log.error(err), + ); + }); }); _showOverlay(context, list); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index d3ac6d8ce3..08d68f197a 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -19,12 +19,12 @@ class GridRowWidget extends StatefulWidget { class _GridRowWidgetState extends State<GridRowWidget> { late RowBloc _rowBloc; - late RowRegionStateNotifier _rowStateNotifier; + late _RegionStateNotifier _rowStateNotifier; @override void initState() { _rowBloc = getIt<RowBloc>(param1: widget.data)..add(const RowEvent.initial()); - _rowStateNotifier = RowRegionStateNotifier(); + _rowStateNotifier = _RegionStateNotifier(); super.initState(); } @@ -72,7 +72,7 @@ class _RowLeading extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer<RowRegionStateNotifier>( + return Consumer<_RegionStateNotifier>( builder: (context, state, _) { return SizedBox(width: GridSize.leadingHeaderPadding, child: state.onEnter ? _activeWidget() : null); }, @@ -140,7 +140,7 @@ class _RowCells extends StatelessWidget { } } -class RowRegionStateNotifier extends ChangeNotifier { +class _RegionStateNotifier extends ChangeNotifier { bool _onEnter = false; set onEnter(bool value) {