1// Service Worker for Push Notifications 2// TimeCard ãã«ãããã³ã夿 管çã·ã¹ãã 3 4const NOTIFICATION_TAG = 'timecard-notification'; 5 6/** 7 * ããã·ã¥éç¥åä¿¡æã®å¦ç 8 */ 9self.addEventListener('push', (event) => { 10 console.log('[Service Worker] Push notification received'); 11 12 if (!event.data) { 13 console.warn('[Service Worker] Push event has no data'); 14 return; 15 } 16 17 try { 18 const data = event.data.json(); 19 console.log('[Service Worker] Push data:', data); 20 21 const options = { 22 body: data.body || 'æ°ããéç¥ãããã¾ã', 23 icon: data.icon || '/icons/icon-192x192.png', 24 badge: data.badge || '/icons/icon-192x192.png', 25 tag: NOTIFICATION_TAG, 26 requireInteraction: true, // ã¦ã¼ã¶ã¼ãæä½ããã¾ã§è¡¨ç¤ºãç¶ãã 27 data: data.data || {}, 28 actions: [ 29 { 30 action: 'view', 31 title: '確èªãã', 32 icon: '/icons/icon-192x192.png', 33 }, 34 { 35 action: 'close', 36 title: 'éãã', 37 }, 38 ], 39 // æ¯åãã¿ã¼ã³ï¼ã¢ãã¤ã«ç¨ï¼: 200msæ¯å, 100ms忢, 200msæ¯å 40 vibrate: [200, 100, 200], 41 // é³ï¼ã·ã¹ãã ããã©ã«ãï¼ 42 silent: false, 43 }; 44 45 event.waitUntil( 46 self.registration.showNotification(data.title || '夿 管çã·ã¹ãã ', options) 47 ); 48 } catch (error) { 49 console.error('[Service Worker] Error parsing push data:', error); 50 } 51}); 52 53/** 54 * éç¥ã¯ãªãã¯æã®å¦ç 55 */ 56self.addEventListener('notificationclick', (event) => { 57 console.log('[Service Worker] Notification clicked:', event.action); 58 59 event.notification.close(); 60 61 if (event.action === 'close') { 62 // ãéããããã¿ã³ - ä½ãããªã 63 return; 64 } 65 66 // ã確èªããããã¿ã³ ã¾ã㯠éç¥æ¬ä½ã¯ãªã㯠67 const urlToOpen = event.notification.data?.url || '/'; 68 const fullUrl = new URL(urlToOpen, self.location.origin).href; 69 70 event.waitUntil( 71 clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => { 72 // åããªãªã¸ã³ã®ã¦ã£ã³ãã¦ãæ¢ã«ããã°ãã©ã¼ã«ã¹ã®ã¿ï¼navigate 㯠Android ã§ç½ç»é¢ã«ãªãï¼ 73 for (const client of clientList) { 74 if (client.url.startsWith(self.location.origin) && 'focus' in client) { 75 return client.focus(); 76 } 77 } 78 79 // ã¦ã£ã³ãã¦ãåå¨ããªãå ´åã®ã¿æ°è¦ãªã¼ãã³ 80 if (clients.openWindow) { 81 return clients.openWindow(fullUrl); 82 } 83 }) 84 ); 85}); 86 87/** 88 * ããã·ã¥è³¼èªå¤æ´æã®å¦ç 89 * è³¼èªã®æ´æ°ã¯ã¢ããªå´ï¼Punch.vueï¼ã§è¡ããããããã§ã¯ä½ãããªã 90 */ 91self.addEventListener('pushsubscriptionchange', (_event) => { 92 // ã¢ããªèµ·åæã« Punch.vue ãè³¼èªç¶æ ã確èªãã¦åç»é²ãã 93}); 94 95/** 96 * Service Worker ã¤ã³ã¹ãã¼ã«æ 97 */ 98self.addEventListener('install', (event) => { 99 console.log('[Service Worker] Installing...'); 100 self.skipWaiting(); // å³åº§ã«ã¢ã¯ãã£ãå 101}); 102 103/** 104 * Service Worker ã¢ã¯ãã£ãã¼ã·ã§ã³æ 105 */ 106self.addEventListener('activate', (event) => { 107 console.log('[Service Worker] Activating...'); 108 event.waitUntil(clients.claim()); // æ¢åã®ã¿ããå³åº§ã«å¶å¾¡ä¸ã«ç½®ã 109}); 110 111console.log('[Service Worker] Loaded successfully');
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.