Sfoglia il codice sorgente

feat: use popover in date cell

Vincent Chan 2 anni fa
parent
commit
6ef7b6cf68

+ 30 - 18
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart

@@ -3,6 +3,7 @@ import 'package:flutter/widgets.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/plugins/grid/application/prelude.dart';
 import 'package:app_flowy/plugins/grid/application/prelude.dart';
+import 'package:appflowy_popover/popover.dart';
 
 
 import '../cell_builder.dart';
 import '../cell_builder.dart';
 import 'date_editor.dart';
 import 'date_editor.dart';
@@ -39,10 +40,12 @@ class GridDateCell extends GridCellWidget {
 }
 }
 
 
 class _DateCellState extends GridCellState<GridDateCell> {
 class _DateCellState extends GridCellState<GridDateCell> {
+  late PopoverController _popover;
   late DateCellBloc _cellBloc;
   late DateCellBloc _cellBloc;
 
 
   @override
   @override
   void initState() {
   void initState() {
+    _popover = PopoverController();
     final cellController = widget.cellControllerBuilder.build();
     final cellController = widget.cellControllerBuilder.build();
     _cellBloc = getIt<DateCellBloc>(param1: cellController)
     _cellBloc = getIt<DateCellBloc>(param1: cellController)
       ..add(const DateCellEvent.initial());
       ..add(const DateCellEvent.initial());
@@ -58,19 +61,35 @@ class _DateCellState extends GridCellState<GridDateCell> {
       value: _cellBloc,
       value: _cellBloc,
       child: BlocBuilder<DateCellBloc, DateCellState>(
       child: BlocBuilder<DateCellBloc, DateCellState>(
         builder: (context, state) {
         builder: (context, state) {
-          return SizedBox.expand(
-            child: GestureDetector(
-              behavior: HitTestBehavior.opaque,
-              onTap: () => _showCalendar(context),
-              child: MouseRegion(
-                opaque: false,
-                cursor: SystemMouseCursors.click,
-                child: Align(
-                  alignment: alignment,
-                  child: FlowyText.medium(state.dateStr, fontSize: 12),
+          return Popover(
+            controller: _popover,
+            targetAnchor: Alignment.bottomLeft,
+            followerAnchor: Alignment.topLeft,
+            offset: const Offset(0, 20),
+            child: SizedBox.expand(
+              child: GestureDetector(
+                behavior: HitTestBehavior.opaque,
+                onTap: () => _showCalendar(context),
+                child: MouseRegion(
+                  opaque: false,
+                  cursor: SystemMouseCursors.click,
+                  child: Align(
+                    alignment: alignment,
+                    child: FlowyText.medium(state.dateStr, fontSize: 12),
+                  ),
                 ),
                 ),
               ),
               ),
             ),
             ),
+            popupBuilder: (BuildContext popoverContent) {
+              final bloc = context.read<DateCellBloc>();
+              return DateCellEditor(
+                cellController: bloc.cellController.clone(),
+                onDismissed: () => widget.onCellEditing.value = false,
+              );
+            },
+            onClose: () {
+              widget.onCellEditing.value = false;
+            },
           );
           );
         },
         },
       ),
       ),
@@ -78,14 +97,7 @@ class _DateCellState extends GridCellState<GridDateCell> {
   }
   }
 
 
   void _showCalendar(BuildContext context) {
   void _showCalendar(BuildContext context) {
-    final bloc = context.read<DateCellBloc>();
-    widget.onCellEditing.value = true;
-    final calendar =
-        DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
-    calendar.show(
-      context,
-      cellController: bloc.cellController.clone(),
-    );
+    _popover.show();
   }
   }
 
 
   @override
   @override

+ 35 - 38
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart

@@ -1,6 +1,7 @@
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
 import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
+import 'package:app_flowy/startup/tasks/platform_service.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra/theme.dart';
@@ -23,58 +24,54 @@ final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
 final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day);
 final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day);
 const kMargin = EdgeInsets.symmetric(horizontal: 6, vertical: 10);
 const kMargin = EdgeInsets.symmetric(horizontal: 6, vertical: 10);
 
 
-class DateCellEditor with FlowyOverlayDelegate {
+class DateCellEditor extends StatefulWidget {
   final VoidCallback onDismissed;
   final VoidCallback onDismissed;
+  final GridDateCellController cellController;
 
 
   const DateCellEditor({
   const DateCellEditor({
+    Key? key,
     required this.onDismissed,
     required this.onDismissed,
-  });
-
-  Future<void> show(
-    BuildContext context, {
-    required GridDateCellController cellController,
-  }) async {
-    DateCellEditor.remove(context);
+    required this.cellController,
+  }) : super(key: key);
 
 
-    final result =
-        await cellController.getFieldTypeOption(DateTypeOptionDataParser());
+  @override
+  State<StatefulWidget> createState() => _DateCellEditor();
+}
 
 
-    result.fold(
-      (dateTypeOptionPB) {
-        final calendar = _CellCalendarWidget(
-          cellContext: cellController,
-          dateTypeOptionPB: dateTypeOptionPB,
-        );
+class _DateCellEditor extends State<DateCellEditor> {
+  DateTypeOptionPB? _dateTypeOptionPB;
 
 
-        FlowyOverlay.of(context).insertWithAnchor(
-          widget: OverlayContainer(
-            child: calendar,
-            constraints: BoxConstraints.loose(const Size(320, 500)),
-          ),
-          identifier: DateCellEditor.identifier(),
-          anchorContext: context,
-          anchorDirection: AnchorDirection.leftWithCenterAligned,
-          style: FlowyOverlayStyle(blur: false),
-          delegate: this,
-        );
-      },
-      (err) => Log.error(err),
-    );
+  @override
+  void initState() {
+    super.initState();
+    _fetchData();
   }
   }
 
 
-  static void remove(BuildContext context) {
-    FlowyOverlay.of(context).remove(identifier());
-  }
+  _fetchData() async {
+    final result = await widget.cellController
+        .getFieldTypeOption(DateTypeOptionDataParser());
 
 
-  static String identifier() {
-    return (DateCellEditor).toString();
+    result.fold((dateTypeOptionPB) {
+      setState(() {
+        _dateTypeOptionPB = dateTypeOptionPB;
+      });
+    }, (err) => Log.error(err));
   }
   }
 
 
   @override
   @override
-  void didRemove() => onDismissed();
+  Widget build(BuildContext context) {
+    if (_dateTypeOptionPB == null) {
+      return Container();
+    }
 
 
-  @override
-  bool asBarrier() => true;
+    return OverlayContainer(
+      child: _CellCalendarWidget(
+        cellContext: widget.cellController,
+        dateTypeOptionPB: _dateTypeOptionPB!,
+      ),
+      constraints: BoxConstraints.loose(const Size(320, 500)),
+    );
+  }
 }
 }
 
 
 class _CellCalendarWidget extends StatelessWidget {
 class _CellCalendarWidget extends StatelessWidget {

+ 5 - 8
frontend/app_flowy/packages/appflowy_popover/lib/popover.dart

@@ -37,6 +37,7 @@ class Popover extends StatefulWidget {
   final Alignment targetAnchor;
   final Alignment targetAnchor;
   final Alignment followerAnchor;
   final Alignment followerAnchor;
   final Widget Function(BuildContext context) popupBuilder;
   final Widget Function(BuildContext context) popupBuilder;
+  final void Function()? onClose;
 
 
   const Popover({
   const Popover({
     Key? key,
     Key? key,
@@ -47,6 +48,7 @@ class Popover extends StatefulWidget {
     this.maskDecoration,
     this.maskDecoration,
     this.targetAnchor = Alignment.topLeft,
     this.targetAnchor = Alignment.topLeft,
     this.followerAnchor = Alignment.topLeft,
     this.followerAnchor = Alignment.topLeft,
+    this.onClose,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override
@@ -71,15 +73,9 @@ class PopoverState extends State<Popover> {
     _recognizer.onTap = (() {
     _recognizer.onTap = (() {
       debugPrint("ggg tap");
       debugPrint("ggg tap");
     });
     });
-    WidgetsBinding.instance.pointerRouter
-        .addGlobalRoute(_handleGlobalPointerEvent);
     super.initState();
     super.initState();
   }
   }
 
 
-  _handleGlobalPointerEvent(PointerEvent event) {
-    // debugPrint("mouse down: ${event}");
-  }
-
   showOverlay() {
   showOverlay() {
     debugPrint("show overlay");
     debugPrint("show overlay");
     close();
     close();
@@ -126,14 +122,15 @@ class PopoverState extends State<Popover> {
       if (_popoverWithMask == this) {
       if (_popoverWithMask == this) {
         _popoverWithMask = null;
         _popoverWithMask = null;
       }
       }
+      if (widget.onClose != null) {
+        widget.onClose!();
+      }
     }
     }
   }
   }
 
 
   @override
   @override
   void deactivate() {
   void deactivate() {
     debugPrint("deactivate");
     debugPrint("deactivate");
-    WidgetsBinding.instance.pointerRouter
-        .removeGlobalRoute(_handleGlobalPointerEvent);
     close();
     close();
     super.deactivate();
     super.deactivate();
   }
   }