Browse Source

fix: create option with different color

appflowy 3 years ago
parent
commit
0b8083cfc6

+ 3 - 2
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<FieldSwitcherBloc, SwitchFieldContext, void>(
-    (context, _) => FieldSwitcherBloc(context),
+  getIt.registerFactoryParam<FieldEditorPannelBloc, EditFieldContext, void>(
+    (context, _) => FieldEditorPannelBloc(context),
   );
 
   getIt.registerFactoryParam<DateTypeOptionBloc, DateTypeOption, void>(

+ 52 - 19
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<FieldEditorEvent, FieldEditorState> {
             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<FieldEditorEvent, FieldEditorState> {
     return super.close();
   }
 
+  Option<EditFieldContext> _updateEditContext({
+    String? name,
+    Field? field,
+    List<int>? 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<void> _saveField(Emitter<FieldEditorState> 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<FieldEditorEvent, FieldEditorState> {
   Future<void> _getEditFieldContext(Emitter<FieldEditorState> 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<FieldEditorEvent, FieldEditorState> {
 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> field,
-    required List<int> typeOptionData,
+    required Option<EditFieldContext> editFieldContext,
   }) = _FieldEditorState;
 
   factory FieldEditorState.initial(String gridId) => FieldEditorState(
         gridId: gridId,
-        fieldName: '',
-        field: none(),
+        editFieldContext: none(),
         errorText: '',
-        typeOptionData: List<int>.empty(),
       );
 }

+ 53 - 0
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<FieldEditorPannelEvent, FieldEditorPannelState> {
+  FieldEditorPannelBloc(EditFieldContext editContext) : super(FieldEditorPannelState.initial(editContext)) {
+    on<FieldEditorPannelEvent>(
+      (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<void> close() async {
+    return super.close();
+  }
+}
+
+@freezed
+class FieldEditorPannelEvent with _$FieldEditorPannelEvent {
+  const factory FieldEditorPannelEvent.toFieldType(Field field, List<int> 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),
+      );
+}

+ 0 - 61
frontend/app_flowy/lib/workspace/application/grid/field/field_switch_bloc.dart

@@ -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<FieldSwitchEvent, FieldSwitchState> {
-  FieldSwitcherBloc(SwitchFieldContext editContext) : super(FieldSwitchState.initial(editContext)) {
-    on<FieldSwitchEvent>(
-      (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<void> close() async {
-    return super.close();
-  }
-}
-
-@freezed
-class FieldSwitchEvent with _$FieldSwitchEvent {
-  const factory FieldSwitchEvent.toFieldType(Field field, List<int> 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<int> typeOptionData;
-
-  SwitchFieldContext(this.gridId, this.field, this.typeOptionData);
-}

+ 1 - 1
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';

+ 21 - 24
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<FieldEditorBloc, FieldEditorState>(
         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<FieldEditorBloc>().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<FieldEditorBloc>().add(FieldEditorEvent.switchField(field, typeOptionData));
-      },
-    );
-  }
 }
 
 class _FieldNameTextField extends StatelessWidget {
@@ -105,11 +97,16 @@ class _FieldNameTextField extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<FieldEditorBloc, FieldEditorState>(
-      buildWhen: (previous, current) => previous.fieldName != current.fieldName,
-      builder: (context, state) {
+    return BlocSelector<FieldEditorBloc, FieldEditorState, String>(
+      selector: (state) {
+        return state.editFieldContext.fold(
+          () => "",
+          (editFieldContext) => editFieldContext.gridField.name,
+        );
+      },
+      builder: (context, name) {
         return FieldNameTextField(
-          name: state.fieldName,
+          name: name,
           errorText: context.read<FieldEditorBloc>().state.errorText,
           onNameChanged: (newName) {
             context.read<FieldEditorBloc>().add(FieldEditorEvent.updateName(newName));

+ 12 - 12
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart → frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart

@@ -30,30 +30,30 @@ typedef SwitchToFieldCallback = Future<Either<EditFieldContext, FlowyError>> 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<FieldSwitcher> createState() => _FieldSwitcherState();
+  State<FieldEditorPannel> createState() => _FieldEditorPannelState();
 }
 
-class _FieldSwitcherState extends State<FieldSwitcher> {
+class _FieldEditorPannelState extends State<FieldEditorPannel> {
   String? currentOverlayIdentifier;
 
   @override
   Widget build(BuildContext context) {
     return BlocProvider(
-      create: (context) => getIt<FieldSwitcherBloc>(param1: widget.switchContext),
-      child: BlocConsumer<FieldSwitcherBloc, FieldSwitchState>(
+      create: (context) => getIt<FieldEditorPannelBloc>(param1: widget.editFieldContext),
+      child: BlocConsumer<FieldEditorPannelBloc, FieldEditorPannelState>(
         listener: (context, state) {
           widget.onUpdated(state.field, state.typeOptionData);
         },
@@ -87,8 +87,8 @@ class _FieldSwitcherState extends State<FieldSwitcher> {
             widget.onSwitchToField(field.id, newFieldType).then((result) {
               result.fold(
                 (editFieldContext) {
-                  context.read<FieldSwitcherBloc>().add(
-                        FieldSwitchEvent.toFieldType(
+                  context.read<FieldEditorPannelBloc>().add(
+                        FieldEditorPannelEvent.toFieldType(
                           editFieldContext.gridField,
                           editFieldContext.typeOptionData,
                         ),
@@ -108,7 +108,7 @@ class _FieldSwitcherState extends State<FieldSwitcher> {
 
   Widget? _typeOptionWidget({
     required BuildContext context,
-    required FieldSwitchState state,
+    required FieldEditorPannelState state,
   }) {
     final overlayDelegate = TypeOptionOverlayDelegate(
       showOverlay: _showOverlay,
@@ -116,7 +116,7 @@ class _FieldSwitcherState extends State<FieldSwitcher> {
     );
 
     final dataDelegate = TypeOptionDataDelegate(didUpdateTypeOptionData: (data) {
-      context.read<FieldSwitcherBloc>().add(FieldSwitchEvent.didUpdateTypeOptionData(data));
+      context.read<FieldEditorPannelBloc>().add(FieldEditorPannelEvent.didUpdateTypeOptionData(data));
     });
 
     final typeOptionContext = TypeOptionContext(

+ 1 - 1
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';

+ 1 - 1
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';

+ 1 - 1
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';
 

+ 1 - 1
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';

+ 1 - 1
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';