From 0b8083cfc647b29ff2280726a0fc751ffbbf5344 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 4 May 2022 20:34:28 +0800 Subject: [PATCH] fix: create option with different color --- .../app_flowy/lib/startup/deps_resolver.dart | 5 +- .../grid/field/field_editor_bloc.dart | 71 ++++++++++++++----- .../grid/field/field_editor_pannel_bloc.dart | 53 ++++++++++++++ .../grid/field/field_switch_bloc.dart | 61 ---------------- .../workspace/application/grid/prelude.dart | 2 +- .../grid/src/widgets/header/field_editor.dart | 45 ++++++------ ...switcher.dart => field_editor_pannel.dart} | 24 +++---- .../src/widgets/header/type_option/date.dart | 2 +- .../type_option/field_option_pannel.dart | 2 +- .../header/type_option/multi_select.dart | 2 +- .../widgets/header/type_option/number.dart | 2 +- .../header/type_option/single_select.dart | 2 +- 12 files changed, 147 insertions(+), 124 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_editor_pannel_bloc.dart delete mode 100644 frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/{field_switcher.dart => field_editor_pannel.dart} (91%) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index fb5cad590e..a0daac273d 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -17,6 +17,7 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:app_flowy/workspace/presentation/home/menu/menu.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show EditFieldContext; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; @@ -201,8 +202,8 @@ void _resolveGridDeps(GetIt getIt) { ), ); - getIt.registerFactoryParam( - (context, _) => FieldSwitcherBloc(context), + getIt.registerFactoryParam( + (context, _) => FieldEditorPannelBloc(context), ); getIt.registerFactoryParam( 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 c38713862e..b3c37dbd76 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 @@ -6,6 +6,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'field_service.dart'; import 'package:dartz/dartz.dart'; +import 'package:protobuf/protobuf.dart'; part 'field_editor_bloc.freezed.dart'; @@ -25,10 +26,13 @@ class FieldEditorBloc extends Bloc { await _getEditFieldContext(emit); }, updateName: (_UpdateName value) { - emit(state.copyWith(fieldName: value.name)); + final newContext = _updateEditContext(name: value.name); + emit(state.copyWith(editFieldContext: newContext)); }, - switchField: (_SwitchField value) { - emit(state.copyWith(field: Some(value.field), typeOptionData: value.typeOptionData)); + updateField: (_UpdateField value) { + final newContext = _updateEditContext(field: value.field, typeOptionData: value.typeOptionData); + + emit(state.copyWith(editFieldContext: newContext)); }, done: (_Done value) async { await _saveField(emit); @@ -43,14 +47,49 @@ class FieldEditorBloc extends Bloc { return super.close(); } + Option _updateEditContext({ + String? name, + Field? field, + List? typeOptionData, + }) { + return state.editFieldContext.fold( + () => none(), + (context) { + context.freeze(); + final newContext = context.rebuild((newContext) { + newContext.gridField.rebuild((newField) { + if (name != null) { + newField.name = name; + } + + newContext.gridField = newField; + }); + + if (field != null) { + newContext.gridField = field; + } + + if (typeOptionData != null) { + newContext.typeOptionData = typeOptionData; + } + }); + service.insertField( + field: newContext.gridField, + typeOptionData: newContext.typeOptionData, + ); + + return Some(newContext); + }, + ); + } + Future _saveField(Emitter emit) async { - await state.field.fold( + await state.editFieldContext.fold( () async => null, - (field) async { - field.name = state.fieldName; + (context) async { final result = await service.insertField( - field: field, - typeOptionData: state.typeOptionData, + field: context.gridField, + typeOptionData: context.typeOptionData, ); result.fold((l) => null, (r) => null); }, @@ -60,11 +99,9 @@ class FieldEditorBloc extends Bloc { Future _getEditFieldContext(Emitter emit) async { final result = await _loader.load(); result.fold( - (editContext) { + (context) { emit(state.copyWith( - field: Some(editContext.gridField), - typeOptionData: editContext.typeOptionData, - fieldName: editContext.gridField.name, + editFieldContext: Some(context), )); }, (err) => Log.error(err), @@ -76,25 +113,21 @@ class FieldEditorBloc extends Bloc { class FieldEditorEvent with _$FieldEditorEvent { const factory FieldEditorEvent.initial() = _InitialField; const factory FieldEditorEvent.updateName(String name) = _UpdateName; - const factory FieldEditorEvent.switchField(Field field, Uint8List typeOptionData) = _SwitchField; + const factory FieldEditorEvent.updateField(Field field, Uint8List typeOptionData) = _UpdateField; const factory FieldEditorEvent.done() = _Done; } @freezed class FieldEditorState with _$FieldEditorState { const factory FieldEditorState({ - required String fieldName, required String gridId, required String errorText, - required Option field, - required List typeOptionData, + required Option editFieldContext, }) = _FieldEditorState; factory FieldEditorState.initial(String gridId) => FieldEditorState( gridId: gridId, - fieldName: '', - field: none(), + editFieldContext: none(), errorText: '', - typeOptionData: List.empty(), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_pannel_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_pannel_bloc.dart new file mode 100644 index 0000000000..09d0268d63 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_pannel_bloc.dart @@ -0,0 +1,53 @@ +import 'dart:typed_data'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'dart:async'; + +part 'field_editor_pannel_bloc.freezed.dart'; + +class FieldEditorPannelBloc extends Bloc { + FieldEditorPannelBloc(EditFieldContext editContext) : super(FieldEditorPannelState.initial(editContext)) { + on( + (event, emit) async { + await event.map( + toFieldType: (_ToFieldType value) async { + emit(state.copyWith( + field: value.field, + typeOptionData: Uint8List.fromList(value.typeOptionData), + )); + }, + didUpdateTypeOptionData: (_DidUpdateTypeOptionData value) { + emit(state.copyWith(typeOptionData: value.typeOptionData)); + }, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +class FieldEditorPannelEvent with _$FieldEditorPannelEvent { + const factory FieldEditorPannelEvent.toFieldType(Field field, List typeOptionData) = _ToFieldType; + const factory FieldEditorPannelEvent.didUpdateTypeOptionData(Uint8List typeOptionData) = _DidUpdateTypeOptionData; +} + +@freezed +class FieldEditorPannelState with _$FieldEditorPannelState { + const factory FieldEditorPannelState({ + required String gridId, + required Field field, + required Uint8List typeOptionData, + }) = _FieldEditorPannelState; + + factory FieldEditorPannelState.initial(EditFieldContext context) => FieldEditorPannelState( + gridId: context.gridId, + field: context.gridField, + typeOptionData: Uint8List.fromList(context.typeOptionData), + ); +} 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 deleted file mode 100644 index 082c0decf4..0000000000 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'dart:typed_data'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'dart:async'; - -part 'field_switch_bloc.freezed.dart'; - -class FieldSwitcherBloc extends Bloc { - FieldSwitcherBloc(SwitchFieldContext editContext) : super(FieldSwitchState.initial(editContext)) { - on( - (event, emit) async { - await event.map( - toFieldType: (_ToFieldType value) async { - emit(state.copyWith( - field: value.field, - typeOptionData: Uint8List.fromList(value.typeOptionData), - )); - }, - didUpdateTypeOptionData: (_DidUpdateTypeOptionData value) { - emit(state.copyWith(typeOptionData: value.typeOptionData)); - }, - ); - }, - ); - } - - @override - Future close() async { - return super.close(); - } -} - -@freezed -class FieldSwitchEvent with _$FieldSwitchEvent { - const factory FieldSwitchEvent.toFieldType(Field field, List typeOptionData) = _ToFieldType; - const factory FieldSwitchEvent.didUpdateTypeOptionData(Uint8List typeOptionData) = _DidUpdateTypeOptionData; -} - -@freezed -class FieldSwitchState with _$FieldSwitchState { - const factory FieldSwitchState({ - required String gridId, - required Field field, - required Uint8List typeOptionData, - }) = _FieldSwitchState; - - factory FieldSwitchState.initial(SwitchFieldContext switchContext) => FieldSwitchState( - gridId: switchContext.gridId, - field: switchContext.field, - typeOptionData: Uint8List.fromList(switchContext.typeOptionData), - ); -} - -class SwitchFieldContext { - final String gridId; - final Field field; - final List typeOptionData; - - SwitchFieldContext(this.gridId, this.field, this.typeOptionData); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 16287db6bf..92b4d757f0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -8,7 +8,7 @@ export 'grid_header_bloc.dart'; export 'field/field_service.dart'; export 'field/field_action_sheet_bloc.dart'; export 'field/field_editor_bloc.dart'; -export 'field/field_switch_bloc.dart'; +export 'field/field_editor_pannel_bloc.dart'; // Field Type Option export 'field/type_option/date_bloc.dart'; 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 723783fb95..11e55e0e06 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 @@ -1,18 +1,15 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/field_editor_bloc.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; -import 'package:app_flowy/workspace/application/grid/field/field_switch_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; 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/log.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 'package:app_flowy/generated/locale_keys.g.dart'; import 'field_name_input.dart'; -import 'field_switcher.dart'; +import 'field_editor_pannel.dart'; class FieldEditor extends FlowyOverlayDelegate { final String gridId; @@ -30,7 +27,6 @@ class FieldEditor extends FlowyOverlayDelegate { BuildContext context, { AnchorDirection anchorDirection = AnchorDirection.bottomWithLeftAligned, }) { - Log.trace("Show $identifier()"); FlowyOverlay.of(context).remove(identifier()); FlowyOverlay.of(context).insertWithAnchor( widget: OverlayContainer( @@ -69,16 +65,24 @@ class _FieldEditorWidget extends StatelessWidget { value: editorBloc, child: BlocBuilder( builder: (context, state) { - return state.field.fold( + return state.editFieldContext.fold( () => const SizedBox(), - (field) => ListView( + (editFieldContext) => ListView( shrinkWrap: true, children: [ FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12), const VSpace(10), const _FieldNameTextField(), const VSpace(10), - _renderSwitchButton(context, field, state), + FieldEditorPannel( + editFieldContext: editFieldContext, + onSwitchToField: (fieldId, fieldType) { + return fieldContextLoader.switchToField(fieldId, fieldType); + }, + onUpdated: (field, typeOptionData) { + context.read().add(FieldEditorEvent.updateField(field, typeOptionData)); + }, + ), ], ), ); @@ -86,18 +90,6 @@ class _FieldEditorWidget extends StatelessWidget { ), ); } - - Widget _renderSwitchButton(BuildContext context, Field field, FieldEditorState state) { - return FieldSwitcher( - switchContext: SwitchFieldContext(state.gridId, field, state.typeOptionData), - onSwitchToField: (fieldId, fieldType) { - return fieldContextLoader.switchToField(fieldId, fieldType); - }, - onUpdated: (field, typeOptionData) { - context.read().add(FieldEditorEvent.switchField(field, typeOptionData)); - }, - ); - } } class _FieldNameTextField extends StatelessWidget { @@ -105,11 +97,16 @@ class _FieldNameTextField extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - buildWhen: (previous, current) => previous.fieldName != current.fieldName, - builder: (context, state) { + return BlocSelector( + selector: (state) { + return state.editFieldContext.fold( + () => "", + (editFieldContext) => editFieldContext.gridField.name, + ); + }, + builder: (context, name) { return FieldNameTextField( - name: state.fieldName, + name: name, errorText: context.read().state.errorText, onNameChanged: (newName) { context.read().add(FieldEditorEvent.updateName(newName)); 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_editor_pannel.dart similarity index 91% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart index 1a44f439e2..1258847520 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_editor_pannel.dart @@ -30,30 +30,30 @@ typedef SwitchToFieldCallback = Future> Fun FieldType fieldType, ); -class FieldSwitcher extends StatefulWidget { - final SwitchFieldContext switchContext; +class FieldEditorPannel extends StatefulWidget { + final EditFieldContext editFieldContext; final UpdateFieldCallback onUpdated; final SwitchToFieldCallback onSwitchToField; - const FieldSwitcher({ - required this.switchContext, + const FieldEditorPannel({ + required this.editFieldContext, required this.onUpdated, required this.onSwitchToField, Key? key, }) : super(key: key); @override - State createState() => _FieldSwitcherState(); + State createState() => _FieldEditorPannelState(); } -class _FieldSwitcherState extends State { +class _FieldEditorPannelState extends State { String? currentOverlayIdentifier; @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: widget.switchContext), - child: BlocConsumer( + create: (context) => getIt(param1: widget.editFieldContext), + child: BlocConsumer( listener: (context, state) { widget.onUpdated(state.field, state.typeOptionData); }, @@ -87,8 +87,8 @@ class _FieldSwitcherState extends State { widget.onSwitchToField(field.id, newFieldType).then((result) { result.fold( (editFieldContext) { - context.read().add( - FieldSwitchEvent.toFieldType( + context.read().add( + FieldEditorPannelEvent.toFieldType( editFieldContext.gridField, editFieldContext.typeOptionData, ), @@ -108,7 +108,7 @@ class _FieldSwitcherState extends State { Widget? _typeOptionWidget({ required BuildContext context, - required FieldSwitchState state, + required FieldEditorPannelState state, }) { final overlayDelegate = TypeOptionOverlayDelegate( showOverlay: _showOverlay, @@ -116,7 +116,7 @@ class _FieldSwitcherState extends State { ); final dataDelegate = TypeOptionDataDelegate(didUpdateTypeOptionData: (data) { - context.read().add(FieldSwitchEvent.didUpdateTypeOptionData(data)); + context.read().add(FieldEditorPannelEvent.didUpdateTypeOptionData(data)); }); final typeOptionContext = TypeOptionContext( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index a580bbebf1..2d920cbbf2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -1,7 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/date_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart'; import 'package:easy_localization/easy_localization.dart' hide DateFormat; import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:flowy_infra/image.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart index 5e85ba9474..ce6c69d2cd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/field_option_pannel.dart @@ -1,7 +1,7 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/field_option_pannel_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart index fb5da57bec..b5b3ece1a8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart index 591b54187f..b887fd53a9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -3,7 +3,7 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/number_bl import 'package:app_flowy/workspace/application/grid/field/type_option/number_format_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart index 89d2f63a2d..f8cc2293f6 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_bloc.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_option_pannel.dart';