From f65e99c8fb1552aedcfdef59df495602c47df598 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Nov 2025 16:29:35 +0000 Subject: [PATCH 1/2] Version 0.9.1-2: Fix npm installation and pause button behavior Critical Fixes: - FIXED: npm installation verification added * Now explicitly checks if npm is installed after nodejs * Falls back to installing npm separately if missing * Displays npm version after installation * Prevents "npm: command not found" error during Electron install - FIXED: Pause button now appears only on user interaction * Hidden by default (display:none) * Shows on mousedown/touchstart/keydown events * Similar behavior to keyboard icon * Throttled to check every 5 seconds * Better UX - less visual clutter - FIXED: Pause button hidden on manual sites (duration=0) * Main process checks site duration when visibility requested * Sends pause-button-visibility message to views * attachView() function controls visibility on tab switch * Prevents confusion on sites where return-to-home popup appears Implementation: - Added 'request-pause-button-visibility' IPC message - Main process responds with 'pause-button-visibility' based on duration - Pause button automatically hidden/shown when switching tabs - User interaction triggers visibility check --- install_kiosk_0.9.1.sh | 92 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 10 deletions(-) diff --git a/install_kiosk_0.9.1.sh b/install_kiosk_0.9.1.sh index 4d7babd..64f3e16 100644 --- a/install_kiosk_0.9.1.sh +++ b/install_kiosk_0.9.1.sh @@ -3280,7 +3280,15 @@ first_time_install() { curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install -y nodejs fi + + # Verify npm is installed + if ! command -v npm &>/dev/null; then + echo "⚠ npm not found, attempting to install..." + sudo apt install -y npm + fi + echo "Node.js: $(node -v)" + echo "npm: $(npm -v)" echo "[7-10/27] Core configuration..." configure_touch_controls @@ -3706,25 +3714,30 @@ function rotateToNextSite(){ function attachView(i){ closeHTMLKeyboard(); - + if(!mainWindow||!views[i]||showingHidden)return; - + currentIndex=i; mainWindow.setTopBrowserView(views[i]); const[w,h]=mainWindow.getContentSize(); views[i].setBounds({x:0,y:0,width:w,height:h}); - + const tabIdx=viewIndexToTabIndex(i); if(tabIdx>=0&&tabs[tabIdx]){ const configuredUrl=tabs[tabIdx].url; const currentUrl=views[i].webContents.getURL(); - + if(currentUrl&&!currentUrl.startsWith(configuredUrl)){ programmaticNavigation=true; views[i].webContents.loadURL(configuredUrl); } + + // Control pause button visibility based on site duration + const siteDuration=parseInt(tabs[tabIdx].duration)||0; + const shouldShow=siteDuration!==0; // Hide on manual sites (duration=0) + views[i].webContents.send('pause-button-visibility',shouldShow); } - + views[i].webContents.focus(); siteStartTime=Date.now(); } @@ -4219,6 +4232,27 @@ function createWindow(){ ipcMain.on('close-keyboard',()=>{closeHTMLKeyboard();}); ipcMain.on('keyboard-activity',()=>{markKeyboardActivity();}); ipcMain.on('show-pause-dialog',()=>{showPauseDialog();}); + + // Handle pause button visibility request + ipcMain.on('request-pause-button-visibility',()=>{ + const currentTabIdx=viewIndexToTabIndex(currentIndex); + let shouldShow=true; + + if(currentTabIdx>=0&&tabs[currentTabIdx]){ + const siteDuration=parseInt(tabs[currentTabIdx].duration)||0; + // Hide pause button on manual sites (duration=0) + if(siteDuration===0){ + shouldShow=false; + } + } + + // Send visibility state to all views + views.forEach(v=>{ + if(v&&v.webContents){ + v.webContents.send('pause-button-visibility',shouldShow); + } + }); + }); ipcMain.on('keyboard-type',(event,key)=>{ markKeyboardActivity(); @@ -5125,6 +5159,7 @@ window.addEventListener('DOMContentLoaded',()=>{ // Pause button functionality let pauseButton=null; + let pauseButtonVisible=false; function createPauseButton(){ if(pauseButton)return; @@ -5136,7 +5171,7 @@ window.addEventListener('DOMContentLoaded',()=>{ pauseButton.style.cssText=` position:fixed;bottom:20px;left:20px;width:60px;height:60px; background:rgba(230,126,34,0.95);border:3px solid rgba(255,255,255,0.9); - border-radius:50%;display:flex;align-items:center;justify-content:center; + border-radius:50%;display:none;align-items:center;justify-content:center; font-size:32px;cursor:pointer;z-index:999999; box-shadow:0 4px 12px rgba(0,0,0,0.4);user-select:none; `; @@ -5150,10 +5185,47 @@ window.addEventListener('DOMContentLoaded',()=>{ document.body.appendChild(pauseButton); } - // Create pause button on page load - setTimeout(()=>{ - createPauseButton(); - },1000); + function showPauseButton(){ + if(!pauseButton)createPauseButton(); + pauseButton.style.display='flex'; + pauseButtonVisible=true; + } + + function hidePauseButton(){ + if(pauseButton){ + pauseButton.style.display='none'; + pauseButtonVisible=false; + } + } + + // Listen for pause button visibility control from main process + ipcRenderer.on('pause-button-visibility',(event,visible)=>{ + if(visible){ + showPauseButton(); + }else{ + hidePauseButton(); + } + }); + + // Show pause button on user interaction (but not on manual sites) + let lastPauseButtonCheck=0; + const PAUSE_BUTTON_THROTTLE=5000; + + function checkAndShowPauseButton(){ + const now=Date.now(); + if(now-lastPauseButtonCheck>PAUSE_BUTTON_THROTTLE){ + lastPauseButtonCheck=now; + ipcRenderer.send('request-pause-button-visibility'); + } + } + + // Show pause button on any user interaction + const pauseButtonTriggers=['mousedown','touchstart','keydown']; + pauseButtonTriggers.forEach(eventType=>{ + document.addEventListener(eventType,()=>{ + checkAndShowPauseButton(); + },{passive:true,capture:true}); + }); function isTextInput(el){ if(!el)return false; From 1521b7e54f8b3cf7609c164b756317ade220bbbe Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Nov 2025 17:22:28 +0000 Subject: [PATCH 2/2] Version 0.9.1-2: Critical fixes for pause button and Electron update Major Fixes: 1. FIXED: Pause button visibility logic completely rewritten - Pause button now properly hidden on duration=0 sites - Shows ONLY on user interaction (mousedown/touchstart/keydown) - Main process sends pause-button-visibility on tab switch - Preload receives visibility state and enforces it - Button hidden immediately when switching to manual sites 2. FIXED: Pause dialog window conflict resolved - Created separate pauseWindow variable (was reusing promptWindow) - Pause dialog no longer disappears immediately - Prevents conflicts with inactivity prompt window - Each dialog has its own window lifecycle 3. FIXED: Mixed header characters now uniform - All =--- and =-- patterns replaced with --- - Consistent use of dashes throughout script - Better terminal display compatibility 4. FIXED: Manual Electron update detection improved - Three-method detection strategy: * Method 1: Check /home/kiosk/kiosk-app * Method 2: Search all /home/*/kiosk-app with main.js verification * Method 3: Check current directory for kiosk-app - Added debug output showing search paths and current context - More robust detection across different installation scenarios Implementation Details: - pauseButtonShouldShow tracks if button is allowed on current site - pauseButtonShown tracks if button is currently displayed - User interaction only shows button if pauseButtonShouldShow is true - attachView() sends visibility message on every tab switch - Throttled user interaction handling (100ms) prevents spam --- install_kiosk_0.9.1.sh | 122 +++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 59 deletions(-) diff --git a/install_kiosk_0.9.1.sh b/install_kiosk_0.9.1.sh index 64f3e16..f370597 100644 --- a/install_kiosk_0.9.1.sh +++ b/install_kiosk_0.9.1.sh @@ -473,7 +473,7 @@ show_system_status() { } show_addon_status() { - echo " =-- INSTALLED ADDONS --=" + echo " --- INSTALLED ADDONS ---" echo local any_addon=false @@ -3321,7 +3321,7 @@ const CONFIG_FILE=path.join(__dirname,'config.json'); const VERSION='0.9.1-2'; let mainWindow,views=[],hiddenViews=[],tabs=[],currentIndex=0,showingHidden=false; -let pinWindow=null,promptWindow=null,htmlKeyboardWindow=null; +let pinWindow=null,promptWindow=null,pauseWindow=null,htmlKeyboardWindow=null; let tabIndexToViewIndex=[]; let currentHiddenIndex=0; @@ -3544,10 +3544,10 @@ function startMasterTimer(){ clearInterval(masterTimer); } - console.log('[TIMER] =--- MASTER TIMER STARTED ---=='); + console.log('[TIMER] --- MASTER TIMER STARTED ---'); console.log('[TIMER] Home tab index:',homeTabIndex); console.log('[TIMER] Inactivity timeout:',inactivityTimeout/1000,'seconds'); - console.log('[TIMER] =-----------------------------------='); + console.log('[TIMER] -----------------------------------'); siteStartTime=Date.now(); lastUserInteraction=Date.now(); @@ -3849,9 +3849,9 @@ function showInactivityPrompt(){ } function showPauseDialog(){ - if(promptWindow&&!promptWindow.isDestroyed())return; + if(pauseWindow&&!pauseWindow.isDestroyed())return; - promptWindow=new BrowserWindow({ + pauseWindow=new BrowserWindow({ width:800, height:600, frame:false, @@ -3861,17 +3861,17 @@ function showPauseDialog(){ webPreferences:{nodeIntegration:true,contextIsolation:false} }); - promptWindow.loadFile(path.join(__dirname,'pause-dialog.html')); + pauseWindow.loadFile(path.join(__dirname,'pause-dialog.html')); - promptWindow.on('closed',()=>{ - promptWindow=null; + pauseWindow.on('closed',()=>{ + pauseWindow=null; }); ipcMain.once('pause-time-selected',(event,minutes)=>{ - if(promptWindow&&!promptWindow.isDestroyed()){ - promptWindow.close(); + if(pauseWindow&&!pauseWindow.isDestroyed()){ + pauseWindow.close(); } - promptWindow=null; + pauseWindow=null; if(minutes===0){ // Cancel - do nothing @@ -4232,27 +4232,6 @@ function createWindow(){ ipcMain.on('close-keyboard',()=>{closeHTMLKeyboard();}); ipcMain.on('keyboard-activity',()=>{markKeyboardActivity();}); ipcMain.on('show-pause-dialog',()=>{showPauseDialog();}); - - // Handle pause button visibility request - ipcMain.on('request-pause-button-visibility',()=>{ - const currentTabIdx=viewIndexToTabIndex(currentIndex); - let shouldShow=true; - - if(currentTabIdx>=0&&tabs[currentTabIdx]){ - const siteDuration=parseInt(tabs[currentTabIdx].duration)||0; - // Hide pause button on manual sites (duration=0) - if(siteDuration===0){ - shouldShow=false; - } - } - - // Send visibility state to all views - views.forEach(v=>{ - if(v&&v.webContents){ - v.webContents.send('pause-button-visibility',shouldShow); - } - }); - }); ipcMain.on('keyboard-type',(event,key)=>{ markKeyboardActivity(); @@ -5159,7 +5138,8 @@ window.addEventListener('DOMContentLoaded',()=>{ // Pause button functionality let pauseButton=null; - let pauseButtonVisible=false; + let pauseButtonShouldShow=false; + let pauseButtonShown=false; function createPauseButton(){ if(pauseButton)return; @@ -5188,43 +5168,46 @@ window.addEventListener('DOMContentLoaded',()=>{ function showPauseButton(){ if(!pauseButton)createPauseButton(); pauseButton.style.display='flex'; - pauseButtonVisible=true; + pauseButtonShown=true; } function hidePauseButton(){ if(pauseButton){ pauseButton.style.display='none'; - pauseButtonVisible=false; + pauseButtonShown=false; } } // Listen for pause button visibility control from main process - ipcRenderer.on('pause-button-visibility',(event,visible)=>{ - if(visible){ - showPauseButton(); - }else{ + // Main process controls whether button should be available on this site + ipcRenderer.on('pause-button-visibility',(event,shouldShow)=>{ + pauseButtonShouldShow=shouldShow; + if(!shouldShow){ + // If button should not show on this site, hide it immediately hidePauseButton(); } + // If shouldShow is true, button will appear on user interaction }); - // Show pause button on user interaction (but not on manual sites) - let lastPauseButtonCheck=0; - const PAUSE_BUTTON_THROTTLE=5000; + // Show pause button on user interaction (only if allowed on this site) + let lastUserInteraction=0; + const USER_INTERACTION_THROTTLE=100; - function checkAndShowPauseButton(){ + function handleUserInteraction(){ const now=Date.now(); - if(now-lastPauseButtonCheck>PAUSE_BUTTON_THROTTLE){ - lastPauseButtonCheck=now; - ipcRenderer.send('request-pause-button-visibility'); + if(now-lastUserInteraction{ - document.addEventListener(eventType,()=>{ - checkAndShowPauseButton(); - },{passive:true,capture:true}); + document.addEventListener(eventType,handleUserInteraction,{passive:true,capture:true}); }); function isTextInput(el){ @@ -8266,14 +8249,21 @@ manual_electron_update() { local DETECTED_KIOSK_USER="" local DETECTED_KIOSK_DIR="" - # Check if kiosk user exists - if id "$KIOSK_USER" &>/dev/null 2>&1; then - DETECTED_KIOSK_USER="$KIOSK_USER" - DETECTED_KIOSK_DIR="$(eval echo ~$KIOSK_USER)/kiosk-app" - else - # Try to find any user with kiosk-app directory + echo "Searching for kiosk installation..." + + # Method 1: Check if default kiosk user exists and has kiosk-app + if id "$KIOSK_USER" &>/dev/null; then + local kiosk_home=$(eval echo ~$KIOSK_USER) + if [ -d "$kiosk_home/kiosk-app" ]; then + DETECTED_KIOSK_USER="$KIOSK_USER" + DETECTED_KIOSK_DIR="$kiosk_home/kiosk-app" + fi + fi + + # Method 2: Search all /home directories for kiosk-app + if [ -z "$DETECTED_KIOSK_DIR" ]; then for user_home in /home/*; do - if [ -d "$user_home/kiosk-app" ]; then + if [ -d "$user_home/kiosk-app" ] && [ -f "$user_home/kiosk-app/main.js" ]; then DETECTED_KIOSK_USER=$(basename "$user_home") DETECTED_KIOSK_DIR="$user_home/kiosk-app" break @@ -8281,6 +8271,14 @@ manual_electron_update() { done fi + # Method 3: Check current directory + if [ -z "$DETECTED_KIOSK_DIR" ]; then + if [ -f "$PWD/kiosk-app/main.js" ]; then + DETECTED_KIOSK_USER=$(whoami) + DETECTED_KIOSK_DIR="$PWD/kiosk-app" + fi + fi + # Check if we found a kiosk installation if [ -z "$DETECTED_KIOSK_DIR" ] || [ ! -d "$DETECTED_KIOSK_DIR" ]; then echo "✗ Kiosk installation not found!" @@ -8288,6 +8286,12 @@ manual_electron_update() { echo "Searched locations:" echo " - /home/$KIOSK_USER/kiosk-app" echo " - /home/*/kiosk-app" + echo " - $PWD/kiosk-app" + echo "" + echo "Debug info:" + echo " Current user: $(whoami)" + echo " Current directory: $PWD" + echo " Kiosk user exists: $(id "$KIOSK_USER" &>/dev/null && echo 'yes' || echo 'no')" echo "" echo "Please install the kiosk first (Main Menu > Install Kiosk)" pause @@ -8616,7 +8620,7 @@ core_menu() { clear echo "------------------------------------------------------------" echo " CORE SETTINGS " - echo "=------------------------------------------------------------=" + echo "------------------------------------------------------------" echo show_current_config echo @@ -8829,7 +8833,7 @@ audio_diagnostics() { fix_squeezelite_audio() { clear - echo "=-- FIX SQUEEZELITE AUDIO --=" + echo "--- FIX SQUEEZELITE AUDIO ---" echo echo "This will attempt to fix Squeezelite audio issues by:"