fix: resolve navigation-cache regressions and todo UX

This commit is contained in:
qzl
2026-03-20 16:45:08 +08:00
parent 3f1858d733
commit 55f3805ee9
15 changed files with 160 additions and 105 deletions
@@ -1,7 +1,5 @@
import 'dart:math';
import 'package:flutter/widgets.dart';
import '../data/services/calendar_service.dart';
import '../../../core/notifications/local_notification_service.dart';
import 'models/reminder_action.dart';
@@ -13,23 +11,16 @@ class ReminderActionExecutor {
final LocalNotificationService _notificationService;
final ReminderOutboxStore _outboxStore;
final Random _random;
final bool Function() _isAppActive;
ReminderActionExecutor({
required CalendarService calendarService,
required LocalNotificationService notificationService,
required ReminderOutboxStore outboxStore,
Random? random,
bool Function()? isAppActive,
}) : _calendarService = calendarService,
_notificationService = notificationService,
_outboxStore = outboxStore,
_random = random ?? Random(),
_isAppActive =
isAppActive ??
(() =>
WidgetsBinding.instance.lifecycleState ==
AppLifecycleState.resumed);
_random = random ?? Random();
Future<void> handleAction({
required ReminderAction action,
@@ -95,9 +86,11 @@ class ReminderActionExecutor {
}
Future<void> _archiveEvent(String eventId, ReminderAction action) async {
if (_isAppActive()) {
try {
await _calendarService.archiveEvent(eventId);
return;
} catch (_) {
// fall through to enqueue local outbox for retry
}
final opId =
@@ -304,9 +304,14 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
if (isNotToday) const SizedBox(width: 8),
AppPressable(
borderRadius: BorderRadius.circular(AppRadius.full),
onTap: () => context.push(
'${AppRoutes.calendarEventCreate}?date=${formatYmd(_selectedDate)}',
),
onTap: () async {
final changed = await context.push<bool>(
'${AppRoutes.calendarEventCreate}?date=${formatYmd(_selectedDate)}',
);
if (changed == true) {
await _loadEvents(forceRefresh: true);
}
},
child: Container(
width: 36,
height: 36,
@@ -625,8 +630,14 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
height: tapHeight,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () =>
context.push(AppRoutes.calendarEventDetail(layout.event.id)),
onTap: () async {
final changed = await context.push<bool>(
AppRoutes.calendarEventDetail(layout.event.id),
);
if (changed == true) {
await _loadEvents(forceRefresh: true);
}
},
child: Stack(
children: [
Positioned(
@@ -481,7 +481,7 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
if (!mounted) {
return;
}
context.pop();
context.pop(true);
}
Future<void> _archiveEvent() async {
@@ -496,9 +496,8 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
}
try {
await sl<CalendarService>().archiveEvent(widget.eventId);
await _loadEvent();
if (mounted) {
Toast.show(context, '已归档', type: ToastType.success);
context.pop(true);
}
} catch (e) {
if (mounted) {
@@ -150,7 +150,14 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
const Spacer(),
AppPressable(
borderRadius: BorderRadius.circular(AppRadius.full),
onTap: () => context.push(AppRoutes.calendarEventCreate),
onTap: () async {
final changed = await context.push<bool>(
AppRoutes.calendarEventCreate,
);
if (changed == true) {
await _loadMonthEvents(forceRefresh: true);
}
},
child: Container(
width: 36,
height: 36,
@@ -345,9 +352,14 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
);
return AppPressable(
borderRadius: BorderRadius.circular(AppRadius.sm),
onTap: () {
onTap: () async {
_calendarManager.setSelectedDate(date);
context.push('/calendar/events/${event.id}');
final changed = await context.push<bool>(
'/calendar/events/${event.id}',
);
if (changed == true) {
await _loadMonthEvents(forceRefresh: true);
}
},
child: Container(
margin: const EdgeInsets.only(bottom: 2),
@@ -751,7 +751,7 @@ class _CreateEventSheetState extends State<CreateEventSheet>
widget.onSaved?.call();
if (mounted) {
Navigator.pop(context);
Navigator.pop(context, true);
}
} catch (e) {
if (mounted) {