import 'dart:async'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../push/push_message_handler.dart'; import '../state/app/modules/chat/bloc/chat_bloc.dart'; import '../widget/debug/debug_tile.dart'; import '../widget/debug/json_viewer.dart'; import '../widget/info_dialog.dart'; import 'notification_tasks.dart'; /// Bridges FCM lifecycle callbacks to the push pipeline. Background messages are /// handled directly by [PushMessageHandler.onBackgroundMessage]; this class /// covers the foreground and app-opened paths where a [BuildContext] is /// available. class NotificationController { static Future onForegroundMessageHandler( RemoteMessage message, BuildContext context, ) async { final chatBloc = context.read(); // hasOpenChat, not currentToken: currentToken sticks around after // leaveChat so didPopNext can re-claim a stacked chat. final openChatToken = chatBloc.hasOpenChat ? (chatBloc.state.data?.currentToken ?? '') : null; await PushMessageHandler().handle( message, foreground: true, openChatToken: openChatToken, ); await NotificationTasks.refreshBadge(); if (!context.mounted) return; NotificationTasks.updateProviders(context); } static Future onAppOpenedByNotification( RemoteMessage message, BuildContext context, ) async { NotificationTasks.navigateToTalk( context, chatToken: _extractChatToken(message), ); NotificationTasks.updateProviders(context); unawaited(NotificationTasks.refreshBadge()); DebugTile(context).run(() { InfoDialog.show( context, 'Dieser Bericht wird angezeigt, da du den Entwicklermodus aktiviert hast und die App über eine Benachrichtigung geöffnet wurde.\n\n' '${JsonViewer.format(message.data)}', copyable: true, title: 'Notification report', ); }); } static String? _extractChatToken(RemoteMessage message) { for (final key in const ['chatToken', 'token', 'roomToken']) { final value = message.data[key]; if (value is String && value.isNotEmpty) return value; } return null; } }