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_type_option_edit_bloc.dart similarity index 51% rename from frontend/app_flowy/lib/workspace/application/grid/field/field_editor_pannel_bloc.dart rename to frontend/app_flowy/lib/workspace/application/grid/field/field_type_option_edit_bloc.dart index 6310452d48..c92ad41d56 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_editor_pannel_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_type_option_edit_bloc.dart @@ -5,21 +5,21 @@ import 'dart:async'; import 'field_service.dart'; -part 'field_editor_pannel_bloc.freezed.dart'; +part 'field_type_option_edit_bloc.freezed.dart'; -class FieldEditorPannelBloc extends Bloc { +class FieldTypeOptionEditBloc extends Bloc { final GridFieldContext _fieldContext; void Function()? _fieldListenFn; - FieldEditorPannelBloc(GridFieldContext fieldContext) + FieldTypeOptionEditBloc(GridFieldContext fieldContext) : _fieldContext = fieldContext, - super(FieldEditorPannelState.initial(fieldContext)) { - on( + super(FieldTypeOptionEditState.initial(fieldContext)) { + on( (event, emit) async { event.when( initial: () { _fieldListenFn = fieldContext.addFieldListener((field) { - add(FieldEditorPannelEvent.didReceiveFieldUpdated(field)); + add(FieldTypeOptionEditEvent.didReceiveFieldUpdated(field)); }); }, didReceiveFieldUpdated: (field) { @@ -40,18 +40,18 @@ class FieldEditorPannelBloc extends Bloc FieldEditorPannelState( + factory FieldTypeOptionEditState.initial(GridFieldContext fieldContext) => FieldTypeOptionEditState( field: fieldContext.field, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart index 8784422c54..73be8a427e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart @@ -6,9 +6,9 @@ import 'dart:async'; import 'package:protobuf/protobuf.dart'; part 'date_bloc.freezed.dart'; -typedef DateTypeOptionContext = TypeOptionContext; +typedef DateTypeOptionContext = TypeOptionWidgetContext; -class DateTypeOptionDataBuilder extends TypeOptionDataBuilder { +class DateTypeOptionDataParser extends TypeOptionWidgetDataParser { @override DateTypeOption fromBuffer(List buffer) { return DateTypeOption.fromBuffer(buffer); 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 0a6e2de14c..f36974f8e3 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 @@ -7,11 +7,12 @@ import 'package:protobuf/protobuf.dart'; import 'select_option_type_option_bloc.dart'; import 'type_option_service.dart'; -class MultiSelectTypeOptionContext extends TypeOptionContext with SelectOptionTypeOptionAction { +class MultiSelectTypeOptionContext extends TypeOptionWidgetContext + with SelectOptionTypeOptionAction { final TypeOptionService service; MultiSelectTypeOptionContext({ - required MultiSelectTypeOptionDataBuilder dataBuilder, + required MultiSelectTypeOptionWidgetDataParser dataBuilder, required GridFieldContext fieldContext, }) : service = TypeOptionService( gridId: fieldContext.gridId, @@ -70,7 +71,7 @@ class MultiSelectTypeOptionContext extends TypeOptionContext { +class MultiSelectTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { @override MultiSelectTypeOption fromBuffer(List buffer) { return MultiSelectTypeOption.fromBuffer(buffer); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart index a708668066..ea51970b32 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart @@ -8,9 +8,9 @@ import 'package:protobuf/protobuf.dart'; part 'number_bloc.freezed.dart'; -typedef NumberTypeOptionContext = TypeOptionContext; +typedef NumberTypeOptionContext = TypeOptionWidgetContext; -class NumberTypeOptionDataBuilder extends TypeOptionDataBuilder { +class NumberTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { @override NumberTypeOption fromBuffer(List buffer) { return NumberTypeOption.fromBuffer(buffer); 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 c09d17f11e..0dc05e8e1f 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 @@ -7,12 +7,12 @@ import 'package:protobuf/protobuf.dart'; import 'select_option_type_option_bloc.dart'; import 'type_option_service.dart'; -class SingleSelectTypeOptionContext extends TypeOptionContext +class SingleSelectTypeOptionContext extends TypeOptionWidgetContext with SelectOptionTypeOptionAction { final TypeOptionService service; SingleSelectTypeOptionContext({ - required SingleSelectTypeOptionDataBuilder dataBuilder, + required SingleSelectTypeOptionWidgetDataParser dataBuilder, required GridFieldContext fieldContext, }) : service = TypeOptionService( gridId: fieldContext.gridId, @@ -71,7 +71,7 @@ class SingleSelectTypeOptionContext extends TypeOptionContext { +class SingleSelectTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { @override SingleSelectTypeOption fromBuffer(List buffer) { return SingleSelectTypeOption.fromBuffer(buffer); 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 3a30ef30ca..84faa3c35a 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 @@ -33,16 +33,16 @@ class TypeOptionService { } } -abstract class TypeOptionDataBuilder { +abstract class TypeOptionWidgetDataParser { T fromBuffer(List buffer); } -class TypeOptionContext { +class TypeOptionWidgetContext { T? _typeOptionObject; final GridFieldContext _fieldContext; - final TypeOptionDataBuilder dataBuilder; + final TypeOptionWidgetDataParser dataBuilder; - TypeOptionContext({ + TypeOptionWidgetContext({ required this.dataBuilder, required GridFieldContext fieldContext, }) : _fieldContext = fieldContext; @@ -77,7 +77,7 @@ class TypeOptionContext2 { final Field field; final FieldService _fieldService; T? _data; - final TypeOptionDataBuilder dataBuilder; + final TypeOptionWidgetDataParser dataBuilder; TypeOptionContext2({ required this.gridId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 6ea198f303..9c09a038e1 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_editor_pannel_bloc.dart'; +export 'field/field_type_option_edit_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 3390351663..148727752c 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 @@ -8,7 +8,7 @@ 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_editor_pannel.dart'; +import 'field_type_option_editor.dart'; class FieldEditor extends StatelessWidget with FlowyOverlayDelegate { final String gridId; @@ -38,9 +38,9 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate { children: [ FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(), fontSize: 12), const VSpace(10), - const _FieldNameTextField(), + const _FieldNameCell(), const VSpace(10), - const _FieldPannel(), + const _FieldTypeOptionCell(), ], ); }, @@ -74,8 +74,8 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate { bool asBarrier() => true; } -class _FieldPannel extends StatelessWidget { - const _FieldPannel({Key? key}) : super(key: key); +class _FieldTypeOptionCell extends StatelessWidget { + const _FieldTypeOptionCell({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -84,15 +84,15 @@ class _FieldPannel extends StatelessWidget { builder: (context, state) { return state.fieldContext.fold( () => const SizedBox(), - (fieldContext) => FieldEditorPannel(fieldContext: fieldContext), + (fieldContext) => FieldTypeOptionEditor(fieldContext: fieldContext), ); }, ); } } -class _FieldNameTextField extends StatelessWidget { - const _FieldNameTextField({Key? key}) : super(key: key); +class _FieldNameCell extends StatelessWidget { + const _FieldNameCell({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart deleted file mode 100644 index 7ec5144458..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart +++ /dev/null @@ -1,243 +0,0 @@ -import 'dart:typed_data'; - -import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_type_option.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/type_option/checkbox.dart'; -import 'package:dartz/dartz.dart' show Either; -import 'package:flowy_infra/image.dart'; -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/protobuf/flowy-error/errors.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/prelude.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_type_list.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart'; -import 'field_type_extension.dart'; -import 'type_option/multi_select.dart'; -import 'type_option/number.dart'; -import 'type_option/rich_text.dart'; -import 'type_option/single_select.dart'; -import 'type_option/url.dart'; - -typedef UpdateFieldCallback = void Function(Field, Uint8List); -typedef SwitchToFieldCallback = Future> Function( - String fieldId, - FieldType fieldType, -); - -class FieldEditorPannel extends StatefulWidget { - final GridFieldContext fieldContext; - - const FieldEditorPannel({ - required this.fieldContext, - Key? key, - }) : super(key: key); - - @override - State createState() => _FieldEditorPannelState(); -} - -class _FieldEditorPannelState extends State { - String? currentOverlayIdentifier; - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => FieldEditorPannelBloc(widget.fieldContext)..add(const FieldEditorPannelEvent.initial()), - child: BlocBuilder( - builder: (context, state) { - List children = [_switchFieldTypeButton(context, widget.fieldContext.field)]; - final typeOptionWidget = _typeOptionWidget(context: context, state: state); - - if (typeOptionWidget != null) { - children.add(typeOptionWidget); - } - - return ListView( - shrinkWrap: true, - children: children, - ); - }, - ), - ); - } - - Widget _switchFieldTypeButton(BuildContext context, Field field) { - final theme = context.watch(); - return SizedBox( - height: GridSize.typeOptionItemHeight, - child: FlowyButton( - text: FlowyText.medium(field.fieldType.title(), fontSize: 12), - margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), - hoverColor: theme.hover, - onTap: () { - final list = FieldTypeList(onSelectField: (newFieldType) { - widget.fieldContext.switchToField(newFieldType); - }); - _showOverlay(context, list); - }, - leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), - rightIcon: svgWidget("grid/more", color: theme.iconColor), - ), - ); - } - - Widget? _typeOptionWidget({ - required BuildContext context, - required FieldEditorPannelState state, - }) { - final overlayDelegate = TypeOptionOverlayDelegate( - showOverlay: _showOverlay, - hideOverlay: _hideOverlay, - ); - - final builder = _makeTypeOptionBuild( - typeOptionContext: _makeTypeOptionContext(widget.fieldContext), - overlayDelegate: overlayDelegate, - ); - - return builder.customWidget; - } - - void _showOverlay(BuildContext context, Widget child, {VoidCallback? onRemoved}) { - final identifier = child.toString(); - if (currentOverlayIdentifier != null) { - FlowyOverlay.of(context).remove(currentOverlayIdentifier!); - } - - currentOverlayIdentifier = identifier; - FlowyOverlay.of(context).insertWithAnchor( - widget: OverlayContainer( - child: child, - constraints: BoxConstraints.loose(const Size(460, 440)), - ), - identifier: identifier, - anchorContext: context, - anchorDirection: AnchorDirection.leftWithCenterAligned, - style: FlowyOverlayStyle(blur: false), - anchorOffset: const Offset(-20, 0), - ); - } - - void _hideOverlay(BuildContext context) { - if (currentOverlayIdentifier != null) { - FlowyOverlay.of(context).remove(currentOverlayIdentifier!); - } - } -} - -abstract class TypeOptionBuilder { - Widget? get customWidget; -} - -TypeOptionBuilder _makeTypeOptionBuild({ - required TypeOptionContext typeOptionContext, - required TypeOptionOverlayDelegate overlayDelegate, -}) { - switch (typeOptionContext.field.fieldType) { - case FieldType.Checkbox: - return CheckboxTypeOptionBuilder( - typeOptionContext as CheckboxTypeOptionContext, - ); - case FieldType.DateTime: - return DateTypeOptionBuilder( - typeOptionContext as DateTypeOptionContext, - overlayDelegate, - ); - case FieldType.SingleSelect: - return SingleSelectTypeOptionBuilder( - typeOptionContext as SingleSelectTypeOptionContext, - overlayDelegate, - ); - case FieldType.MultiSelect: - return MultiSelectTypeOptionBuilder( - typeOptionContext as MultiSelectTypeOptionContext, - overlayDelegate, - ); - case FieldType.Number: - return NumberTypeOptionBuilder( - typeOptionContext as NumberTypeOptionContext, - overlayDelegate, - ); - case FieldType.RichText: - return RichTextTypeOptionBuilder( - typeOptionContext as RichTextTypeOptionContext, - ); - - case FieldType.URL: - return URLTypeOptionBuilder( - typeOptionContext as URLTypeOptionContext, - ); - } - throw UnimplementedError; -} - -TypeOptionContext _makeTypeOptionContext(GridFieldContext fieldContext) { - switch (fieldContext.field.fieldType) { - case FieldType.Checkbox: - return CheckboxTypeOptionContext( - fieldContext: fieldContext, - dataBuilder: CheckboxTypeOptionDataBuilder(), - ); - case FieldType.DateTime: - return DateTypeOptionContext( - fieldContext: fieldContext, - dataBuilder: DateTypeOptionDataBuilder(), - ); - case FieldType.MultiSelect: - return MultiSelectTypeOptionContext( - fieldContext: fieldContext, - dataBuilder: MultiSelectTypeOptionDataBuilder(), - ); - case FieldType.Number: - return NumberTypeOptionContext( - fieldContext: fieldContext, - dataBuilder: NumberTypeOptionDataBuilder(), - ); - case FieldType.RichText: - return RichTextTypeOptionContext( - fieldContext: fieldContext, - dataBuilder: RichTextTypeOptionDataBuilder(), - ); - case FieldType.SingleSelect: - return SingleSelectTypeOptionContext( - fieldContext: fieldContext, - dataBuilder: SingleSelectTypeOptionDataBuilder(), - ); - - case FieldType.URL: - return URLTypeOptionContext( - fieldContext: fieldContext, - dataBuilder: URLTypeOptionDataBuilder(), - ); - } - - throw UnimplementedError(); -} - -abstract class TypeOptionWidget extends StatelessWidget { - const TypeOptionWidget({Key? key}) : super(key: key); -} - -typedef TypeOptionData = Uint8List; -typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData); -typedef ShowOverlayCallback = void Function( - BuildContext anchorContext, - Widget child, { - VoidCallback? onRemoved, -}); -typedef HideOverlayCallback = void Function(BuildContext anchorContext); - -class TypeOptionOverlayDelegate { - ShowOverlayCallback showOverlay; - HideOverlayCallback hideOverlay; - TypeOptionOverlayDelegate({ - required this.showOverlay, - required this.hideOverlay, - }); -} 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 new file mode 100644 index 0000000000..bca9b8e2f7 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart @@ -0,0 +1,126 @@ +import 'dart:typed_data'; +import 'package:dartz/dartz.dart' show Either; +import 'package:flowy_infra/image.dart'; +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/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.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_type_list.dart'; +import 'field_type_extension.dart'; +import 'type_option/builder.dart'; + +typedef UpdateFieldCallback = void Function(Field, Uint8List); +typedef SwitchToFieldCallback = Future> Function( + String fieldId, + FieldType fieldType, +); + +class FieldTypeOptionEditor extends StatefulWidget { + final GridFieldContext fieldContext; + + const FieldTypeOptionEditor({ + required this.fieldContext, + Key? key, + }) : super(key: key); + + @override + State createState() => _FieldTypeOptionEditorState(); +} + +class _FieldTypeOptionEditorState extends State { + String? currentOverlayIdentifier; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => FieldTypeOptionEditBloc(widget.fieldContext)..add(const FieldTypeOptionEditEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + List children = [_switchFieldTypeButton(context, widget.fieldContext.field)]; + final typeOptionWidget = _typeOptionWidget(context: context, state: state); + + if (typeOptionWidget != null) { + children.add(typeOptionWidget); + } + + return ListView( + shrinkWrap: true, + children: children, + ); + }, + ), + ); + } + + Widget _switchFieldTypeButton(BuildContext context, Field field) { + final theme = context.watch(); + return SizedBox( + height: GridSize.typeOptionItemHeight, + child: FlowyButton( + text: FlowyText.medium(field.fieldType.title(), fontSize: 12), + margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + hoverColor: theme.hover, + onTap: () { + final list = FieldTypeList(onSelectField: (newFieldType) { + widget.fieldContext.switchToField(newFieldType); + }); + _showOverlay(context, list); + }, + leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), + rightIcon: svgWidget("grid/more", color: theme.iconColor), + ), + ); + } + + Widget? _typeOptionWidget({ + required BuildContext context, + required FieldTypeOptionEditState state, + }) { + final overlayDelegate = TypeOptionOverlayDelegate( + showOverlay: _showOverlay, + hideOverlay: _hideOverlay, + ); + + return makeTypeOptionWidget( + context: context, + fieldContext: widget.fieldContext, + overlayDelegate: overlayDelegate, + ); + } + + void _showOverlay(BuildContext context, Widget child, {VoidCallback? onRemoved}) { + final identifier = child.toString(); + if (currentOverlayIdentifier != null) { + FlowyOverlay.of(context).remove(currentOverlayIdentifier!); + } + + currentOverlayIdentifier = identifier; + FlowyOverlay.of(context).insertWithAnchor( + widget: OverlayContainer( + child: child, + constraints: BoxConstraints.loose(const Size(460, 440)), + ), + identifier: identifier, + anchorContext: context, + anchorDirection: AnchorDirection.leftWithCenterAligned, + style: FlowyOverlayStyle(blur: false), + anchorOffset: const Offset(-20, 0), + ); + } + + void _hideOverlay(BuildContext context) { + if (currentOverlayIdentifier != null) { + FlowyOverlay.of(context).remove(currentOverlayIdentifier!); + } + } +} + +abstract class TypeOptionWidget extends StatelessWidget { + const TypeOptionWidget({Key? key}) : super(key: key); +} 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 new file mode 100644 index 0000000000..872a501f90 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart @@ -0,0 +1,108 @@ +import 'dart:typed_data'; + +import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_type_option.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; +import 'package:flutter/material.dart'; +import 'date.dart'; +import 'multi_select.dart'; +import 'number.dart'; +import 'rich_text.dart'; +import 'single_select.dart'; +import 'url.dart'; + +typedef TypeOptionData = Uint8List; +typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData); +typedef ShowOverlayCallback = void Function( + BuildContext anchorContext, + Widget child, { + VoidCallback? onRemoved, +}); +typedef HideOverlayCallback = void Function(BuildContext anchorContext); + +class TypeOptionOverlayDelegate { + ShowOverlayCallback showOverlay; + HideOverlayCallback hideOverlay; + TypeOptionOverlayDelegate({ + required this.showOverlay, + required this.hideOverlay, + }); +} + +abstract class TypeOptionWidgetBuilder { + Widget? build(BuildContext context); +} + +Widget? makeTypeOptionWidget({ + required BuildContext context, + required GridFieldContext fieldContext, + required TypeOptionOverlayDelegate overlayDelegate, +}) { + final builder = makeTypeOptionWidgetBuilder(fieldContext, overlayDelegate); + return builder.build(context); +} + +TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( + GridFieldContext fieldContext, + TypeOptionOverlayDelegate overlayDelegate, +) { + switch (fieldContext.field.fieldType) { + case FieldType.Checkbox: + final context = CheckboxTypeOptionContext( + fieldContext: fieldContext, + dataBuilder: CheckboxTypeOptionWidgetDataParser(), + ); + return CheckboxTypeOptionWidgetBuilder(context); + case FieldType.DateTime: + final context = DateTypeOptionContext( + fieldContext: fieldContext, + dataBuilder: DateTypeOptionDataParser(), + ); + return DateTypeOptionWidgetBuilder( + context, + overlayDelegate, + ); + case FieldType.SingleSelect: + final context = SingleSelectTypeOptionContext( + fieldContext: fieldContext, + dataBuilder: SingleSelectTypeOptionWidgetDataParser(), + ); + return SingleSelectTypeOptionWidgetBuilder( + context, + overlayDelegate, + ); + case FieldType.MultiSelect: + final context = MultiSelectTypeOptionContext( + fieldContext: fieldContext, + dataBuilder: MultiSelectTypeOptionWidgetDataParser(), + ); + return MultiSelectTypeOptionWidgetBuilder( + context, + overlayDelegate, + ); + case FieldType.Number: + final context = NumberTypeOptionContext( + fieldContext: fieldContext, + dataBuilder: NumberTypeOptionWidgetDataParser(), + ); + return NumberTypeOptionWidgetBuilder( + context, + overlayDelegate, + ); + case FieldType.RichText: + final context = RichTextTypeOptionContext( + fieldContext: fieldContext, + dataBuilder: RichTextTypeOptionWidgetDataParser(), + ); + return RichTextTypeOptionWidgetBuilder(context); + + case FieldType.URL: + final context = URLTypeOptionContext( + fieldContext: fieldContext, + dataBuilder: URLTypeOptionWidgetDataParser(), + ); + return URLTypeOptionWidgetBuilder(context); + } + throw UnimplementedError; +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart index c1e202f358..79622a6731 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart @@ -1,20 +1,20 @@ 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_editor_pannel.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart'; import 'package:flutter/material.dart'; +import 'builder.dart'; -typedef CheckboxTypeOptionContext = TypeOptionContext; +typedef CheckboxTypeOptionContext = TypeOptionWidgetContext; -class CheckboxTypeOptionDataBuilder extends TypeOptionDataBuilder { +class CheckboxTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { @override CheckboxTypeOption fromBuffer(List buffer) { return CheckboxTypeOption.fromBuffer(buffer); } } -class CheckboxTypeOptionBuilder extends TypeOptionBuilder { - CheckboxTypeOptionBuilder(CheckboxTypeOptionContext typeOptionContext); +class CheckboxTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder { + CheckboxTypeOptionWidgetBuilder(CheckboxTypeOptionContext typeOptionContext); @override - Widget? get customWidget => null; + Widget? build(BuildContext context) => null; } 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 f4031dc9ce..f15b73f75c 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,6 +1,6 @@ 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_editor_pannel.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.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'; @@ -12,11 +12,12 @@ import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'builder.dart'; -class DateTypeOptionBuilder extends TypeOptionBuilder { +class DateTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder { final DateTypeOptionWidget _widget; - DateTypeOptionBuilder( + DateTypeOptionWidgetBuilder( DateTypeOptionContext typeOptionContext, TypeOptionOverlayDelegate overlayDelegate, ) : _widget = DateTypeOptionWidget( @@ -25,7 +26,9 @@ class DateTypeOptionBuilder extends TypeOptionBuilder { ); @override - Widget? get customWidget => _widget; + Widget? build(BuildContext context) { + return _widget; + } } class DateTypeOptionWidget extends TypeOptionWidget { 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 fc310410f9..8c7ab40a6f 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,13 +1,14 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_type_option.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart'; import 'package:flutter/material.dart'; +import 'builder.dart'; import 'select_option.dart'; -class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { +class MultiSelectTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder { final MultiSelectTypeOptionWidget _widget; - MultiSelectTypeOptionBuilder( + MultiSelectTypeOptionWidgetBuilder( MultiSelectTypeOptionContext typeOptionContext, TypeOptionOverlayDelegate overlayDelegate, ) : _widget = MultiSelectTypeOptionWidget( @@ -16,7 +17,7 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { ); @override - Widget? get customWidget => _widget; + Widget? build(BuildContext context) => _widget; } class MultiSelectTypeOptionWidget extends TypeOptionWidget { 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 bca17e1cd8..e15abb1728 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 @@ -2,7 +2,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_editor_pannel.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -15,10 +15,12 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart' hide NumberFormat; import 'package:app_flowy/generated/locale_keys.g.dart'; -class NumberTypeOptionBuilder extends TypeOptionBuilder { +import 'builder.dart'; + +class NumberTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder { final NumberTypeOptionWidget _widget; - NumberTypeOptionBuilder( + NumberTypeOptionWidgetBuilder( NumberTypeOptionContext typeOptionContext, TypeOptionOverlayDelegate overlayDelegate, ) : _widget = NumberTypeOptionWidget( @@ -27,7 +29,7 @@ class NumberTypeOptionBuilder extends TypeOptionBuilder { ); @override - Widget? get customWidget => _widget; + Widget? build(BuildContext context) => _widget; } class NumberTypeOptionWidget extends TypeOptionWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/rich_text.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/rich_text.dart index 03f9ed347c..f79fb2dd9d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/rich_text.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/rich_text.dart @@ -1,21 +1,20 @@ 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_editor_pannel.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; - import 'package:flutter/material.dart'; +import 'builder.dart'; -typedef RichTextTypeOptionContext = TypeOptionContext; +typedef RichTextTypeOptionContext = TypeOptionWidgetContext; -class RichTextTypeOptionDataBuilder extends TypeOptionDataBuilder { +class RichTextTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { @override RichTextTypeOption fromBuffer(List buffer) { return RichTextTypeOption.fromBuffer(buffer); } } -class RichTextTypeOptionBuilder extends TypeOptionBuilder { - RichTextTypeOptionBuilder(RichTextTypeOptionContext typeOptionContext); +class RichTextTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder { + RichTextTypeOptionWidgetBuilder(RichTextTypeOptionContext typeOptionContext); @override - Widget? get customWidget => null; + Widget? build(BuildContext context) => null; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/select_option.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/select_option.dart index 60c1bfcdd6..fea3e5df43 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/select_option.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/select_option.dart @@ -2,7 +2,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/select_op import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.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_editor_pannel.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; @@ -14,6 +13,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'builder.dart'; import 'select_option_editor.dart'; class SelectOptionTypeOptionWidget extends StatelessWidget { 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 fedddec11d..a1ed4e857a 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,12 +1,13 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_type_option.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_option_editor.dart'; import 'package:flutter/material.dart'; +import 'builder.dart'; import 'select_option.dart'; -class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { +class SingleSelectTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder { final SingleSelectTypeOptionWidget _widget; - SingleSelectTypeOptionBuilder( + SingleSelectTypeOptionWidgetBuilder( SingleSelectTypeOptionContext typeOptionContext, TypeOptionOverlayDelegate overlayDelegate, ) : _widget = SingleSelectTypeOptionWidget( @@ -15,7 +16,7 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { ); @override - Widget? get customWidget => _widget; + Widget? build(BuildContext context) => _widget; } class SingleSelectTypeOptionWidget extends TypeOptionWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/url.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/url.dart index f4e73f7fdc..a55711bd05 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/url.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/url.dart @@ -1,20 +1,20 @@ 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_editor_pannel.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart'; import 'package:flutter/material.dart'; +import 'builder.dart'; -typedef URLTypeOptionContext = TypeOptionContext; +typedef URLTypeOptionContext = TypeOptionWidgetContext; -class URLTypeOptionDataBuilder extends TypeOptionDataBuilder { +class URLTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { @override URLTypeOption fromBuffer(List buffer) { return URLTypeOption.fromBuffer(buffer); } } -class URLTypeOptionBuilder extends TypeOptionBuilder { - URLTypeOptionBuilder(URLTypeOptionContext typeOptionContext); +class URLTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder { + URLTypeOptionWidgetBuilder(URLTypeOptionContext typeOptionContext); @override - Widget? get customWidget => null; + Widget? build(BuildContext context) => null; }