88 lines
3.2 KiB
Dart
88 lines
3.2 KiB
Dart
import 'dart:convert';
|
|
import 'package:workmanager/workmanager.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:odoo_rpc/odoo_rpc.dart';
|
|
import 'notification_service.dart';
|
|
|
|
// NOTE: This key tracks what IDs have been shown as device tray notifications.
|
|
// It is separate from 'last_seen_notification_id' (which tracks what the user READ in-app).
|
|
|
|
@pragma('vm:entry-point')
|
|
void callbackDispatcher() {
|
|
Workmanager().executeTask((task, inputData) async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final url = prefs.getString('odoo_url');
|
|
final sessionStr = prefs.getString('odoo_session');
|
|
|
|
if (url == null || sessionStr == null) {
|
|
return Future.value(true); // Not logged in, nothing to do
|
|
}
|
|
|
|
final sessionArgs = json.decode(sessionStr);
|
|
final session = OdooSession.fromJson(
|
|
Map<String, dynamic>.from(sessionArgs as Map));
|
|
final partnerId = session.partnerId;
|
|
final keyLastDeviceNotifiedId = 'last_device_notified_id_$partnerId';
|
|
final keyReadNotificationIds = 'read_notification_ids_$partnerId';
|
|
|
|
final client = OdooClient(url, sessionId: session);
|
|
|
|
final response = await client.callRPC(
|
|
'/api/loyalty/fetch_notifications',
|
|
'call',
|
|
{'last_id': 0},
|
|
);
|
|
|
|
client.close();
|
|
|
|
if (response != null && response['status'] == 'success') {
|
|
final List<dynamic> notifications =
|
|
List<dynamic>.from(response['data'] ?? []);
|
|
|
|
// Filter to only truly new ones not yet shown on device tray
|
|
final lastDeviceNotifiedId = prefs.getInt(keyLastDeviceNotifiedId) ?? 0;
|
|
final newNotifs = notifications
|
|
.where((n) => (n['id'] as int? ?? 0) > lastDeviceNotifiedId)
|
|
.toList();
|
|
|
|
final notifService = NotificationService();
|
|
await notifService.initialize();
|
|
|
|
if (newNotifs.isNotEmpty) {
|
|
int highestId = lastDeviceNotifiedId;
|
|
for (final notif in newNotifs) {
|
|
final int notifId = notif['id'] as int? ?? 0;
|
|
if (notifId > highestId) highestId = notifId;
|
|
|
|
await notifService.showNotification(
|
|
id: notifId,
|
|
title: notif['title'] as String? ?? 'Mie Mapan',
|
|
body: notif['body'] as String? ?? '',
|
|
);
|
|
}
|
|
|
|
await prefs.setInt(keyLastDeviceNotifiedId, highestId);
|
|
}
|
|
|
|
// Always compute badge count based on read_notification_ids
|
|
final readIds = prefs.getStringList(keyReadNotificationIds);
|
|
if (readIds == null) {
|
|
// Initialize read list with all currently fetched notifications on first install/run
|
|
final initialRead = notifications.map((n) => (n['id'] as int? ?? 0).toString()).toList();
|
|
await prefs.setStringList(keyReadNotificationIds, initialRead);
|
|
await notifService.setBadge(0);
|
|
} else {
|
|
final unreadCount = notifications
|
|
.where((n) => !readIds.contains((n['id'] as int? ?? 0).toString()))
|
|
.length;
|
|
await notifService.setBadge(unreadCount);
|
|
}
|
|
}
|
|
} catch (_) {
|
|
// Silently swallow — background isolate must never crash
|
|
}
|
|
return Future.value(true);
|
|
});
|
|
}
|