Browse Source

chore: fix bugs

appflowy 2 years ago
parent
commit
1de3999e3a

+ 2 - 1
frontend/app_flowy/lib/plugins/doc/document.dart

@@ -186,7 +186,8 @@ class DocumentShareButton extends StatelessWidget {
                 'Exported to: ${LocaleKeys.notifications_export_path.tr()}');
             break;
           case ShareAction.copyLink:
-            FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr())
+            NavigatorAlertDialog(
+                    title: LocaleKeys.shareAction_workInProgress.tr())
                 .show(context);
             break;
         }

+ 1 - 1
frontend/app_flowy/lib/plugins/doc/presentation/toolbar/link_button.dart

@@ -84,7 +84,7 @@ class FlowyLinkStyleButtonState extends State<FlowyLinkStyleButton> {
       value = values.first;
     }
 
-    TextFieldDialog(
+    NavigatorTextFieldDialog(
       title: 'URL',
       value: value,
       confirm: (newValue) {

+ 9 - 0
frontend/app_flowy/lib/plugins/grid/application/row/row_detail_bloc.dart

@@ -1,4 +1,5 @@
 import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';
@@ -24,6 +25,13 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
           didReceiveCellDatas: (_DidReceiveCellDatas value) {
             emit(state.copyWith(gridCells: value.gridCells));
           },
+          deleteField: (_DeleteField value) {
+            final fieldService = FieldService(
+              gridId: dataController.rowInfo.gridId,
+              fieldId: value.fieldId,
+            );
+            fieldService.deleteField();
+          },
         );
       },
     );
@@ -49,6 +57,7 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
 @freezed
 class RowDetailEvent with _$RowDetailEvent {
   const factory RowDetailEvent.initial() = _Initial;
+  const factory RowDetailEvent.deleteField(String fieldId) = _DeleteField;
   const factory RowDetailEvent.didReceiveCellDatas(
       List<GridCellIdentifier> gridCells) = _DidReceiveCellDatas;
 }

+ 1 - 3
frontend/app_flowy/lib/plugins/grid/presentation/grid_page.dart

@@ -317,9 +317,7 @@ class _GridFooter extends StatelessWidget {
           height: GridSize.footerHeight,
           child: Padding(
             padding: GridSize.footerContentInsets,
-            child: const Expanded(
-              child: SizedBox(height: 40, child: GridAddRowButton()),
-            ),
+            child: const SizedBox(height: 40, child: GridAddRowButton()),
           ),
         ),
       ),

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

@@ -169,7 +169,7 @@ class FieldActionCell extends StatelessWidget {
         }
       },
       leftIcon: svgWidget(action.iconName(),
-        color: enable ? theme.iconColor : theme.disableIconColor),
+          color: enable ? theme.iconColor : theme.disableIconColor),
     );
   }
 }
@@ -216,7 +216,7 @@ extension _FieldActionExtension on FieldAction {
             .add(const FieldActionSheetEvent.duplicateField());
         break;
       case FieldAction.delete:
-        FlowyAlertDialog(
+        NavigatorAlertDialog(
           title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(),
           confirm: () {
             context

+ 44 - 33
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart

@@ -2,15 +2,13 @@ import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart'
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
 import 'package:appflowy_popover/popover.dart';
 import 'package:easy_localization/easy_localization.dart';
-import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart';
 import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
-import 'package:easy_localization/easy_localization.dart';
-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_infra_ui/widget/spacing.dart';
+import 'package:flowy_sdk/log.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
@@ -21,7 +19,7 @@ class FieldEditor extends StatefulWidget {
   final String gridId;
   final String fieldName;
   final bool isGroupField;
-  final VoidCallback? onRemoved;
+  final Function(String)? onDeleted;
 
   final IFieldTypeOptionLoader typeOptionLoader;
   const FieldEditor({
@@ -29,7 +27,7 @@ class FieldEditor extends StatefulWidget {
     this.fieldName = "",
     required this.typeOptionLoader,
     this.isGroupField = false,
-    this.onRemoved,
+    this.onDeleted,
     Key? key,
   }) : super(key: key);
 
@@ -56,7 +54,6 @@ class _FieldEditorState extends State<FieldEditor> {
         loader: widget.typeOptionLoader,
       )..add(const FieldEditorEvent.initial()),
       child: BlocBuilder<FieldEditorBloc, FieldEditorState>(
-        buildWhen: (p, c) => false,
         builder: (context, state) {
           return ListView(
             shrinkWrap: true,
@@ -66,7 +63,15 @@ class _FieldEditorState extends State<FieldEditor> {
               const VSpace(10),
               const _FieldNameCell(),
               const VSpace(10),
-              _DeleteFieldButton(popoverMutex: popoverMutex),
+              _DeleteFieldButton(
+                popoverMutex: popoverMutex,
+                onDeleted: () {
+                  state.field.fold(
+                    () => Log.error('Can not delete the field'),
+                    (field) => widget.onDeleted?.call(field.id),
+                  );
+                },
+              ),
               const VSpace(10),
               _FieldTypeOptionCell(popoverMutex: popoverMutex),
             ],
@@ -129,9 +134,11 @@ class _FieldNameCell extends StatelessWidget {
 
 class _DeleteFieldButton extends StatelessWidget {
   final PopoverMutex popoverMutex;
+  final VoidCallback? onDeleted;
 
   const _DeleteFieldButton({
     required this.popoverMutex,
+    required this.onDeleted,
     Key? key,
   }) : super(key: key);
 
@@ -139,38 +146,42 @@ class _DeleteFieldButton extends StatelessWidget {
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
     return BlocBuilder<FieldEditorBloc, FieldEditorState>(
+      buildWhen: (previous, current) => previous != current,
       builder: (context, state) {
         final enable = !state.canDelete && !state.isGroupField;
+        Widget button = FlowyButton(
+          text: FlowyText.medium(
+            LocaleKeys.grid_field_delete.tr(),
+            fontSize: 12,
+            color: enable ? null : theme.shader4,
+          ),
+        );
+        if (enable) button = _wrapPopover(button);
+        return button;
+      },
+    );
+  }
 
-        return Popover(
-          triggerActions: PopoverTriggerActionFlags.click,
-          mutex: popoverMutex,
-          direction: PopoverDirection.center,
-          popupBuilder: (context) {
-            return FlowyAlertDialog(
-              title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(),
-              cancel: () {
-                // FlowyOverlay.of(context).remove(FieldEditor.identifier())
-                // popoverMutex.state?.close();
-              },
-              confirm: () {
-                context
-                    .read<FieldEditorBloc>()
-                    .add(const FieldEditorEvent.deleteField());
-
-                // FlowyOverlay.of(context).remove(FieldEditor.identifier());
-              },
-            );
-          },
-          child: FlowyButton(
-            text: FlowyText.medium(
-              LocaleKeys.grid_field_delete.tr(),
-              fontSize: 12,
-              color: enable ? null : theme.shader4,
-            ),
+  Widget _wrapPopover(Widget widget) {
+    return Popover(
+      triggerActions: PopoverTriggerActionFlags.click,
+      mutex: popoverMutex,
+      direction: PopoverDirection.center,
+      popupBuilder: (popupContext) {
+        return OverlayContainer(
+          constraints: BoxConstraints.loose(const Size(400, 240)),
+          child: PopoverAlertView(
+            title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(),
+            cancel: () => popoverMutex.state?.close(),
+            confirm: () {
+              onDeleted?.call();
+              popoverMutex.state?.close();
+            },
+            popoverMutex: popoverMutex,
           ),
         );
       },
+      child: widget,
     );
   }
 }

+ 1 - 2
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart

@@ -65,8 +65,7 @@ class FieldTypeOptionEditor extends StatelessWidget {
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
       child: Popover(
-        triggerActions:
-            PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
+        triggerActions: PopoverTriggerActionFlags.click,
         mutex: popoverMutex,
         offset: const Offset(20, 0),
         popupBuilder: (context) {

+ 4 - 3
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/builder.dart

@@ -54,9 +54,10 @@ Widget? makeTypeOptionWidget({
   return builder.build(context);
 }
 
-TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder(
-    {required TypeOptionDataController dataController,
-    required PopoverMutex popoverMutex}) {
+TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder({
+  required TypeOptionDataController dataController,
+  required PopoverMutex popoverMutex,
+}) {
   final gridId = dataController.gridId;
   final fieldType = dataController.field.fieldType;
 

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart

@@ -151,7 +151,7 @@ extension _RowActionExtension on _RowAction {
             .add(const RowActionSheetEvent.duplicateRow());
         break;
       case _RowAction.delete:
-        FlowyAlertDialog(
+        NavigatorAlertDialog(
           title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(),
           confirm: () {
             context

+ 21 - 6
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart

@@ -145,12 +145,18 @@ class _PropertyList extends StatelessWidget {
                   );
                 });
               },
-              onOpened: () {
+              onOpened: (controller) {
                 return OverlayContainer(
                   constraints: BoxConstraints.loose(const Size(240, 200)),
                   child: FieldEditor(
                     gridId: viewId,
                     typeOptionLoader: NewFieldTypeOptionLoader(gridId: viewId),
+                    onDeleted: (fieldId) {
+                      controller.close();
+                      context
+                          .read<RowDetailBloc>()
+                          .add(RowDetailEvent.deleteField(fieldId));
+                    },
                   ),
                 );
               },
@@ -164,9 +170,11 @@ class _PropertyList extends StatelessWidget {
 
 class _CreateFieldButton extends StatelessWidget {
   final String viewId;
-  final Widget Function() onOpened;
+  final Widget Function(PopoverController) onOpened;
   final VoidCallback onClosed;
-  const _CreateFieldButton({
+  final PopoverController popoverController = PopoverController();
+
+  _CreateFieldButton({
     required this.viewId,
     required this.onOpened,
     required this.onClosed,
@@ -178,8 +186,9 @@ class _CreateFieldButton extends StatelessWidget {
     final theme = context.read<AppTheme>();
 
     return Popover(
+      controller: popoverController,
       triggerActions: PopoverTriggerActionFlags.click,
-      direction: PopoverDirection.bottomWithLeftAligned,
+      direction: PopoverDirection.topWithLeftAligned,
       onClose: onClosed,
       child: Container(
         height: 40,
@@ -194,7 +203,7 @@ class _CreateFieldButton extends StatelessWidget {
           leftIcon: svgWidget("home/add"),
         ),
       ),
-      popupBuilder: (BuildContext context) => onOpened(),
+      popupBuilder: (BuildContext context) => onOpened(popoverController),
     );
   }
 
@@ -252,7 +261,7 @@ class _RowDetailCellState extends State<_RowDetailCell> {
               child: Popover(
                 controller: popover,
                 offset: const Offset(20, 0),
-                popupBuilder: (context) {
+                popupBuilder: (popoverContext) {
                   return OverlayContainer(
                     constraints: BoxConstraints.loose(const Size(240, 200)),
                     child: FieldEditor(
@@ -263,6 +272,12 @@ class _RowDetailCellState extends State<_RowDetailCell> {
                         gridId: widget.cellId.gridId,
                         field: widget.cellId.fieldContext.field,
                       ),
+                      onDeleted: (fieldId) {
+                        popover.close();
+                        context
+                            .read<RowDetailBloc>()
+                            .add(RowDetailEvent.deleteField(fieldId));
+                      },
                     ),
                   );
                 },

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/home/menu/app/create_button.dart

@@ -30,7 +30,7 @@ class NewAppButton extends StatelessWidget {
   }
 
   Future<void> _showCreateAppDialog(BuildContext context) async {
-    return TextFieldDialog(
+    return NavigatorTextFieldDialog(
       title: LocaleKeys.newPageText.tr(),
       value: "",
       confirm: (newValue) {

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart

@@ -126,7 +126,7 @@ class MenuAppHeader extends StatelessWidget {
     action.fold(() {}, (action) {
       switch (action) {
         case AppDisclosureAction.rename:
-          TextFieldDialog(
+          NavigatorTextFieldDialog(
             title: LocaleKeys.menuAppHeader_renameDialog.tr(),
             value: context.read<AppBloc>().state.app.name,
             confirm: (newValue) {

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart

@@ -109,7 +109,7 @@ class ViewSectionItem extends StatelessWidget {
     action.foldRight({}, (action, previous) {
       switch (action) {
         case ViewDisclosureAction.rename:
-          TextFieldDialog(
+          NavigatorTextFieldDialog(
             title: LocaleKeys.disclosureAction_rename.tr(),
             value: context.read<ViewBloc>().state.view.name,
             confirm: (newValue) {

+ 68 - 24
frontend/app_flowy/lib/workspace/presentation/widgets/dialogs.dart

@@ -1,3 +1,4 @@
+import 'package:appflowy_popover/popover.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/text_style.dart';
 import 'package:flowy_infra/theme.dart';
@@ -15,13 +16,13 @@ import 'package:textstyle_extensions/textstyle_extensions.dart';
 export 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 
-class TextFieldDialog extends StatefulWidget {
+class NavigatorTextFieldDialog extends StatefulWidget {
   final String value;
   final String title;
   final void Function()? cancel;
   final void Function(String) confirm;
 
-  const TextFieldDialog({
+  const NavigatorTextFieldDialog({
     required this.title,
     required this.value,
     required this.confirm,
@@ -30,10 +31,10 @@ class TextFieldDialog extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  State<TextFieldDialog> createState() => _CreateTextFieldDialog();
+  State<NavigatorTextFieldDialog> createState() => _CreateTextFieldDialog();
 }
 
-class _CreateTextFieldDialog extends State<TextFieldDialog> {
+class _CreateTextFieldDialog extends State<NavigatorTextFieldDialog> {
   String newValue = "";
 
   @override
@@ -71,11 +72,13 @@ class _CreateTextFieldDialog extends State<TextFieldDialog> {
           OkCancelButton(
             onOkPressed: () {
               widget.confirm(newValue);
+              Navigator.of(context).pop();
             },
             onCancelPressed: () {
               if (widget.cancel != null) {
                 widget.cancel!();
               }
+              Navigator.of(context).pop();
             },
           )
         ],
@@ -84,12 +87,14 @@ class _CreateTextFieldDialog extends State<TextFieldDialog> {
   }
 }
 
-class FlowyAlertDialog extends StatefulWidget {
+class PopoverAlertView extends StatelessWidget {
+  final PopoverMutex popoverMutex;
   final String title;
   final void Function()? cancel;
   final void Function()? confirm;
 
-  const FlowyAlertDialog({
+  const PopoverAlertView({
+    required this.popoverMutex,
     required this.title,
     this.confirm,
     this.cancel,
@@ -97,10 +102,46 @@ class FlowyAlertDialog extends StatefulWidget {
   }) : super(key: key);
 
   @override
-  State<FlowyAlertDialog> createState() => _CreateFlowyAlertDialog();
+  Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    return StyledDialog(
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: <Widget>[
+          ...[
+            FlowyText.medium(title, color: theme.shader4),
+          ],
+          if (confirm != null) ...[
+            const VSpace(20),
+            OkCancelButton(
+              onOkPressed: confirm,
+              onCancelPressed: cancel,
+            )
+          ]
+        ],
+      ),
+    );
+  }
+}
+
+class NavigatorAlertDialog extends StatefulWidget {
+  final String title;
+  final void Function()? cancel;
+  final void Function()? confirm;
+
+  const NavigatorAlertDialog({
+    required this.title,
+    this.confirm,
+    this.cancel,
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  State<NavigatorAlertDialog> createState() => _CreateFlowyAlertDialog();
 }
 
-class _CreateFlowyAlertDialog extends State<FlowyAlertDialog> {
+class _CreateFlowyAlertDialog extends State<NavigatorAlertDialog> {
   @override
   void initState() {
     super.initState();
@@ -119,10 +160,13 @@ class _CreateFlowyAlertDialog extends State<FlowyAlertDialog> {
           ],
           if (widget.confirm != null) ...[
             const VSpace(20),
-            OkCancelButton(
-              onOkPressed: widget.confirm!,
-              onCancelPressed: widget.cancel,
-            )
+            OkCancelButton(onOkPressed: () {
+              widget.confirm?.call();
+              Navigator.of(context).pop();
+            }, onCancelPressed: () {
+              widget.cancel?.call();
+              Navigator.of(context).pop();
+            })
           ]
         ],
       ),
@@ -130,7 +174,7 @@ class _CreateFlowyAlertDialog extends State<FlowyAlertDialog> {
   }
 }
 
-class OkCancelDialog extends StatelessWidget {
+class NavigatorOkCancelDialog extends StatelessWidget {
   final VoidCallback? onOkPressed;
   final VoidCallback? onCancelPressed;
   final String? okTitle;
@@ -139,7 +183,7 @@ class OkCancelDialog extends StatelessWidget {
   final String message;
   final double? maxWidth;
 
-  const OkCancelDialog(
+  const NavigatorOkCancelDialog(
       {Key? key,
       this.onOkPressed,
       this.onCancelPressed,
@@ -167,8 +211,14 @@ class OkCancelDialog extends StatelessWidget {
           Text(message, style: TextStyles.Body1.textHeight(1.5)),
           SizedBox(height: Insets.l),
           OkCancelButton(
-            onOkPressed: onOkPressed,
-            onCancelPressed: onCancelPressed,
+            onOkPressed: () {
+              onOkPressed?.call();
+              Navigator.of(context).pop();
+            },
+            onCancelPressed: () {
+              onCancelPressed?.call();
+              Navigator.of(context).pop();
+            },
             okTitle: okTitle?.toUpperCase(),
             cancelTitle: cancelTitle?.toUpperCase(),
           )
@@ -204,20 +254,14 @@ class OkCancelButton extends StatelessWidget {
           if (onCancelPressed != null)
             SecondaryTextButton(
               cancelTitle ?? LocaleKeys.button_Cancel.tr(),
-              onPressed: () {
-                onCancelPressed!();
-                Navigator.of(context).pop();
-              },
+              onPressed: onCancelPressed,
               bigMode: true,
             ),
           HSpace(Insets.m),
           if (onOkPressed != null)
             PrimaryTextButton(
               okTitle ?? LocaleKeys.button_OK.tr(),
-              onPressed: () {
-                onOkPressed!();
-                Navigator.of(context).pop();
-              },
+              onPressed: onOkPressed,
               bigMode: true,
             ),
         ],

+ 2 - 2
frontend/app_flowy/packages/appflowy_popover/lib/popover.dart

@@ -59,7 +59,7 @@ class Popover extends StatefulWidget {
   final Decoration? maskDecoration;
 
   /// The function used to build the popover.
-  final Widget Function(BuildContext context) popupBuilder;
+  final Widget? Function(BuildContext context) popupBuilder;
 
   final int triggerActions;
 
@@ -265,7 +265,7 @@ class _PopoverMaskState extends State<_PopoverMask> {
 }
 
 class PopoverContainer extends StatefulWidget {
-  final Widget Function(BuildContext context) popupBuilder;
+  final Widget? Function(BuildContext context) popupBuilder;
   final PopoverDirection direction;
   final PopoverLink popoverLink;
   final Offset offset;

+ 1 - 1
frontend/app_flowy/packages/flowy_infra_ui/lib/widget/dialog/styled_dialogs.dart

@@ -65,7 +65,7 @@ class StyledDialog extends StatelessWidget {
 
     return FocusTraversalGroup(
       child: Container(
-        margin: margin ?? EdgeInsets.all(Insets.lGutter * 2),
+        margin: margin ?? EdgeInsets.all(Insets.sm * 2),
         alignment: Alignment.center,
         child: Container(
           constraints: BoxConstraints(