File size: 3,559 Bytes
3a08226 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | // Notification Worker - Manages notification state
let notifications = [];
let notificationHistory = [];
const MAX_NOTIFICATIONS = 25;
self.addEventListener('message', (e) => {
const { action, data } = e.data;
switch (action) {
case 'FETCH':
fetchNotifications();
break;
case 'POST':
postNotification(data);
break;
case 'CLEAR':
clearNotification(data.id);
break;
case 'CLEAR_ALL':
clearAllNotifications();
break;
case 'GET_HISTORY':
self.postMessage({ type: 'HISTORY', history: notificationHistory.slice(-50) });
break;
}
});
async function fetchNotifications() {
let activeNotifs = [];
// Try Android notification listener
if (self.Android?.NotificationListener?.getActiveNotifications) {
activeNotifs = JSON.parse(self.Android.NotificationListener.getActiveNotifications());
}
// Fallback: Generate from stored or mock for testing
if (activeNotifs.length === 0) {
activeNotifs = getMockNotifications();
}
notifications = activeNotifs;
self.postMessage({
type: 'NOTIFICATIONS',
notifications: notifications.slice(0, MAX_NOTIFICATIONS),
hasMore: notifications.length > MAX_NOTIFICATIONS
});
}
function postNotification(data) {
const notif = {
id: Date.now().toString(),
package: 'archdroid.launcher',
title: data.title,
text: data.text,
timestamp: Date.now(),
actions: data.actions || []
};
notifications.unshift(notif);
if (notifications.length > MAX_NOTIFICATIONS) {
notificationHistory.push(...notifications.splice(MAX_NOTIFICATIONS));
}
self.postMessage({ type: 'NEW_NOTIFICATION', notification: notif });
}
function clearNotification(id) {
notifications = notifications.filter(n => n.id !== id);
if (self.Android?.NotificationListener?.cancelNotification) {
self.Android.NotificationListener.cancelNotification(id);
}
self.postMessage({ type: 'NOTIFICATION_CLEARED', id });
broadcastUpdate();
}
function clearAllNotifications() {
notificationHistory.unshift(...notifications);
notifications = [];
self.postMessage({ type: 'ALL_CLEARED' });
broadcastUpdate();
}
function broadcastUpdate() {
self.postMessage({
type: 'NOTIFICATIONS',
notifications: notifications.slice(0, MAX_NOTIFICATIONS),
count: notifications.length
});
}
function getMockNotifications() {
return [
{
id: '1',
package: 'com.samsung.android.messaging',
title: 'Sarah Chen',
text: 'Meeting at 3pm tomorrow, don\'t forget the docs! π',
timestamp: Date.now() - 120000,
icon: 'message-square',
actions: ['Reply', 'Mark as read']
},
{
id: '2',
package: 'com.google.android.gm',
title: 'GitHub',
text: 'New pull request: "Fix gesture worker memory leak"',
timestamp: Date.now() - 300000,
icon: 'github',
actions: ['View', 'Archive']
},
{
id: '3',
package: 'com.samsung.android.calendar',
title: 'Upcoming: Stand-up',
text: 'In 15 minutes β’ Video call with Engineering team',
timestamp: Date.now() - 6000000,
icon: 'calendar',
actions: ['Join', 'Snooze']
},
{
id: '4',
package: 'com.spotify.music',
title: 'Now playing',
text: 'Cyberpunk 2077: I Really Want to Stay At Your House',
timestamp: Date.now() - 900000,
icon: 'music',
progress: 45,
actions: ['ββ', 'β']
}
];
}
// Periodic sync
setInterval(fetchNotifications, 5000); |