Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9f3a98286 | ||
|
|
47d41b4a61 |
@@ -20,8 +20,9 @@ joke_cache = {'data': None, 'timestamp': None}
|
|||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
"""Render the main display page."""
|
js_path = os.path.join(app.static_folder, 'js', 'app.js')
|
||||||
return render_template('index.html')
|
cache_bust = int(os.path.getmtime(js_path))
|
||||||
|
return render_template('index.html', cache_bust=cache_bust)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/weather')
|
@app.route('/api/weather')
|
||||||
|
|||||||
+14
-32
@@ -276,10 +276,6 @@ async function showSlideshow() {
|
|||||||
activeSlot = 'a';
|
activeSlot = 'a';
|
||||||
|
|
||||||
loadSlide('a', photos[slideIndex]);
|
loadSlide('a', photos[slideIndex]);
|
||||||
if (photos.length > 1) {
|
|
||||||
loadSlide('b', photos[(slideIndex + 1) % photos.length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
slideTimer = setInterval(advanceSlide, SLIDE_DURATION);
|
slideTimer = setInterval(advanceSlide, SLIDE_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,29 +287,21 @@ function hideSlideshow() {
|
|||||||
const overlay = document.getElementById('slideshow-overlay');
|
const overlay = document.getElementById('slideshow-overlay');
|
||||||
overlay.classList.add('hidden');
|
overlay.classList.add('hidden');
|
||||||
|
|
||||||
// Clear images to free memory
|
const a = document.getElementById('slide-a');
|
||||||
document.getElementById('slide-a').classList.remove('active');
|
const b = document.getElementById('slide-b');
|
||||||
document.getElementById('slide-b').classList.remove('active');
|
a.onload = null; b.onload = null;
|
||||||
document.getElementById('slide-a').src = '';
|
a.classList.remove('active'); b.classList.remove('active');
|
||||||
document.getElementById('slide-b').src = '';
|
a.removeAttribute('src'); b.removeAttribute('src');
|
||||||
|
|
||||||
resetInactivityTimer();
|
resetInactivityTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSlide(slot, url) {
|
function loadSlide(slot, url) {
|
||||||
const img = document.getElementById(`slide-${slot}`);
|
const img = document.getElementById(`slide-${slot}`);
|
||||||
if (slot === activeSlot) {
|
const show = () => { img.onload = null; img.classList.add('active'); };
|
||||||
// Only fade in once the image is fully decoded — no blank-then-flash
|
img.onload = show;
|
||||||
img.onload = () => { img.onload = null; img.classList.add('active'); };
|
|
||||||
img.src = url;
|
img.src = url;
|
||||||
// Handle cached images that won't fire onload
|
if (img.complete && img.naturalWidth > 0) show();
|
||||||
if (img.complete && img.naturalWidth > 0) {
|
|
||||||
img.onload = null;
|
|
||||||
img.classList.add('active');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
img.src = url; // preload only
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function advanceSlide() {
|
function advanceSlide() {
|
||||||
@@ -321,22 +309,16 @@ function advanceSlide() {
|
|||||||
const current = document.getElementById(`slide-${activeSlot}`);
|
const current = document.getElementById(`slide-${activeSlot}`);
|
||||||
const next = document.getElementById(`slide-${nextSlot}`);
|
const next = document.getElementById(`slide-${nextSlot}`);
|
||||||
|
|
||||||
const doSwap = () => {
|
slideIndex = (slideIndex + 1) % photos.length;
|
||||||
|
|
||||||
|
const swap = () => {
|
||||||
next.onload = null;
|
next.onload = null;
|
||||||
next.classList.add('active');
|
next.classList.add('active');
|
||||||
current.classList.remove('active');
|
current.classList.remove('active');
|
||||||
activeSlot = nextSlot;
|
activeSlot = nextSlot;
|
||||||
slideIndex = (slideIndex + 1) % photos.length;
|
|
||||||
const preloadSrc = photos[(slideIndex + 1) % photos.length];
|
|
||||||
// Only change src after the fade-out completes — changing it mid-transition
|
|
||||||
// causes the new image to appear at partial opacity (the flash the user sees)
|
|
||||||
current.addEventListener('transitionend', () => { current.src = preloadSrc; }, { once: true });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the preloaded image is ready, swap immediately; otherwise wait for it
|
next.onload = swap;
|
||||||
if (next.complete && next.naturalWidth > 0) {
|
next.src = photos[slideIndex];
|
||||||
doSwap();
|
if (next.complete && next.naturalWidth > 0) swap();
|
||||||
} else {
|
|
||||||
next.onload = doSwap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,6 @@
|
|||||||
<div class="slideshow-hint">Touch to return to calendar</div>
|
<div class="slideshow-hint">Touch to return to calendar</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/app.js') }}?v={{ cache_bust }}"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user