import 'dart:convert'; import 'dart:developer'; import 'package:flutter/foundation.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'push_actions.dart'; import 'push_target.dart'; /// Routes foreground notification interactions from the single /// flutter_local_notifications response callback. Action responses (reply / /// mark-read) are dispatched straight to [PushActions]; a plain tap publishes /// its target via [pendingTarget] for [App] to navigate to. class PushTapRouter { PushTapRouter._(); /// Target of the most recently tapped notification, or null. [App] listens /// to this and navigates, then resets it to null. static final ValueNotifier pendingTarget = ValueNotifier(null); static void handleResponse(NotificationResponse response) { final actionId = response.actionId; if (actionId == kTalkReplyActionId || actionId == kTalkMarkReadActionId) { // Reuse the isolate-safe action dispatch for foreground actions too. PushActions.handleBackgroundResponse(response); return; } final map = _payloadMap(response.payload); if (map == null) return; final target = resolvePushTarget(map); if (target != null) pendingTarget.value = target; } static bool _launchHandled = false; /// Routes the tap that cold-started the app. The plugin reports such a tap /// only through its launch details, never through the response callback; /// the details stay set for the whole process, hence the one-shot guard. static Future handleAppLaunch( FlutterLocalNotificationsPlugin plugin, ) async { if (_launchHandled) return; _launchHandled = true; try { final details = await plugin.getNotificationAppLaunchDetails(); final response = details?.notificationResponse; if (details?.didNotificationLaunchApp != true || response == null) return; handleResponse(response); } on Object catch (e) { log('Reading the notification launch details failed: $e'); } } static Map? _payloadMap(String? payload) { if (payload == null || payload.isEmpty) return null; try { return jsonDecode(payload) as Map; } on Object { return null; } } }