feat: use popover in date cell

This commit is contained in:
Vincent Chan 2022-08-30 15:29:37 +08:00
parent 01a79c69c3
commit 6ef7b6cf68
3 changed files with 74 additions and 68 deletions

View File

@ -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( return Popover(
child: GestureDetector( controller: _popover,
behavior: HitTestBehavior.opaque, targetAnchor: Alignment.bottomLeft,
onTap: () => _showCalendar(context), followerAnchor: Alignment.topLeft,
child: MouseRegion( offset: const Offset(0, 20),
opaque: false, child: SizedBox.expand(
cursor: SystemMouseCursors.click, child: GestureDetector(
child: Align( behavior: HitTestBehavior.opaque,
alignment: alignment, onTap: () => _showCalendar(context),
child: FlowyText.medium(state.dateStr, fontSize: 12), 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>(); _popover.show();
widget.onCellEditing.value = true;
final calendar =
DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
calendar.show(
context,
cellController: bloc.cellController.clone(),
);
} }
@override @override

View File

@ -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,
}); required this.cellController,
}) : super(key: key);
Future<void> show( @override
BuildContext context, { State<StatefulWidget> createState() => _DateCellEditor();
required GridDateCellController cellController, }
}) async {
DateCellEditor.remove(context);
final result = class _DateCellEditor extends State<DateCellEditor> {
await cellController.getFieldTypeOption(DateTypeOptionDataParser()); DateTypeOptionPB? _dateTypeOptionPB;
result.fold( @override
(dateTypeOptionPB) { void initState() {
final calendar = _CellCalendarWidget( super.initState();
cellContext: cellController, _fetchData();
dateTypeOptionPB: dateTypeOptionPB, }
);
FlowyOverlay.of(context).insertWithAnchor( _fetchData() async {
widget: OverlayContainer( final result = await widget.cellController
child: calendar, .getFieldTypeOption(DateTypeOptionDataParser());
constraints: BoxConstraints.loose(const Size(320, 500)),
), result.fold((dateTypeOptionPB) {
identifier: DateCellEditor.identifier(), setState(() {
anchorContext: context, _dateTypeOptionPB = dateTypeOptionPB;
anchorDirection: AnchorDirection.leftWithCenterAligned, });
style: FlowyOverlayStyle(blur: false), }, (err) => Log.error(err));
delegate: this, }
);
}, @override
(err) => Log.error(err), Widget build(BuildContext context) {
if (_dateTypeOptionPB == null) {
return Container();
}
return OverlayContainer(
child: _CellCalendarWidget(
cellContext: widget.cellController,
dateTypeOptionPB: _dateTypeOptionPB!,
),
constraints: BoxConstraints.loose(const Size(320, 500)),
); );
} }
static void remove(BuildContext context) {
FlowyOverlay.of(context).remove(identifier());
}
static String identifier() {
return (DateCellEditor).toString();
}
@override
void didRemove() => onDismissed();
@override
bool asBarrier() => true;
} }
class _CellCalendarWidget extends StatelessWidget { class _CellCalendarWidget extends StatelessWidget {

View File

@ -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();
} }