mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-11-10 10:18:57 +03:00
chore: rename classes
This commit is contained in:
parent
8ac75af875
commit
4825d83d2f
@ -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<FieldEditorPannelEvent, FieldEditorPannelState> {
|
||||
class FieldTypeOptionEditBloc extends Bloc<FieldTypeOptionEditEvent, FieldTypeOptionEditState> {
|
||||
final GridFieldContext _fieldContext;
|
||||
void Function()? _fieldListenFn;
|
||||
|
||||
FieldEditorPannelBloc(GridFieldContext fieldContext)
|
||||
FieldTypeOptionEditBloc(GridFieldContext fieldContext)
|
||||
: _fieldContext = fieldContext,
|
||||
super(FieldEditorPannelState.initial(fieldContext)) {
|
||||
on<FieldEditorPannelEvent>(
|
||||
super(FieldTypeOptionEditState.initial(fieldContext)) {
|
||||
on<FieldTypeOptionEditEvent>(
|
||||
(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<FieldEditorPannelEvent, FieldEditorPann
|
||||
}
|
||||
|
||||
@freezed
|
||||
class FieldEditorPannelEvent with _$FieldEditorPannelEvent {
|
||||
const factory FieldEditorPannelEvent.initial() = _Initial;
|
||||
const factory FieldEditorPannelEvent.didReceiveFieldUpdated(Field field) = _DidReceiveFieldUpdated;
|
||||
class FieldTypeOptionEditEvent with _$FieldTypeOptionEditEvent {
|
||||
const factory FieldTypeOptionEditEvent.initial() = _Initial;
|
||||
const factory FieldTypeOptionEditEvent.didReceiveFieldUpdated(Field field) = _DidReceiveFieldUpdated;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class FieldEditorPannelState with _$FieldEditorPannelState {
|
||||
const factory FieldEditorPannelState({
|
||||
class FieldTypeOptionEditState with _$FieldTypeOptionEditState {
|
||||
const factory FieldTypeOptionEditState({
|
||||
required Field field,
|
||||
}) = _FieldEditorPannelState;
|
||||
}) = _FieldTypeOptionEditState;
|
||||
|
||||
factory FieldEditorPannelState.initial(GridFieldContext fieldContext) => FieldEditorPannelState(
|
||||
factory FieldTypeOptionEditState.initial(GridFieldContext fieldContext) => FieldTypeOptionEditState(
|
||||
field: fieldContext.field,
|
||||
);
|
||||
}
|
@ -6,9 +6,9 @@ import 'dart:async';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
part 'date_bloc.freezed.dart';
|
||||
|
||||
typedef DateTypeOptionContext = TypeOptionContext<DateTypeOption>;
|
||||
typedef DateTypeOptionContext = TypeOptionWidgetContext<DateTypeOption>;
|
||||
|
||||
class DateTypeOptionDataBuilder extends TypeOptionDataBuilder<DateTypeOption> {
|
||||
class DateTypeOptionDataParser extends TypeOptionWidgetDataParser<DateTypeOption> {
|
||||
@override
|
||||
DateTypeOption fromBuffer(List<int> buffer) {
|
||||
return DateTypeOption.fromBuffer(buffer);
|
||||
|
@ -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<MultiSelectTypeOption> with SelectOptionTypeOptionAction {
|
||||
class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTypeOption>
|
||||
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<MultiSelectTypeOpti
|
||||
}
|
||||
}
|
||||
|
||||
class MultiSelectTypeOptionDataBuilder extends TypeOptionDataBuilder<MultiSelectTypeOption> {
|
||||
class MultiSelectTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser<MultiSelectTypeOption> {
|
||||
@override
|
||||
MultiSelectTypeOption fromBuffer(List<int> buffer) {
|
||||
return MultiSelectTypeOption.fromBuffer(buffer);
|
||||
|
@ -8,9 +8,9 @@ import 'package:protobuf/protobuf.dart';
|
||||
|
||||
part 'number_bloc.freezed.dart';
|
||||
|
||||
typedef NumberTypeOptionContext = TypeOptionContext<NumberTypeOption>;
|
||||
typedef NumberTypeOptionContext = TypeOptionWidgetContext<NumberTypeOption>;
|
||||
|
||||
class NumberTypeOptionDataBuilder extends TypeOptionDataBuilder<NumberTypeOption> {
|
||||
class NumberTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser<NumberTypeOption> {
|
||||
@override
|
||||
NumberTypeOption fromBuffer(List<int> buffer) {
|
||||
return NumberTypeOption.fromBuffer(buffer);
|
||||
|
@ -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<SingleSelectTypeOption>
|
||||
class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelectTypeOption>
|
||||
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<SingleSelectTypeOp
|
||||
}
|
||||
}
|
||||
|
||||
class SingleSelectTypeOptionDataBuilder extends TypeOptionDataBuilder<SingleSelectTypeOption> {
|
||||
class SingleSelectTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser<SingleSelectTypeOption> {
|
||||
@override
|
||||
SingleSelectTypeOption fromBuffer(List<int> buffer) {
|
||||
return SingleSelectTypeOption.fromBuffer(buffer);
|
||||
|
@ -33,16 +33,16 @@ class TypeOptionService {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TypeOptionDataBuilder<T> {
|
||||
abstract class TypeOptionWidgetDataParser<T> {
|
||||
T fromBuffer(List<int> buffer);
|
||||
}
|
||||
|
||||
class TypeOptionContext<T extends GeneratedMessage> {
|
||||
class TypeOptionWidgetContext<T extends GeneratedMessage> {
|
||||
T? _typeOptionObject;
|
||||
final GridFieldContext _fieldContext;
|
||||
final TypeOptionDataBuilder<T> dataBuilder;
|
||||
final TypeOptionWidgetDataParser<T> dataBuilder;
|
||||
|
||||
TypeOptionContext({
|
||||
TypeOptionWidgetContext({
|
||||
required this.dataBuilder,
|
||||
required GridFieldContext fieldContext,
|
||||
}) : _fieldContext = fieldContext;
|
||||
@ -77,7 +77,7 @@ class TypeOptionContext2<T> {
|
||||
final Field field;
|
||||
final FieldService _fieldService;
|
||||
T? _data;
|
||||
final TypeOptionDataBuilder dataBuilder;
|
||||
final TypeOptionWidgetDataParser dataBuilder;
|
||||
|
||||
TypeOptionContext2({
|
||||
required this.gridId,
|
||||
|
@ -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';
|
||||
|
@ -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) {
|
||||
|
@ -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<Either<FieldTypeOptionData, FlowyError>> Function(
|
||||
String fieldId,
|
||||
FieldType fieldType,
|
||||
);
|
||||
|
||||
class FieldEditorPannel extends StatefulWidget {
|
||||
final GridFieldContext fieldContext;
|
||||
|
||||
const FieldEditorPannel({
|
||||
required this.fieldContext,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<FieldEditorPannel> createState() => _FieldEditorPannelState();
|
||||
}
|
||||
|
||||
class _FieldEditorPannelState extends State<FieldEditorPannel> {
|
||||
String? currentOverlayIdentifier;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => FieldEditorPannelBloc(widget.fieldContext)..add(const FieldEditorPannelEvent.initial()),
|
||||
child: BlocBuilder<FieldEditorPannelBloc, FieldEditorPannelState>(
|
||||
builder: (context, state) {
|
||||
List<Widget> 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<AppTheme>();
|
||||
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,
|
||||
});
|
||||
}
|
@ -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<Either<FieldTypeOptionData, FlowyError>> Function(
|
||||
String fieldId,
|
||||
FieldType fieldType,
|
||||
);
|
||||
|
||||
class FieldTypeOptionEditor extends StatefulWidget {
|
||||
final GridFieldContext fieldContext;
|
||||
|
||||
const FieldTypeOptionEditor({
|
||||
required this.fieldContext,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<FieldTypeOptionEditor> createState() => _FieldTypeOptionEditorState();
|
||||
}
|
||||
|
||||
class _FieldTypeOptionEditorState extends State<FieldTypeOptionEditor> {
|
||||
String? currentOverlayIdentifier;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => FieldTypeOptionEditBloc(widget.fieldContext)..add(const FieldTypeOptionEditEvent.initial()),
|
||||
child: BlocBuilder<FieldTypeOptionEditBloc, FieldTypeOptionEditState>(
|
||||
builder: (context, state) {
|
||||
List<Widget> 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<AppTheme>();
|
||||
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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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<CheckboxTypeOption>;
|
||||
typedef CheckboxTypeOptionContext = TypeOptionWidgetContext<CheckboxTypeOption>;
|
||||
|
||||
class CheckboxTypeOptionDataBuilder extends TypeOptionDataBuilder<CheckboxTypeOption> {
|
||||
class CheckboxTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser<CheckboxTypeOption> {
|
||||
@override
|
||||
CheckboxTypeOption fromBuffer(List<int> 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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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<RichTextTypeOption>;
|
||||
typedef RichTextTypeOptionContext = TypeOptionWidgetContext<RichTextTypeOption>;
|
||||
|
||||
class RichTextTypeOptionDataBuilder extends TypeOptionDataBuilder<RichTextTypeOption> {
|
||||
class RichTextTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser<RichTextTypeOption> {
|
||||
@override
|
||||
RichTextTypeOption fromBuffer(List<int> 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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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<URLTypeOption>;
|
||||
typedef URLTypeOptionContext = TypeOptionWidgetContext<URLTypeOption>;
|
||||
|
||||
class URLTypeOptionDataBuilder extends TypeOptionDataBuilder<URLTypeOption> {
|
||||
class URLTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser<URLTypeOption> {
|
||||
@override
|
||||
URLTypeOption fromBuffer(List<int> 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user