added more button actions
This commit is contained in:
142
app.js
142
app.js
@@ -12,7 +12,7 @@ let currentX = 0;
|
|||||||
let pushSubscription = null;
|
let pushSubscription = null;
|
||||||
const PUBLIC_VAPID_KEY = 'BKfRJXjSQmAJ452gLwlK_8scGrW6qMU1mBRp39ONtcQHkSsQgmLAaODIyGbgHyRpnDEv3HfXV1oGh3SC0fHxY0E';
|
const PUBLIC_VAPID_KEY = 'BKfRJXjSQmAJ452gLwlK_8scGrW6qMU1mBRp39ONtcQHkSsQgmLAaODIyGbgHyRpnDEv3HfXV1oGh3SC0fHxY0E';
|
||||||
const BACKEND_URL = 'https://webpush.virtonline.eu';
|
const BACKEND_URL = 'https://webpush.virtonline.eu';
|
||||||
const BUTTON_ID = 'your_button1_serial';
|
const BUTTON_ID = 'game-button';
|
||||||
const SINGLE_CLICK = 'SingleClick';
|
const SINGLE_CLICK = 'SingleClick';
|
||||||
|
|
||||||
// DOM Elements
|
// DOM Elements
|
||||||
@@ -42,6 +42,42 @@ const cameraCancelButton = document.getElementById('cameraCancelButton');
|
|||||||
|
|
||||||
let stream = null;
|
let stream = null;
|
||||||
|
|
||||||
|
// Get stored basic auth credentials or prompt user for them
|
||||||
|
function getBasicAuthCredentials() {
|
||||||
|
// Try to get stored credentials from localStorage
|
||||||
|
const storedAuth = localStorage.getItem('basicAuthCredentials');
|
||||||
|
if (storedAuth) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(storedAuth);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to parse stored credentials:', error);
|
||||||
|
// Fall through to prompt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no stored credentials, prompt the user
|
||||||
|
const username = prompt('Please enter your username for authentication:');
|
||||||
|
if (!username) return null;
|
||||||
|
|
||||||
|
const password = prompt('Please enter your password:');
|
||||||
|
if (!password) return null;
|
||||||
|
|
||||||
|
// Store the credentials for future use
|
||||||
|
const credentials = { username, password };
|
||||||
|
localStorage.setItem('basicAuthCredentials', JSON.stringify(credentials));
|
||||||
|
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Basic Auth header
|
||||||
|
function createBasicAuthHeader(credentials) {
|
||||||
|
if (!credentials || !credentials.username || !credentials.password) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'Basic ' + btoa(`${credentials.username}:${credentials.password}`);
|
||||||
|
}
|
||||||
|
|
||||||
async function subscribeToPushNotifications() {
|
async function subscribeToPushNotifications() {
|
||||||
let buttonId = BUTTON_ID;
|
let buttonId = BUTTON_ID;
|
||||||
// 1. Validate input buttonId
|
// 1. Validate input buttonId
|
||||||
@@ -125,15 +161,33 @@ async function subscribeToPushNotifications() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Sending subscription for button "${buttonId}" to backend...`);
|
console.log(`Sending subscription for button "${buttonId}" to backend...`);
|
||||||
|
|
||||||
|
// Get basic auth credentials
|
||||||
|
const credentials = getBasicAuthCredentials();
|
||||||
|
if (!credentials) {
|
||||||
|
console.error('Authentication credentials are required.');
|
||||||
|
alert('Authentication failed. Please try again with valid credentials.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create headers with auth
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add Authorization header with Basic Auth if credentials are available
|
||||||
|
const authHeader = createBasicAuthHeader(credentials);
|
||||||
|
if (authHeader) {
|
||||||
|
headers['Authorization'] = authHeader;
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch(`${BACKEND_URL}/subscribe`, {
|
const response = await fetch(`${BACKEND_URL}/subscribe`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
button_id: buttonId,
|
button_id: buttonId,
|
||||||
subscription: finalSubscription
|
subscription: finalSubscription
|
||||||
}),
|
}),
|
||||||
headers: {
|
headers: headers
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 9. Handle the server response
|
// 9. Handle the server response
|
||||||
@@ -142,6 +196,13 @@ async function subscribeToPushNotifications() {
|
|||||||
console.log('Push subscription successfully sent to server:', result.message);
|
console.log('Push subscription successfully sent to server:', result.message);
|
||||||
} else {
|
} else {
|
||||||
let errorMessage = `Server error: ${response.status}`;
|
let errorMessage = `Server error: ${response.status}`;
|
||||||
|
|
||||||
|
// If it's an auth error, clear stored credentials and try again
|
||||||
|
if (response.status === 401 || response.status === 403) {
|
||||||
|
localStorage.removeItem('basicAuthCredentials');
|
||||||
|
errorMessage = 'Authentication failed. Please try again with valid credentials.';
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const errorResult = await response.json();
|
const errorResult = await response.json();
|
||||||
errorMessage = errorResult.message || errorMessage;
|
errorMessage = errorResult.message || errorMessage;
|
||||||
@@ -515,30 +576,23 @@ function findNextPlayerWithTimeCircular(startIndex, direction) {
|
|||||||
return -1; // No player has time left
|
return -1; // No player has time left
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFlicAction(action, buttonId) {
|
function handleFlicAction(action, buttonId, timestamp) {
|
||||||
console.log(`[App] Received Flic Action: ${action} from Button: ${buttonId}`);
|
console.log(`[App] Received Flic Action: ${action} from Button: ${buttonId} at Timestamp: ${timestamp}`);
|
||||||
|
|
||||||
// --- Trigger your PWA action based on the 'action' string ---
|
// --- Trigger your PWA action based on the 'action' string ---
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'SingleClick':
|
case 'SingleClick':
|
||||||
console.log('[App] Single click action...');
|
console.log('[App] Remotely triggered single click action...');
|
||||||
handleSingleClickLogic(buttonId);
|
handleSingleClickLogic(buttonId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'DoubleClick':
|
case 'DoubleClick':
|
||||||
console.log('[App] Simulating double click action...');
|
console.log('[App] Remotely triggered double click action...');
|
||||||
const elementForDoubleClick = document.getElementById('myDoubleClickTarget');
|
handleDoubleClickLogic();
|
||||||
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;
|
break;
|
||||||
|
|
||||||
case 'Hold':
|
case 'Hold':
|
||||||
console.log('[App] Simulating hold action...');
|
console.log('[App] Remotely triggered hold action...');
|
||||||
// Example: Call a function associated with holding
|
|
||||||
handleHoldLogic();
|
handleHoldLogic();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -554,8 +608,8 @@ if ('serviceWorker' in navigator) {
|
|||||||
|
|
||||||
// Check if the message is the one we expect
|
// Check if the message is the one we expect
|
||||||
if (event.data && event.data.type === 'flic-action') {
|
if (event.data && event.data.type === 'flic-action') {
|
||||||
const { action, button } = event.data;
|
const { action, button, timestamp } = event.data;
|
||||||
handleFlicAction(action, button);
|
handleFlicAction(action, button, timestamp);
|
||||||
}
|
}
|
||||||
// Add else if blocks here for other message types if needed
|
// Add else if blocks here for other message types if needed
|
||||||
});
|
});
|
||||||
@@ -570,7 +624,7 @@ function handleSingleClickLogic(buttonId) {
|
|||||||
console.log(`Single Click Logic Executed from Button: ${buttonId}`);
|
console.log(`Single Click Logic Executed from Button: ${buttonId}`);
|
||||||
|
|
||||||
if (buttonId === BUTTON_ID) {
|
if (buttonId === BUTTON_ID) {
|
||||||
moveCarousel(-1);
|
moveCarousel(-1); // Move to next player
|
||||||
}
|
}
|
||||||
// Reset carousel to proper position
|
// Reset carousel to proper position
|
||||||
carousel.style.transform = `translateX(${-100 * currentPlayerIndex}%)`;
|
carousel.style.transform = `translateX(${-100 * currentPlayerIndex}%)`;
|
||||||
@@ -580,12 +634,56 @@ function handleSingleClickLogic(buttonId) {
|
|||||||
|
|
||||||
function handleDoubleClickLogic() {
|
function handleDoubleClickLogic() {
|
||||||
console.log("Double Click Logic Executed!");
|
console.log("Double Click Logic Executed!");
|
||||||
// Update UI, trigger different game action, etc.
|
|
||||||
|
if (buttonId === BUTTON_ID) {
|
||||||
|
moveCarousel(1); // Move to previous player
|
||||||
|
}
|
||||||
|
// Reset carousel to proper position
|
||||||
|
carousel.style.transform = `translateX(${-100 * currentPlayerIndex}%)`;
|
||||||
|
renderPlayers();
|
||||||
|
saveData();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleHoldLogic() {
|
function handleHoldLogic() {
|
||||||
console.log("Hold Logic Executed!");
|
console.log("Hold Logic Executed!");
|
||||||
// Update UI, show a menu, etc.
|
// Implement game pause/resume toggle
|
||||||
|
if (players.length < 2) {
|
||||||
|
console.log('Need at least 2 players to toggle game state.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle between running and paused states
|
||||||
|
switch (gameState) {
|
||||||
|
case 'setup':
|
||||||
|
// Start the game if in setup
|
||||||
|
gameState = 'running';
|
||||||
|
audioManager.play('gameStart');
|
||||||
|
startTimer();
|
||||||
|
break;
|
||||||
|
case 'running':
|
||||||
|
// Pause the game if running
|
||||||
|
gameState = 'paused';
|
||||||
|
audioManager.play('gamePause');
|
||||||
|
stopTimer();
|
||||||
|
break;
|
||||||
|
case 'paused':
|
||||||
|
// Resume the game if paused
|
||||||
|
gameState = 'running';
|
||||||
|
audioManager.play('gameResume');
|
||||||
|
startTimer();
|
||||||
|
break;
|
||||||
|
case 'over':
|
||||||
|
// Reset timers and start new game if game is over
|
||||||
|
players.forEach(player => {
|
||||||
|
player.remainingTime = player.timeInSeconds;
|
||||||
|
});
|
||||||
|
gameState = 'setup';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGameButton();
|
||||||
|
renderPlayers(); // Make sure to re-render after state change
|
||||||
|
saveData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup button
|
// Setup button
|
||||||
|
|||||||
3
sw.js
3
sw.js
@@ -184,7 +184,8 @@ self.addEventListener('push', event => {
|
|||||||
const messagePayload = {
|
const messagePayload = {
|
||||||
type: 'flic-action', // Custom message type
|
type: 'flic-action', // Custom message type
|
||||||
action: pushData.data.action, // e.g., 'SingleClick', 'DoubleClick', 'Hold'
|
action: pushData.data.action, // e.g., 'SingleClick', 'DoubleClick', 'Hold'
|
||||||
button: pushData.data.button // e.g., the button serial
|
button: pushData.data.button, // e.g., the button name
|
||||||
|
timestamp: pushData.data.timestamp // e.g., the timestamp of the action
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send message to all open PWA windows controlled by this SW
|
// Send message to all open PWA windows controlled by this SW
|
||||||
|
|||||||
Reference in New Issue
Block a user