// 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);