Add photo slideshow screensaver with inactivity timer

- After 1 hour of inactivity the screen switches to a fullscreen
  crossfade slideshow of photos from static/photos/
- Touch anywhere on screen to dismiss and return to the calendar
- /api/photos endpoint serves a shuffled list of images from static/photos/
- Two-slot A/B image swap for smooth 1.5s crossfades; next image preloads
  in the background while current is displayed (15s per photo)
- Slideshow only activates if static/photos/ contains at least one image

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 21:00:22 +12:00
parent 20c9bb55b1
commit 93b2dad8fd
5 changed files with 167 additions and 1 deletions

16
app.py
View File

@@ -235,6 +235,20 @@ def get_calendar():
return jsonify(empty_week_payload(week_start_date, members_for_filter))
@app.route('/api/photos')
def get_photos():
"""Return a shuffled list of all image URLs from the photos directory."""
photos_dir = app.config['PHOTOS_DIR']
if not os.path.exists(photos_dir):
return jsonify([])
images = [
f'/static/photos/{f}' for f in os.listdir(photos_dir)
if f.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.webp'))
]
random.shuffle(images)
return jsonify(images)
@app.route('/api/background')
def get_background():
"""Get a random background image."""
@@ -289,8 +303,8 @@ def get_joke():
if __name__ == '__main__':
# Create backgrounds directory if it doesn't exist
os.makedirs(app.config['BACKGROUNDS_DIR'], exist_ok=True)
os.makedirs(app.config['PHOTOS_DIR'], exist_ok=True)
os.makedirs(app.config['CREDENTIALS_DIR'], exist_ok=True)
# Run the app