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:app_flowy/startup/startup.dart';
import 'package:app_flowy/plugins/grid/application/prelude.dart';
import 'package:appflowy_popover/popover.dart';
import '../cell_builder.dart';
import 'date_editor.dart';
@ -39,10 +40,12 @@ class GridDateCell extends GridCellWidget {
}
class _DateCellState extends GridCellState<GridDateCell> {
late PopoverController _popover;
late DateCellBloc _cellBloc;
@override
void initState() {
_popover = PopoverController();
final cellController = widget.cellControllerBuilder.build();
_cellBloc = getIt<DateCellBloc>(param1: cellController)
..add(const DateCellEvent.initial());
@ -58,19 +61,35 @@ class _DateCellState extends GridCellState<GridDateCell> {
value: _cellBloc,
child: BlocBuilder<DateCellBloc, DateCellState>(
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) {
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

View File

@ -1,6 +1,7 @@
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/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:flowy_infra/image.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);
const kMargin = EdgeInsets.symmetric(horizontal: 6, vertical: 10);
class DateCellEditor with FlowyOverlayDelegate {
class DateCellEditor extends StatefulWidget {
final VoidCallback onDismissed;
final GridDateCellController cellController;
const DateCellEditor({
Key? key,
required this.onDismissed,
});
required this.cellController,
}) : super(key: key);
Future<void> show(
BuildContext context, {
required GridDateCellController cellController,
}) async {
DateCellEditor.remove(context);
@override
State<StatefulWidget> createState() => _DateCellEditor();
}
final result =
await cellController.getFieldTypeOption(DateTypeOptionDataParser());
class _DateCellEditor extends State<DateCellEditor> {
DateTypeOptionPB? _dateTypeOptionPB;
result.fold(
(dateTypeOptionPB) {
final calendar = _CellCalendarWidget(
cellContext: cellController,
dateTypeOptionPB: dateTypeOptionPB,
);
@override
void initState() {
super.initState();
_fetchData();
}
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),
_fetchData() async {
final result = await widget.cellController
.getFieldTypeOption(DateTypeOptionDataParser());
result.fold((dateTypeOptionPB) {
setState(() {
_dateTypeOptionPB = dateTypeOptionPB;
});
}, (err) => Log.error(err));
}
@override
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 {

View File

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