diff --git a/app.py b/app.py index 86f296a..187b641 100644 --- a/app.py +++ b/app.py @@ -20,8 +20,9 @@ joke_cache = {'data': None, 'timestamp': None} @app.route('/') def index(): - """Render the main display page.""" - return render_template('index.html') + js_path = os.path.join(app.static_folder, 'js', 'app.js') + cache_bust = int(os.path.getmtime(js_path)) + return render_template('index.html', cache_bust=cache_bust) @app.route('/api/weather') diff --git a/static/js/app.js b/static/js/app.js index fa7cd80..f210549 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -276,10 +276,6 @@ async function showSlideshow() { activeSlot = 'a'; loadSlide('a', photos[slideIndex]); - if (photos.length > 1) { - loadSlide('b', photos[(slideIndex + 1) % photos.length]); - } - slideTimer = setInterval(advanceSlide, SLIDE_DURATION); } @@ -291,58 +287,38 @@ function hideSlideshow() { const overlay = document.getElementById('slideshow-overlay'); overlay.classList.add('hidden'); - // Clear images to free memory - document.getElementById('slide-a').classList.remove('active'); - document.getElementById('slide-b').classList.remove('active'); - document.getElementById('slide-a').src = ''; - document.getElementById('slide-b').src = ''; + const a = document.getElementById('slide-a'); + const b = document.getElementById('slide-b'); + a.onload = null; b.onload = null; + a.classList.remove('active'); b.classList.remove('active'); + a.removeAttribute('src'); b.removeAttribute('src'); resetInactivityTimer(); } function loadSlide(slot, url) { const img = document.getElementById(`slide-${slot}`); - if (slot === activeSlot) { - // Only fade in once the image is fully decoded — no blank-then-flash - img.onload = () => { img.onload = null; img.classList.add('active'); }; - img.src = url; - // Handle cached images that won't fire onload - if (img.complete && img.naturalWidth > 0) { - img.onload = null; - img.classList.add('active'); - } - } else { - img.src = url; // preload only - } + const show = () => { img.onload = null; img.classList.add('active'); }; + img.onload = show; + img.src = url; + if (img.complete && img.naturalWidth > 0) show(); } function advanceSlide() { const nextSlot = activeSlot === 'a' ? 'b' : 'a'; - const current = document.getElementById(`slide-${activeSlot}`); - const next = document.getElementById(`slide-${nextSlot}`); + const current = document.getElementById(`slide-${activeSlot}`); + const next = document.getElementById(`slide-${nextSlot}`); - const doSwap = () => { + slideIndex = (slideIndex + 1) % photos.length; + + const swap = () => { next.onload = null; next.classList.add('active'); current.classList.remove('active'); activeSlot = nextSlot; - slideIndex = (slideIndex + 1) % photos.length; - const preloadSrc = photos[(slideIndex + 1) % photos.length]; - // Wait for the fade-out transition to finish before preloading the next src. - // transitionend is unreliable (can be skipped if display sleeps), so use - // a plain timeout just past the 1.5s CSS transition as the trigger. - setTimeout(() => { current.src = preloadSrc; }, 1600); }; - // If the preloaded image is ready, swap immediately; otherwise wait for it. - // Guard against a stuck onload by also setting src explicitly if needed. - if (next.complete && next.naturalWidth > 0) { - doSwap(); - } else { - if (!next.src || next.src === window.location.href) { - // src was never set (stalled state) — kick it off now - next.src = photos[(slideIndex + 1) % photos.length]; - } - next.onload = doSwap; - } + next.onload = swap; + next.src = photos[slideIndex]; + if (next.complete && next.naturalWidth > 0) swap(); } diff --git a/templates/index.html b/templates/index.html index 0c9813a..c265ac4 100644 --- a/templates/index.html +++ b/templates/index.html @@ -32,6 +32,6 @@
Touch to return to calendar
- +