Fixes two critical bugs reported by user:
1. Fixed inactivity popup appearing on home page without interaction
- markActivity() now only sets userInteractedWithCurrentSite when
resetLockoutTimer=true (actual user touches)
- System events (prompt responses, app initialization) no longer
trigger the interaction flag
- Home page won't show popup until user physically touches screen
- Resolves: "return to rotation popup appears before page rotates"
2. Fixed media playback black screen after couple minutes
- Improved rotation resume logic after media grace period
- Removed narrow 2-second time window (30-32s) that could be missed
- manualNavigationMode now reliably resets after media ends AND
user has been inactive for 60 seconds
- Rotation properly resumes when user walks away after media stops
- Resolves: "media playback stops with black screen, no rotation"
Expected behavior:
- Home page loads, no popup until user touches screen
- Sites rotate for full configured duration (10 seconds)
- Media plays, stops, 30s grace + 60s inactivity, then rotation resumes
- Time extensions (15 min) continue to work correctly
Fixes three critical bugs:
1. Fixed inactivity popup appearing on every rotated site
- userInteractedWithCurrentSite now resets when switching sites
- Each site independently tracks user interaction
- Popup only appears on sites user actually touched
2. Fixed rotation not resuming after "I'm still here" response
- Clicking "I'm still here" now sets manualNavigationMode=false
- Rotation resumes after user acknowledges prompt
3. Fixed rotation stuck after media playback ends
- After media grace period (30s), manualNavigationMode resets
- Prevents black screen when media stops
- Normal rotation automatically resumes
User-reported issue: Sites showing for full duration, no popup spam,
media playback properly returns to rotation.
This release clarifies the media playback behavior and fixes an incorrect
"smart grace period" implementation that violated the core principle.
Core Principle:
- Media playback TRUMPS everything (rotation and inactivity prompts)
- Media plays uninterrupted until: ends naturally, user pauses, session
lockout, or display schedule
- After media stops: 30-second grace period ALWAYS applies (no exceptions)
- After grace period: Normal inactivity and rotation rules resume
Changes:
- Restored simple grace period logic (always 30 seconds after media stops)
- Removed incorrect "smart" grace period that could skip the delay
- Added clarifying comments about media blocking behavior
- Documented that inactivity timeout is user-configurable (default 2 minutes)
The grace period ensures smooth transitions when media ends naturally,
preventing jarring interruptions with popups or rotation changes.
CRITICAL FIX: Manual swipes to 0-time pages now trigger inactivity prompts.
The problem:
- User swipes to a 0-time (manual) page but doesn't touch it
- userInteractedWithCurrentSite stays false
- No inactivity prompt ever appears
- Kiosk stuck on that page forever
The fix:
- Manual swipe now explicitly sets userInteractedWithCurrentSite=true
- Swipe counts as engagement with the new page
- After inactivity timeout, prompt appears even if user never touched page
- Ensures "Return to Rotation" mechanism works on ALL pages
Complete flow now works as designed:
1. Normal rotation with duration > 0 sites
2. User interacts with ANY site → rotation pauses
3. After 2min inactivity → prompt appears
- "Return to Rotation" → returns to home, resumes rotation
- "I'm still here" → waits another 2min, prompt again
- Time extension (5/15/30/60 min) → waits that long, prompt again
- No response (15 sec) → auto-returns to rotation
4. User swipes to new page → counts as interaction, rotation resumes
5. Media playing → blocks all rotation and prompts (30s grace period)
6. Display schedule → screen blanks, app keeps running
7. Password/lockout → takes precedence on boot/resume/timeout
Technical changes:
- Lines 4072-4075: Set userInteractedWithCurrentSite=true in nextTab()
- Lines 4097-4100: Set userInteractedWithCurrentSite=true in prevTab()
- Ensures inactivity logic works even on untouched 0-time pages
This completes the comprehensive rotation/inactivity system.
CRITICAL FIX: Manual swipes now properly resume rotation instead of keeping it paused.
The issue:
- User interacts with page A → rotation pauses
- User swipes to page B → rotation should resume, but was staying paused
- This was because manualNavigationMode stayed true
The fix:
- nextTab() and prevTab() now set manualNavigationMode=false AFTER markActivity
- This overrides the manualNavigationMode=true set by markActivity
- Manual swipes are navigation, not content interaction
- Rotation will now resume on the new page (if it has duration > 0)
Complete flow now:
1. User touches page → manualNavigationMode=true → rotation pauses
2. After 2min idle → prompt appears with options:
- "Return to Rotation" → manualNavigationMode=false → rotation resumes
- "I'm still here" → manualNavigationMode stays true → rotation stays paused
- Time extension → rotation paused during extension, prompt reappears when expires
- No response (15sec) → auto-returns to rotation
3. User swipes to new page → manualNavigationMode=false → rotation resumes
Technical changes:
- Lines 4054-4072: Reordered nextTab() to set manualNavigationMode=false AFTER markActivity
- Lines 4074-4092: Reordered prevTab() to set manualNavigationMode=false AFTER markActivity
- Time extensions still cleared on manual swipe (correct behavior)
This release fixes critical issues with rotation behavior and user interaction:
ROTATION LOGIC FIXES:
- Rotation now properly pauses when user interacts with any URL
- Added manualNavigationMode check to rotation logic
- User interaction (touch, scroll, type) sets manualNavigationMode=true
- "Return to Rotation" button resets manualNavigationMode=false
- Prevents unwanted auto-rotation when user is actively using content
USER INTERACTION IMPROVEMENTS:
- markActivity() now sets manualNavigationMode=true for actual user interaction
- Differentiates between content interaction and prompt responses
- Time extensions continue to be honored during user interaction
- Inactivity prompt closes when user interacts with content
EDGE CASE HANDLING:
- Fixed return to rotation when home URL exists but all URLs have 0 time
- Return to home URL still works even with no rotation configured
- Inactivity prompt properly fires on home URL in no-rotation scenario
PASSWORD/LOCKOUT PRECEDENCE:
- Verified password prompt blocks all interaction on boot
- Lockout properly blocks rotation and prompts
- System resume, screen lock trigger password protection correctly
Technical changes:
- Line 3913: Added !manualNavigationMode check to rotation condition
- Lines 3647-3651: Set manualNavigationMode on user content interaction
- Line 4086-4090: Enhanced returnToHome() documentation for no-rotation case
- Updated VERSION constants and release notes
All existing functionality preserved including:
- Time extensions honored
- Manual tab switching clears extensions
- Prompt only appears on interacted sites
- Password takes precedence on boot/resume/lockout
Password Protection Enhancements:
- Password prompt now appears on bootup if lockout enabled
- Password prompt on system suspend/resume (via powerMonitor)
- Password prompt on screen lock events
- Ensures kiosk is always protected when password feature is enabled
Critical Inactivity Popup Fix:
- Fixed popup not appearing on rotation sites (major UX bug)
- Auto-rotation now preserves userInteractedWithCurrentSite flag
- Added isAutoRotation parameter to attachView()
- Only resets interaction flag on manual navigation
- Inactivity check moved BEFORE rotation check
- Rotation pauses while inactivity prompt is displayed
Lockout Timer Independence:
- Lockout timer now uses lastLockoutCheck instead of lastUserInteraction
- Responding to inactivity prompts no longer resets lockout timer
- Added resetLockoutTimer parameter to markActivity()
- Only actual user interactions (touches, swipes, keyboard) reset lockout
- Ensures lockout fires even if user keeps responding to prompts
Other Fixes:
- Fixed script bailing on manual electron update (graceful error handling)
- Changed "Nuclear reinstall" to "Reinstall complete! System is fresh."
- Moved Session Lockout from Sites menu to Core Settings menu (option 7)
All markActivity() calls updated with proper resetLockoutTimer flags
Critical fix:
- Rotation now pauses completely when session is locked
- Previously rotation would continue running in background while lockout screen displayed
- This caused the lockout screen to disappear after ~1 minute when rotation occurred
- Added sessionLocked check to rotation logic (line 3888)
- Added sessionLocked check to inactivity prompt logic (line 3836)
- Password lockout screen now stays visible until correct password is entered
Major improvements:
- Moved Session Lockout configuration from Sites menu to Core Settings menu
- Now accessible as option 7 in Core Settings for easier access
- Removed from Sites menu to reduce clutter
- Fixed critical inactivity popup bug on rotation sites
- Popup now appears on ALL sites where user has interacted
- Previously only worked on manual (0-timed) sites
- Inactivity check now happens BEFORE rotation check
- Prevents sites from rotating away before popup can appear
- Rotation pauses while inactivity prompt is displayed
Version bump: v0.9.8 → v0.9.9
This commit addresses multiple user-reported issues:
1. UI Improvements:
- Replace box-drawing characters (╔ ╗) with simple equals signs (=)
- Updated addon status display header
- Updated timer logging format
- Updated Squeezelite audio fix header
2. Performance Optimization:
- Removed redundant systemctl calls from show_addon_status()
- Addon status now uses fast file-based checks only
- Eliminates slow service status queries that delayed menu display
3. Password Lock Feature Visibility:
- Added session lockout configuration to initial setup flow
- Users can now set password protection during first-time configuration
- Previously only available in edit menu after setup
4. Return to Rotation (RTR) Popup Fix:
- Fixed RTR popup not appearing on rotation sites
- Removed requirement for Home URL to be configured
- Inactivity prompt now works with or without Home URL
- When typing on rotation site, popup appears after inactivity timeout
- "Return to Rotation" works correctly in both configurations
Bug fixes ensure expected behavior across all use cases.
This update provides a unified, predictable inactivity prompt behavior
regardless of how the user navigated to a page.
Changes:
- Added userInteractedWithCurrentSite flag to track user touch on each site
- Modified markActivity() to set flag when user interacts (tap, swipe, scroll)
- Modified attachView() to clear flag when site changes
- Updated inactivity check to use interaction flag instead of navigation mode
New Behavior (Consistent UX):
✅ Scenario A: Auto-rotation to recipe → user taps → prompt after timeout
- Site auto-rotates to recipe page
- User taps screen to scroll/interact
- userInteractedWithCurrentSite = true
- After 2 min idle → prompt appears
- User can extend time or return to rotation
✅ Scenario B: User swiping through photos every 30 seconds
- Each swipe resets inactivity timer via markActivity()
- No prompt appears (user is actively interacting)
- Prompt only appears after they stop swiping for timeout period
✅ Scenario C: Sites auto-rotating with no user interaction
- userInteractedWithCurrentSite = false on each site
- No prompt appears
- Rotation continues normally
Technical Details:
- Single-finger swipes (in-page content): Reset timer via markActivity()
- Two-finger swipes (tab navigation): Also sets manualNavigationMode
- Both types of interaction trigger the flag
- Flag cleared on every site change (auto or manual)
- If manual swipe, markActivity() re-sets it immediately
Use Cases:
- Recipe viewing: User can interact with page, get timeout prompt, extend time
- Photo browsing: Continuous swiping prevents timeout
- Digital signage: No interaction = no prompt = smooth rotation
- MagicMirror modules: Single-finger swipes keep resetting timer
This provides the consistent UX requested where ANY user interaction
on ANY site enables the inactivity prompt logic.
Changed the inactivity prompt behavior based on user feedback:
Changes:
- Renamed button from "🏠 Return to home now" to "🔄 Return to rotation"
- Reverted inactivity check to work on ALL pages (including home screen)
- Updated returnToHome() function comments to clarify rotation behavior
Behavior:
- Inactivity prompt now appears on home screen AND other pages
- If user is viewing a recipe (or any page), they can extend time
- Clicking "Return to Rotation":
* If NOT on home page: goes to home page first, then starts rotation
* If on home page: just starts the rotation
- This allows users to get "30 extra minutes" before touching the screen
with dirty hands (e.g., when following a recipe)
Use Case:
User navigates to a recipe on menu app, inactivity prompt appears,
they can click "30 more minutes" to read the recipe without any
further screen interaction needed.
This release adds password-protected session lockout and fixes several
reported bugs from v0.9.9.1 testing.
New Features:
- Password-protected session lockout
* Configurable lockout password (separate from sudo user)
* Auto-lock after configurable timeout (default 30 minutes)
* Black lockout screen with password prompt
* Session unlocks with correct password
* New "Configure Session Lockout" menu option
Bug Fixes:
- Fixed return-to-home popup appearing on home screen
* Popup now only appears on timed sites
* Home screen no longer triggers inactivity prompt
* Updated logic: only check inactivity when NOT on home page
- Fixed site edit menu flow
* Edit site URL function now returns properly to menu
* Added explicit return statement to prevent bail
* Added blank line for better UX
Version Updates:
- Updated to semantic versioning: v0.9.8
- Updated all version references in header and script
- Updated changelog with new features and fixes
Technical Changes:
- Added LOCKOUT_ENABLED, LOCKOUT_PASSWORD, LOCKOUT_TIMEOUT config vars
- Created lockout.html template with black screen and password entry
- Added lockout state tracking in main.js
- Implemented showLockout() and hideLockout() functions
- Added unlock-session IPC handler
- Integrated lockout check into master timer
- Updated save_config() to persist lockout settings
- Updated loadConfig() to load lockout settings
Addresses user feedback from testing:
- Time extensions now work correctly
- Return to home popup fixed
- Site edit menu no longer bails