import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import '../push/push_actions.dart'; import '../push/push_renderer.dart'; import '../push/push_tap_router.dart'; class NotificationService { static final NotificationService _instance = NotificationService._internal(); factory NotificationService() => _instance; NotificationService._internal(); FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); Future initializeNotifications() async { // Dedicated monochrome status-bar icon: launcher mipmaps are unusable as // small icons because Android renders only their alpha silhouette (a // solid circle in the status bar). const androidSettings = AndroidInitializationSettings( '@drawable/ic_stat_notification', ); // iOS Talk category mirrors the Android inline reply + mark-as-read actions // so both platforms expose the same quick actions. The actual delivery of // these while the app is terminated is handled by the (Phase 3) NSE. final iosSettings = DarwinInitializationSettings( notificationCategories: [ DarwinNotificationCategory( PushRenderer.iosTalkCategory, actions: [ DarwinNotificationAction.text( kTalkReplyActionId, 'Antworten', buttonTitle: 'Senden', options: const { DarwinNotificationActionOption.authenticationRequired, }, ), DarwinNotificationAction.plain(kTalkMarkReadActionId, 'Gelesen'), ], ), ], ); final initializationSettings = InitializationSettings( android: androidSettings, iOS: iosSettings, ); await flutterLocalNotificationsPlugin.initialize( settings: initializationSettings, onDidReceiveNotificationResponse: PushTapRouter.handleResponse, // Top-level function, NOT the static method: AOT callback resolution // has failed for static class members (see pushActionBackgroundHandler). onDidReceiveBackgroundNotificationResponse: pushActionBackgroundHandler, ); } }