From 82e774cc044bb47a6adfa102bf36e8400e8001d5 Mon Sep 17 00:00:00 2001 From: Tyler Hoang Date: Tue, 26 May 2026 00:41:21 -0700 Subject: films: map real api fields and use 3-star scale films.tylerhoang.xyz/tyler/api/recent returns stars (0-3), date_watched, poster_url, director. Wire those through and render 3 stars instead of 5. Escape user-supplied strings. Co-Authored-By: Claude Opus 4.7 --- index.html | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'index.html') diff --git a/index.html b/index.html index 11404e0..3ad0b55 100755 --- a/index.html +++ b/index.html @@ -434,42 +434,43 @@ const filmsList = document.getElementById('films-list'); if (films.length > 0) { - filmsList.innerHTML = films.map((film, idx) => { - const stars = Array.from({ length: 5 }, (_, i) => { - const fullStars = Math.floor(film.rating || 0); - const hasHalf = (film.rating || 0) % 1 !== 0 && i + 1 === Math.ceil(film.rating || 0); - if (i + 1 <= fullStars) return ''; - if (hasHalf) return ''; - return ''; - }).join(''); + const esc = s => String(s == null ? '' : s).replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); + filmsList.innerHTML = films.slice(0, 4).map((film) => { + const rating = Math.max(0, Math.min(3, Number(film.stars ?? film.rating ?? 0))); + const stars = Array.from({ length: 3 }, (_, i) => + i < rating ? '' : '' + ).join(''); - let when = 'unknown'; - if (film.watchedAt) { - const d = new Date(film.watchedAt); + let when = ''; + const raw = film.date_watched || film.watchedAt; + if (raw) { + const d = new Date(raw); if (!isNaN(d)) { - const diff = Date.now() - d; - const days = Math.floor(diff / 86400000); - if (days === 0) when = 'today'; + const days = Math.floor((Date.now() - d) / 86400000); + if (days <= 0) when = 'today'; else if (days === 1) when = '1d ago'; else if (days < 7) when = days + 'd ago'; - else when = Math.floor(days / 7) + 'w ago'; + else if (days < 30) when = Math.floor(days / 7) + 'w ago'; + else when = Math.floor(days / 30) + 'mo ago'; } else { - when = String(film.watchedAt); + when = String(raw); } } - let posterStyle = `background: linear-gradient(135deg, oklch(${50 + idx * 10}% 0.12 ${30 + idx * 60}), oklch(${30 + idx * 8}% 0.08 ${280 - idx * 40}));`; - if (film.posterUrl) { - posterStyle = `background: url(${JSON.stringify(film.posterUrl)}) center / cover;`; - } + const poster = film.poster_url || film.posterUrl; + const posterStyle = poster + ? `background: url('${esc(poster).replace(/'/g, '%27')}') center / cover;` + : `background: linear-gradient(135deg, oklch(70% 0.13 220), oklch(40% 0.10 250));`; + + const sub = film.director ? esc(film.director) : (film.note ? esc(film.note) : ''); return `
-
${film.title} ${film.year || ''}
-
${stars}${when}${film.note ? '' : ''}
- ${film.note ? `
${film.note}
` : ''} +
${esc(film.title)} ${esc(film.year || '')}
+
${stars}${when}
+ ${sub ? `
${sub}
` : ''}
`; -- cgit v1.3-2-g0d8e