From 429c1dd557638ecd425dedc10fc26cbde66d1741 Mon Sep 17 00:00:00 2001 From: cpu Date: Wed, 26 Mar 2025 22:41:22 +0100 Subject: [PATCH] handle all button types --- app.js | 96 +++++++++++++++++++++++++++++++++++++++++++++----------- sw.js | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 165 insertions(+), 30 deletions(-) diff --git a/app.js b/app.js index 76a0e4a..b161e94 100644 --- a/app.js +++ b/app.js @@ -469,25 +469,6 @@ carousel.addEventListener('touchend', (e) => { saveData(); }); -carousel.addEventListener('push', (e) => { - console.log('[carousel] Push received'); - if (!isDragging) return; - - isDragging = false; - - const data = e.data ? e.data.json() : {}; - const button_id = data.body ? data.body.button_id : ''; - const click_type = data.body ? data.body.click_type : ''; - if (button_id === BUTTON_ID && click_type === SINGLE_CLICK) { - moveCarousel(-1); - } - - // Reset carousel to proper position - carousel.style.transform = `translateX(${-100 * currentPlayerIndex}%)`; - renderPlayers(); - saveData(); -}); - function moveCarousel(diff) { const previousIndex = currentPlayerIndex; @@ -534,6 +515,83 @@ function findNextPlayerWithTimeCircular(startIndex, direction) { return -1; // No player has time left } +function handleFlicAction(action, buttonId) { + console.log(`[App] Received Flic Action: ${action} from Button: ${buttonId}`); + + // --- Trigger your PWA action based on the 'action' string --- + switch (action) { + case 'SingleClick': + console.log('[App] Single click action...'); + handleSingleClickLogic(buttonId); + break; + + case 'DoubleClick': + console.log('[App] Simulating double click action...'); + const elementForDoubleClick = document.getElementById('myDoubleClickTarget'); + if (elementForDoubleClick) { + // You might need a specific function, double clicks are harder to simulate directly + handleDoubleClickLogic(); + } else { + console.warn('[App] Element #myDoubleClickTarget not found.'); + } + break; + + case 'Hold': + console.log('[App] Simulating hold action...'); + // Example: Call a function associated with holding + handleHoldLogic(); + break; + + default: + console.warn(`[App] Unknown Flic action received: ${action}`); + } +} + +// --- Listener for messages from the Service Worker --- +if ('serviceWorker' in navigator) { + navigator.serviceWorker.addEventListener('message', event => { + console.log('[App] Message received from Service Worker:', event.data); + + // Check if the message is the one we expect + if (event.data && event.data.type === 'flic-action') { + const { action, button } = event.data; + handleFlicAction(action, button); + } + // Add else if blocks here for other message types if needed + }); + +// Optional: Send a message TO the service worker if needed +// navigator.serviceWorker.ready.then(registration => { +// registration.active.postMessage({ type: 'client-ready' }); +// }); +} + +function handleSingleClickLogic(buttonId) { + console.log(`Single Click Logic Executed from Button: ${buttonId}`); + if (!isDragging) return; + + isDragging = false; + + if (buttonId === BUTTON_ID) { + moveCarousel(-1); + } + + // Reset carousel to proper position + carousel.style.transform = `translateX(${-100 * currentPlayerIndex}%)`; + renderPlayers(); + saveData(); +} + +function handleDoubleClickLogic() { + console.log("Double Click Logic Executed!"); + // Update UI, trigger different game action, etc. +} + +function handleHoldLogic() { + console.log("Hold Logic Executed!"); + // Update UI, show a menu, etc. +} + // Setup button setupButton.addEventListener('click', () => { audioManager.play('buttonClick'); diff --git a/sw.js b/sw.js index 86980dd..0adeb5d 100644 --- a/sw.js +++ b/sw.js @@ -151,18 +151,95 @@ self.addEventListener('message', event => { self.addEventListener('push', event => { console.log('[ServiceWorker] Push received'); - // const data = event.data ? event.data.json() : {}; - // const title = data.title || 'Game Timer Notification'; - // const options = { - // body: data.body || 'You have a new notification', - // icon: '/icons/android-chrome-192x192.png', - // badge: '/icons/android-chrome-192x192.png', - // data: data - // }; + let pushData = { + title: 'Flic Action', + body: 'Button pressed!', + data: { action: 'Unknown', button: 'Unknown' } // Default data + }; - // event.waitUntil( - // self.registration.showNotification(title, options) - // ); + // --- Attempt to parse data payload --- + if (event.data) { + try { + const parsedData = event.data.json(); + console.log('[ServiceWorker] Push data:', parsedData); + + // Use parsed data for notification and message + pushData = { + title: parsedData.title || pushData.title, + body: parsedData.body || pushData.body, + // IMPORTANT: Extract the action details sent from your backend + data: parsedData.data || pushData.data // Expecting { action: 'SingleClick', button: '...' } + }; + + } catch (e) { + console.error('[ServiceWorker] Error parsing push data:', e); + // Use default notification if parsing fails + pushData.body = event.data.text() || pushData.body; // Fallback to text + } + } else { + console.log('[ServiceWorker] Push event but no data'); + } + + // --- Send message to client(s) --- + const messagePayload = { + type: 'flic-action', // Custom message type + action: pushData.data.action, // e.g., 'SingleClick', 'DoubleClick', 'Hold' + button: pushData.data.button // e.g., the button serial + }; + + // Send message to all open PWA windows controlled by this SW + event.waitUntil( + self.clients.matchAll({ + type: 'window', // Only target window clients + includeUncontrolled: true // Include clients that might not be fully controlled yet + }).then(clientList => { + if (!clientList || clientList.length === 0) { + console.log('[ServiceWorker] No client windows found to send message to.'); + // If no window is open, we MUST show a notification + return self.registration.showNotification(pushData.title, { + body: pushData.body, + icon: '/icons/icon-192x192.png', // Optional: path to an icon + data: pushData.data // Pass data if needed when notification is clicked + }); + } + + // Post message to each client + let messageSent = false; + clientList.forEach(client => { + console.log(`[ServiceWorker] Posting message to client: ${client.id}`, messagePayload); + client.postMessage(messagePayload); + messageSent = true; // Mark that we at least tried to send a message + }); + + // Decide whether to still show a notification even if a window is open. + // Generally good practice unless you are SURE the app will handle it visibly. + // You might choose *not* to show a notification if a client was found and focused. + // For simplicity here, we'll still show one. Adjust as needed. + if (!messageSent) { // Only show notification if no message was sent? Or always show? + return self.registration.showNotification(pushData.title, { + body: pushData.body, + icon: '/icons/icon-192x192.png', + data: pushData.data + }); + } + }) + ); + + // --- Show a notification (Important!) --- + // Push notifications generally REQUIRE showing a notification to the user + // unless the PWA is already in the foreground AND handles the event visually. + // It's safer to always show one unless you have complex foreground detection. + /* This part is now handled inside the clients.matchAll promise */ + /* + const notificationOptions = { + body: pushData.body, + icon: '/icons/icon-192x192.png', // Optional: path to an icon + data: pushData.data // Attach data if needed when notification is clicked + }; + event.waitUntil( + self.registration.showNotification(pushData.title, notificationOptions) + ); + */ }); // This helps with navigation after app is installed