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;
|
||||
const PUBLIC_VAPID_KEY = 'BKfRJXjSQmAJ452gLwlK_8scGrW6qMU1mBRp39ONtcQHkSsQgmLAaODIyGbgHyRpnDEv3HfXV1oGh3SC0fHxY0E';
|
||||
const BACKEND_URL = 'https://webpush.virtonline.eu';
|
||||
const BUTTON_ID = 'your_button1_serial';
|
||||
const BUTTON_ID = 'game-button';
|
||||
const SINGLE_CLICK = 'SingleClick';
|
||||
|
||||
// DOM Elements
|
||||
@@ -42,6 +42,42 @@ const cameraCancelButton = document.getElementById('cameraCancelButton');
|
||||
|
||||
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() {
|
||||
let buttonId = BUTTON_ID;
|
||||
// 1. Validate input buttonId
|
||||
@@ -125,15 +161,33 @@ async function subscribeToPushNotifications() {
|
||||
}
|
||||
|
||||
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`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
button_id: buttonId,
|
||||
subscription: finalSubscription
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
headers: headers
|
||||
});
|
||||
|
||||
// 9. Handle the server response
|
||||
@@ -142,6 +196,13 @@ async function subscribeToPushNotifications() {
|
||||
console.log('Push subscription successfully sent to server:', result.message);
|
||||
} else {
|
||||
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 {
|
||||
const errorResult = await response.json();
|
||||
errorMessage = errorResult.message || errorMessage;
|
||||
@@ -515,30 +576,23 @@ 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}`);
|
||||
function handleFlicAction(action, buttonId, timestamp) {
|
||||
console.log(`[App] Received Flic Action: ${action} from Button: ${buttonId} at Timestamp: ${timestamp}`);
|
||||
|
||||
// --- Trigger your PWA action based on the 'action' string ---
|
||||
switch (action) {
|
||||
case 'SingleClick':
|
||||
console.log('[App] Single click action...');
|
||||
console.log('[App] Remotely triggered 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.');
|
||||
}
|
||||
console.log('[App] Remotely triggered double click action...');
|
||||
handleDoubleClickLogic();
|
||||
break;
|
||||
|
||||
case 'Hold':
|
||||
console.log('[App] Simulating hold action...');
|
||||
// Example: Call a function associated with holding
|
||||
console.log('[App] Remotely triggered hold action...');
|
||||
handleHoldLogic();
|
||||
break;
|
||||
|
||||
@@ -554,8 +608,8 @@ if ('serviceWorker' in navigator) {
|
||||
|
||||
// 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);
|
||||
const { action, button, timestamp } = event.data;
|
||||
handleFlicAction(action, button, timestamp);
|
||||
}
|
||||
// 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}`);
|
||||
|
||||
if (buttonId === BUTTON_ID) {
|
||||
moveCarousel(-1);
|
||||
moveCarousel(-1); // Move to next player
|
||||
}
|
||||
// Reset carousel to proper position
|
||||
carousel.style.transform = `translateX(${-100 * currentPlayerIndex}%)`;
|
||||
@@ -580,12 +634,56 @@ function handleSingleClickLogic(buttonId) {
|
||||
|
||||
function handleDoubleClickLogic() {
|
||||
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() {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user