feat: trigger local notification directly from incoming WebSocket new_message event

This commit is contained in:
Hamza-Ayed
2026-05-18 18:19:03 +03:00
parent cfc1fd0a8e
commit 92d59b0f30
2 changed files with 53 additions and 2 deletions

View File

@@ -153,6 +153,36 @@ class FirebaseService extends GetxService {
); );
} }
void showLocalNotificationFromData(Map<String, dynamic> data) {
final chatId = data['chatId'];
final name = data['name'] ?? 'WhatsApp';
final body = data['body'] ?? 'New Message';
// Smart Notification: Only show if we are NOT currently in this chat
final activeChatId = Get.find<WhatsAppService>().activeChatId.value;
if (chatId != null && activeChatId == chatId) {
return; // Silent
}
const androidDetails = AndroidNotificationDetails(
'whatsapp_channel',
'WhatsApp Messages',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker',
);
const iosDetails = DarwinNotificationDetails();
const details = NotificationDetails(android: androidDetails, iOS: iosDetails);
_localNotifications.show(
DateTime.now().microsecond,
name,
body,
details,
payload: jsonEncode({'chatId': chatId, 'name': name}),
);
}
void _onNotificationTap(NotificationResponse response) { void _onNotificationTap(NotificationResponse response) {
if (response.payload != null) { if (response.payload != null) {
final data = jsonDecode(response.payload!); final data = jsonDecode(response.payload!);
@@ -165,7 +195,6 @@ class FirebaseService extends GetxService {
final name = data['name'] ?? 'Chat'; final name = data['name'] ?? 'Chat';
if (chatId != null) { if (chatId != null) {
// Mock a conversation model to navigate to ChatScreen
final dummyChat = ConversationModel( final dummyChat = ConversationModel(
id: chatId, id: chatId,
name: name, name: name,
@@ -176,7 +205,7 @@ class FirebaseService extends GetxService {
isMuted: false, isMuted: false,
); );
Get.to(() => ChatScreen(conversation: dummyChat)); Get.to(() => ChatScreen(conversation: dummyChat), preventDuplicates: false);
} }
} }
} }

View File

@@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:web_socket_channel/web_socket_channel.dart'; import 'package:web_socket_channel/web_socket_channel.dart';
import '../config/app_config.dart'; import '../config/app_config.dart';
import 'firebase_service.dart';
enum WsStatus { disconnected, connecting, connected, waReady } enum WsStatus { disconnected, connecting, connected, waReady }
@@ -93,7 +94,28 @@ class WhatsAppService extends GetxService {
// Push events // Push events
switch (type) { switch (type) {
case 'new_message':
// Trigger a local notification if the app is open (WebSocket connected)
final chatId = data['chatId'];
final msgData = data['data'];
if (msgData != null && msgData['fromMe'] != true) {
String body = msgData['body'] ?? '';
if (body.isEmpty && msgData['hasMedia'] == true) {
body = '📷 Media/Audio message';
}
try {
Get.find<FirebaseService>().showLocalNotificationFromData({
'chatId': chatId,
'name': chatId?.split('@')[0] ?? 'WhatsApp',
'body': body,
});
} catch (e) {
print('[LOCAL NOTIF ERROR] $e');
}
}
break;
case 'qr': case 'qr':
qrData.value = data['qr']; qrData.value = data['qr'];
isWaReady.value = false; isWaReady.value = false;
if (status.value == WsStatus.waReady) { if (status.value == WsStatus.waReady) {