implemented chat long-polling and optimistic updates, centralized notification management, optimized avatar caching

This commit is contained in:
2026-05-10 15:47:55 +02:00
parent 6ae396e605
commit 1458d8ce49
15 changed files with 712 additions and 146 deletions
+22 -1
View File
@@ -1,11 +1,19 @@
import 'dart:async';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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';
// `vm:entry-point` on the class so AOT tree-shaking doesn't drop it: the
// FCM background handler runs in a fresh isolate that looks up the class
// by name from native code.
@pragma('vm:entry-point')
class NotificationController {
// Notification display is handled by the Firebase SDK using server-generated payloads.
@pragma('vm:entry-point')
@@ -17,8 +25,21 @@ class NotificationController {
RemoteMessage message,
BuildContext context,
) async {
NotificationTasks.updateProviders(context);
final pushToken = _extractChatToken(message);
final activeToken = context.read<ChatBloc>().state.data?.currentToken ?? '';
final chatIsOpen =
pushToken != null && pushToken.isNotEmpty && pushToken == activeToken;
NotificationTasks.updateBadgeCount(message);
if (chatIsOpen) {
// Long-poll already fetches the message and moves the marker; just
// dismiss any tray entry that slipped through foreground rendering.
unawaited(NotificationTasks.clearNotificationsForChat(pushToken));
return;
}
NotificationTasks.updateProviders(context);
}
static Future<void> onAppOpenedByNotification(