mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-11-02 02:53:59 +00:00
feat: use popover in date cell
This commit is contained in:
parent
01a79c69c3
commit
6ef7b6cf68
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user