fix: create option with different color

This commit is contained in:
appflowy 2022-05-04 20:34:28 +08:00
parent bd0907b0a4
commit 0b8083cfc6
12 changed files with 147 additions and 124 deletions

View File

@ -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>(

View File

@ -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(),
);
}

View File

@ -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),
);
}

View File

@ -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);
}

View File

@ -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';

View File

@ -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));

View File

@ -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(

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';