Browse Source

feat: use popover in property field

Vincent Chan 2 years ago
parent
commit
d79a7cb194

+ 2 - 6
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart

@@ -3,7 +3,6 @@ import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'package:appflowy_popover/popover.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
-import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/hover.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
@@ -44,11 +43,8 @@ class _GridFieldCellState extends State<GridFieldCell> {
             followerAnchor: Alignment.topLeft,
             offset: const Offset(0, 10),
             popupBuilder: (BuildContext context) {
-              return OverlayContainer(
-                constraints: BoxConstraints.loose(const Size(240, 200)),
-                child: GridFieldCellActionSheet(
-                  cellContext: widget.cellContext,
-                ),
+              return GridFieldCellActionSheet(
+                cellContext: widget.cellContext,
               );
             },
           );

+ 51 - 58
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell_action_sheet.dart

@@ -11,92 +11,85 @@ import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:easy_localization/easy_localization.dart';
-import 'package:appflowy_popover/popover.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 
 import '../../layout/sizes.dart';
 
-class GridFieldCellActionSheet extends StatelessWidget
-    with FlowyOverlayDelegate {
+class GridFieldCellActionSheet extends StatefulWidget {
   final GridFieldCellContext cellContext;
   const GridFieldCellActionSheet({required this.cellContext, Key? key})
       : super(key: key);
 
+  @override
+  State<StatefulWidget> createState() => _GridFieldCellActionSheetState();
+}
+
+class _GridFieldCellActionSheetState extends State<GridFieldCellActionSheet> {
+  bool _showFieldEditor = false;
+
   @override
   Widget build(BuildContext context) {
+    if (_showFieldEditor) {
+      final field = widget.cellContext.field;
+      return OverlayContainer(
+        constraints: BoxConstraints.loose(const Size(240, 200)),
+        child: FieldEditor(
+          gridId: widget.cellContext.gridId,
+          fieldName: field.name,
+          typeOptionLoader: FieldTypeOptionLoader(
+            gridId: widget.cellContext.gridId,
+            field: field,
+          ),
+        ),
+      );
+    }
     return BlocProvider(
-      create: (context) => getIt<FieldActionSheetBloc>(param1: cellContext),
-      child: SingleChildScrollView(
-        child: Column(
-          children: [
-            _EditFieldButton(
-              cellContext: cellContext,
-            ),
-            const VSpace(6),
-            _FieldOperationList(cellContext,
-                () => FlowyOverlay.of(context).remove(identifier())),
-          ],
+      create: (context) =>
+          getIt<FieldActionSheetBloc>(param1: widget.cellContext),
+      child: OverlayContainer(
+        constraints: BoxConstraints.loose(const Size(240, 200)),
+        child: SingleChildScrollView(
+          child: Column(
+            children: [
+              _EditFieldButton(
+                cellContext: widget.cellContext,
+                onTap: () {
+                  setState(() {
+                    _showFieldEditor = true;
+                  });
+                },
+              ),
+              const VSpace(6),
+              _FieldOperationList(widget.cellContext, () {}),
+            ],
+          ),
         ),
       ),
     );
   }
-
-  static String identifier() {
-    return (GridFieldCellActionSheet).toString();
-  }
-
-  @override
-  bool asBarrier() {
-    return true;
-  }
 }
 
-class _EditFieldButton extends StatefulWidget {
+class _EditFieldButton extends StatelessWidget {
   final GridFieldCellContext cellContext;
-  const _EditFieldButton({required this.cellContext, Key? key})
+  final void Function()? onTap;
+  const _EditFieldButton({required this.cellContext, Key? key, this.onTap})
       : super(key: key);
 
-  @override
-  State<StatefulWidget> createState() => _EditFieldButtonState();
-}
-
-class _EditFieldButtonState extends State<_EditFieldButton> {
-  final popover = PopoverController();
-
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
+
     return BlocBuilder<FieldActionSheetBloc, FieldActionSheetState>(
       builder: (context, state) {
         return SizedBox(
           height: GridSize.typeOptionItemHeight,
-          child: Popover(
-            controller: popover,
-            targetAnchor: Alignment.topRight,
-            followerAnchor: Alignment.topLeft,
-            offset: const Offset(20, 0),
-            popupBuilder: (context) {
-              final field = widget.cellContext.field;
-              return OverlayContainer(
-                constraints: BoxConstraints.loose(const Size(240, 200)),
-                child: FieldEditor(
-                  gridId: widget.cellContext.gridId,
-                  fieldName: field.name,
-                  typeOptionLoader: FieldTypeOptionLoader(
-                    gridId: widget.cellContext.gridId,
-                    field: field,
-                  ),
-                ),
-              );
-            },
-            child: FlowyButton(
-              text: FlowyText.medium(
-                LocaleKeys.grid_field_editProperty.tr(),
-                fontSize: 12,
-              ),
-              hoverColor: theme.hover,
-              onTap: () => popover.show(),
+          child: FlowyButton(
+            text: FlowyText.medium(
+              LocaleKeys.grid_field_editProperty.tr(),
+              fontSize: 12,
             ),
+            hoverColor: theme.hover,
+            onTap: onTap,
           ),
         );
       },

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart

@@ -70,7 +70,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
       targetAnchor: Alignment.topRight,
       followerAnchor: Alignment.topLeft,
       offset: const Offset(20, 0),
-      popupBuilder: (context) {
+      popupBuilder: (popoverContext) {
         return OverlayContainer(
           constraints: BoxConstraints.loose(const Size(460, 440)),
           child: DateFormatList(

+ 24 - 36
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart

@@ -1,7 +1,9 @@
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
+import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_editor.dart';
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/plugins/grid/application/setting/property_bloc.dart';
 import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_type_extension.dart';
+import 'package:appflowy_popover/popover.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@@ -16,9 +18,8 @@ import 'package:styled_widget/styled_widget.dart';
 
 import '../../../application/field/field_cache.dart';
 import '../../layout/sizes.dart';
-import '../header/field_editor.dart';
 
-class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
+class GridPropertyList extends StatelessWidget {
   final String gridId;
   final GridFieldCache fieldCache;
   const GridPropertyList({
@@ -27,20 +28,6 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
     Key? key,
   }) : super(key: key);
 
-  void show(BuildContext context) {
-    FlowyOverlay.of(context).insertWithAnchor(
-      widget: OverlayContainer(
-        child: this,
-        constraints: BoxConstraints.loose(const Size(260, 400)),
-      ),
-      identifier: identifier(),
-      anchorContext: context,
-      anchorDirection: AnchorDirection.bottomRight,
-      style: FlowyOverlayStyle(blur: false),
-      delegate: this,
-    );
-  }
-
   @override
   Widget build(BuildContext context) {
     return BlocProvider(
@@ -68,13 +55,6 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
       ),
     );
   }
-
-  String identifier() {
-    return (GridPropertyList).toString();
-  }
-
-  @override
-  bool asBarrier() => true;
 }
 
 class _GridPropertyCell extends StatelessWidget {
@@ -113,19 +93,27 @@ class _GridPropertyCell extends StatelessWidget {
     );
   }
 
-  FlowyButton _editFieldButton(AppTheme theme, BuildContext context) {
-    return FlowyButton(
-      text: FlowyText.medium(field.name, fontSize: 12),
-      hoverColor: theme.hover,
-      leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
-      onTap: () {
-        // FieldEditorPopOver.show(
-        //   context,
-        //   anchorContext: context,
-        //   gridId: gridId,
-        //   fieldName: field.name,
-        //   typeOptionLoader: FieldTypeOptionLoader(gridId: gridId, field: field),
-        // );
+  Widget _editFieldButton(AppTheme theme, BuildContext context) {
+    return Popover(
+      triggerActions: PopoverTriggerActionFlags.click,
+      targetAnchor: Alignment.topRight,
+      followerAnchor: Alignment.topLeft,
+      offset: const Offset(20, 0),
+      child: FlowyButton(
+        text: FlowyText.medium(field.name, fontSize: 12),
+        hoverColor: theme.hover,
+        leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
+      ),
+      popupBuilder: (BuildContext context) {
+        return OverlayContainer(
+          constraints: BoxConstraints.loose(const Size(240, 200)),
+          child: FieldEditor(
+            gridId: gridId,
+            fieldName: field.name,
+            typeOptionLoader:
+                FieldTypeOptionLoader(gridId: gridId, field: field),
+          ),
+        );
       },
     );
   }

+ 1 - 31
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_setting.dart

@@ -1,4 +1,5 @@
 import 'package:app_flowy/plugins/grid/application/setting/setting_bloc.dart';
+import 'package:appflowy_popover/popover.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
@@ -32,37 +33,6 @@ class GridSettingList extends StatelessWidget {
       {required this.settingContext, required this.onAction, Key? key})
       : super(key: key);
 
-  static void show(BuildContext context, GridSettingContext settingContext) {
-    final list = GridSettingList(
-      settingContext: settingContext,
-      onAction: (action, settingContext) {
-        switch (action) {
-          case GridSettingAction.filter:
-            break;
-          case GridSettingAction.sortBy:
-            break;
-          case GridSettingAction.properties:
-            GridPropertyList(
-                    gridId: settingContext.gridId,
-                    fieldCache: settingContext.fieldCache)
-                .show(context);
-            break;
-        }
-      },
-    );
-
-    FlowyOverlay.of(context).insertWithAnchor(
-      widget: OverlayContainer(
-        child: list,
-        constraints: BoxConstraints.loose(const Size(140, 400)),
-      ),
-      identifier: list.identifier(),
-      anchorContext: context,
-      anchorDirection: AnchorDirection.bottomRight,
-      style: FlowyOverlayStyle(blur: false),
-    );
-  }
-
   @override
   Widget build(BuildContext context) {
     return BlocProvider(

+ 40 - 23
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart

@@ -65,30 +65,47 @@ class _SettingButton extends StatelessWidget {
             .padding(horizontal: 3, vertical: 3),
       ),
       popupBuilder: (BuildContext context) {
-        return OverlayContainer(
-          constraints: BoxConstraints.loose(const Size(140, 400)),
-          child: GridSettingList(
-            settingContext: settingContext,
-            onAction: (action, settingContext) {
-              switch (action) {
-                case GridSettingAction.filter:
-                  break;
-                case GridSettingAction.sortBy:
-                  break;
-                case GridSettingAction.properties:
-                  GridPropertyList(
-                          gridId: settingContext.gridId,
-                          fieldCache: settingContext.fieldCache)
-                      .show(context);
-                  break;
-              }
-            },
-          ),
-        );
+        return _GridSettingListPopover(settingContext: settingContext);
       },
     );
-    // return FlowyIconButton(
-    //   onPressed: () => GridSettingList.show(context, settingContext),
-    // );
+  }
+}
+
+class _GridSettingListPopover extends StatefulWidget {
+  final GridSettingContext settingContext;
+
+  const _GridSettingListPopover({Key? key, required this.settingContext})
+      : super(key: key);
+
+  @override
+  State<StatefulWidget> createState() => _GridSettingListPopoverState();
+}
+
+class _GridSettingListPopoverState extends State<_GridSettingListPopover> {
+  GridSettingAction? _action;
+
+  @override
+  Widget build(BuildContext context) {
+    if (_action == GridSettingAction.properties) {
+      return OverlayContainer(
+        constraints: BoxConstraints.loose(const Size(260, 400)),
+        child: GridPropertyList(
+          gridId: widget.settingContext.gridId,
+          fieldCache: widget.settingContext.fieldCache,
+        ),
+      );
+    }
+
+    return OverlayContainer(
+      constraints: BoxConstraints.loose(const Size(140, 400)),
+      child: GridSettingList(
+        settingContext: widget.settingContext,
+        onAction: (action, settingContext) {
+          setState(() {
+            _action = action;
+          });
+        },
+      ),
+    );
   }
 }