handle all button types
This commit is contained in:
96
app.js
96
app.js
@@ -469,25 +469,6 @@ carousel.addEventListener('touchend', (e) => {
|
|||||||
saveData();
|
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) {
|
function moveCarousel(diff) {
|
||||||
const previousIndex = currentPlayerIndex;
|
const previousIndex = currentPlayerIndex;
|
||||||
|
|
||||||
@@ -534,6 +515,83 @@ function findNextPlayerWithTimeCircular(startIndex, direction) {
|
|||||||
return -1; // No player has time left
|
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
|
// Setup button
|
||||||
setupButton.addEventListener('click', () => {
|
setupButton.addEventListener('click', () => {
|
||||||
audioManager.play('buttonClick');
|
audioManager.play('buttonClick');
|
||||||
|
|||||||
99
sw.js
99
sw.js
@@ -151,18 +151,95 @@ self.addEventListener('message', event => {
|
|||||||
self.addEventListener('push', event => {
|
self.addEventListener('push', event => {
|
||||||
console.log('[ServiceWorker] Push received');
|
console.log('[ServiceWorker] Push received');
|
||||||
|
|
||||||
// const data = event.data ? event.data.json() : {};
|
let pushData = {
|
||||||
// const title = data.title || 'Game Timer Notification';
|
title: 'Flic Action',
|
||||||
// const options = {
|
body: 'Button pressed!',
|
||||||
// body: data.body || 'You have a new notification',
|
data: { action: 'Unknown', button: 'Unknown' } // Default data
|
||||||
// icon: '/icons/android-chrome-192x192.png',
|
};
|
||||||
// badge: '/icons/android-chrome-192x192.png',
|
|
||||||
// data: data
|
|
||||||
// };
|
|
||||||
|
|
||||||
// event.waitUntil(
|
// --- Attempt to parse data payload ---
|
||||||
// self.registration.showNotification(title, options)
|
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
|
// This helps with navigation after app is installed
|
||||||
|
|||||||
Reference in New Issue
Block a user