Fix notification delivery and settings flows

This commit is contained in:
Dwindi Ramadhana
2026-05-31 20:40:20 +07:00
parent 5195ba19ad
commit 2bd8e3666a
12 changed files with 1419 additions and 435 deletions

View File

@@ -4,10 +4,36 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/data/latest.dart' as tz_data;
import 'package:timezone/timezone.dart' as tz;
import '../../app/router.dart';
import '../local/models/app_settings.dart';
import 'notification_analytics_service.dart';
import 'notification_runtime_service.dart';
@pragma('vm:entry-point')
void notificationTapBackgroundHandler(NotificationResponse response) {
// Background isolates cannot safely drive GoRouter. Foreground/cold-start
// taps are handled by NotificationService after the app is initialized.
}
String? routeForNotificationPayload(String? payload) {
final type = (payload ?? '').split('|').first.trim().toLowerCase();
switch (type) {
case 'report':
case 'checklist':
return '/checklist';
case 'adhan':
case 'iqamah':
return '/';
case 'remote':
case 'content':
case 'streak_risk':
case 'system':
return '/notifications';
default:
return null;
}
}
class NotificationPermissionStatus {
const NotificationPermissionStatus({
required this.notificationsAllowed,
@@ -148,11 +174,37 @@ class NotificationService {
macOS: darwinSettings,
);
await _plugin.initialize(settings: settings);
await _plugin.initialize(
settings: settings,
onDidReceiveNotificationResponse: _handleNotificationResponse,
onDidReceiveBackgroundNotificationResponse:
notificationTapBackgroundHandler,
);
await _requestPermissions();
await _handleLaunchNotification();
_initialized = true;
}
Future<void> _handleLaunchNotification() async {
final details = await _plugin.getNotificationAppLaunchDetails();
final response = details?.notificationResponse;
if (response == null) return;
_routeFromPayload(response.payload);
}
void _handleNotificationResponse(NotificationResponse response) {
_routeFromPayload(response.payload);
}
void _routeFromPayload(String? payload) {
final route = routeForNotificationPayload(payload);
if (route == null) return;
Future<void>.delayed(Duration.zero, () {
appRouter.go(route);
});
}
void _configureLocalTimeZone() {
final tzId = _resolveTimeZoneIdByOffset(DateTime.now().timeZoneOffset);
try {
@@ -532,7 +584,10 @@ class NotificationService {
final pending = await _plugin.pendingNotificationRequests();
for (final request in pending) {
final id = request.id;
final isPrayerSchedule = id >= 100000 && id < 900000;
// Adhan IDs: 100000..799999
// Iqamah IDs: 800000..1499999
// Report IDs: 700000..789999
final isPrayerSchedule = id >= 100000 && id < 1500000;
if (isPrayerSchedule) {
await _plugin.cancel(id: id);
}