diff --git a/app.js b/app.js index 0b23594..9df7303 100644 --- a/app.js +++ b/app.js @@ -9,6 +9,8 @@ let gameState = 'setup'; // setup, running, paused, over let carouselPosition = 0; let startX = 0; let currentX = 0; +let pushSubscription = null; +const PUBLIC_VAPID_KEY = 'BNIXGVBzq6SNqvlDMFylw_hLTpf_J96ddbwfMa9Cn1tFQ1-vDqmz_NQS0a5UiczqAJ-uYs-6EeuwrnwaMRGtifk='; // DOM Elements const carousel = document.getElementById('carousel'); @@ -37,6 +39,47 @@ const cameraCancelButton = document.getElementById('cameraCancelButton'); let stream = null; +async function subscribeToPushNotifications() { + if ('serviceWorker' in navigator && 'PushManager' in window) { + try { + const registration = await navigator.serviceWorker.ready; + const subscription = await registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array(PUBLIC_VAPID_KEY) + }); + + // Send subscription to your server + await fetch('https://webpush.virtonline.eu/subscribe', { + method: 'POST', + body: JSON.stringify(subscription), + headers: { + 'Content-Type': 'application/json' + } + }); + + pushSubscription = subscription; + console.log('Push subscription successful'); + } catch (error) { + console.error('Error subscribing to push:', error); + } + } + } + + function urlBase64ToUint8Array(base64String) { + const padding = '='.repeat((4 - base64String.length % 4) % 4); + const base64 = (base64String + padding) + .replace(/-/g, '+') + .replace(/_/g, '/'); + + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; + } + // Add sound toggle button const createSoundToggleButton = () => { const headerButtons = document.querySelector('.header-buttons'); @@ -177,11 +220,13 @@ gameButton.addEventListener('click', () => { gameState = 'paused'; audioManager.play('gamePause'); stopTimer(); + // sendPushNotification('Game Paused', 'The game timer has paused!'); break; case 'paused': gameState = 'running'; audioManager.play('gameResume'); startTimer(); + // sendPushNotification('Game Resumed', 'The game timer has resumed!'); break; case 'over': // Reset timers and start new game @@ -198,6 +243,26 @@ gameButton.addEventListener('click', () => { saveData(); }); +async function sendPushNotification(title, message) { + if (!pushSubscription) return; + + try { + await fetch('https://webpush.virtonline.eu/flic-webhook', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + title: title, + body: message, + action: 'game_update' + }) + }); + } catch (error) { + console.error('Error sending push notification:', error); + } +} + // Timer variables let timerInterval = null; @@ -776,19 +841,23 @@ navigator.serviceWorker.addEventListener('message', (event) => { // Service Worker Registration if ('serviceWorker' in navigator) { window.addEventListener('load', () => { - navigator.serviceWorker.register('/sw.js') - .then(registration => { - console.log('ServiceWorker registered: ', registration); - - // Setup and handle deep links after service worker is ready - setupDeepLinks(); - }) - .catch(error => { - console.log('ServiceWorker registration failed: ', error); - - // Still try to handle deep links even if service worker failed - setupDeepLinks(); - }); + navigator.serviceWorker.register('/sw.js') + .then(registration => { + console.log('ServiceWorker registered'); + + // Request notification permission and subscribe + Notification.requestPermission().then(permission => { + if (permission === 'granted') { + subscribeToPushNotifications(); + } + }); + + setupDeepLinks(); + }) + .catch(error => { + console.log('ServiceWorker registration failed:', error); + setupDeepLinks(); + }); }); } else { // If service workers aren't supported, still handle deep links diff --git a/index.html b/index.html index 0d76fbf..42687e0 100644 --- a/index.html +++ b/index.html @@ -164,6 +164,16 @@ .catch((err) => console.log("Service Worker Failed", err)); } +