aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aero.js25
-rwxr-xr-xindex.html50
2 files changed, 64 insertions, 11 deletions
diff --git a/aero.js b/aero.js
index e97e376..01a9b83 100644
--- a/aero.js
+++ b/aero.js
@@ -176,4 +176,27 @@ async function fetchVisitorCount() {
return j.count;
}
-window.Aero = { spawnBubbles, makeClouds, sparkleCursor, makeDraggable, counterHTML, nowPlayingHTML, animateEq, musicToggleHTML, bindMusicToggle, fetchLastFm, fetchFilms, fetchVisitorCount };
+async function fetchReelMouthFeed(limit = 6) {
+ const url = `https://itunes.apple.com/lookup?id=1709836497&entity=podcastEpisode&limit=${limit + 1}`;
+ const r = await fetch(url);
+ if (!r.ok) throw new Error('itunes ' + r.status);
+ const j = await r.json();
+ const podcast = j.results.find(x => x.kind === 'podcast');
+ const episodes = j.results.filter(x => x.kind === 'podcast-episode').slice(0, limit);
+ return {
+ art: podcast ? podcast.artworkUrl600 : null,
+ episodes: episodes.map(e => {
+ const ms = e.trackTimeMillis || 0;
+ const mins = Math.floor(ms / 60000);
+ const h = Math.floor(mins / 60);
+ const m = mins % 60;
+ return {
+ title: e.trackName,
+ url: e.trackViewUrl,
+ duration: h ? `${h}:${m.toString().padStart(2, '0')}` : `${m}m`,
+ };
+ }),
+ };
+}
+
+window.Aero = { spawnBubbles, makeClouds, sparkleCursor, makeDraggable, counterHTML, nowPlayingHTML, animateEq, musicToggleHTML, bindMusicToggle, fetchLastFm, fetchFilms, fetchVisitorCount, fetchReelMouthFeed };
diff --git a/index.html b/index.html
index 8e817be..064ae25 100755
--- a/index.html
+++ b/index.html
@@ -207,7 +207,8 @@
<div class="titlebar" style="background: var(--title-bar);"><div class="dots"><div class="dot r no-drag" onclick="this.closest('.win').style.display='none'"></div><div class="dot y"></div><div class="dot g"></div></div>REEL MOUTH — film pod</div>
<div class="body">
<div style="display: flex; gap: 12px; align-items: flex-start; margin-bottom: 12px;">
- <div class="photo" style="width: 84px; height: 84px;"><span>[ pod art ]</span></div>
+ <img id="pod-art" src="" alt="REEL MOUTH" style="width: 84px; height: 84px; border-radius: 12px; object-fit: cover; box-shadow: 0 3px 10px rgba(0,0,0,0.18); display: none;" />
+ <div class="photo" id="pod-art-placeholder" style="width: 84px; height: 84px;"><span>🎙</span></div>
<div style="font-size: 12px; line-height: 1.5;">
<div style="font-size: 16px; font-weight: 700; color: oklch(28% 0.08 230); letter-spacing: -0.3px;">REEL MOUTH</div>
<div style="opacity: 0.7; margin-bottom: 4px;">a film podcast · since 2022</div>
@@ -215,18 +216,13 @@
</div>
</div>
<div style="font-size: 11px; opacity: 0.7; text-transform: uppercase; letter-spacing: 1.5px; margin-bottom: 6px;">latest episodes</div>
- <!-- TODO: wire to podcast RSS via iTunes lookup API once we know the Apple Podcasts ID -->
- <div style="display: flex; flex-direction: column; gap: 4px; font-size: 12px; line-height: 1.5;">
- <div style="display:flex;justify-content:space-between;gap:8px;"><span>#84 — every wong kar-wai, ranked</span><span style="opacity:0.6;flex-shrink:0;">1:47</span></div>
- <div style="display:flex;justify-content:space-between;gap:8px;"><span>#83 — paul thomas anderson cinematic universe</span><span style="opacity:0.6;flex-shrink:0;">1:32</span></div>
- <div style="display:flex;justify-content:space-between;gap:8px;"><span>#82 — vietnamese cinema is real, actually</span><span style="opacity:0.6;flex-shrink:0;">1:58</span></div>
- <div style="display:flex;justify-content:space-between;gap:8px;"><span>#81 — the criterion sale haul</span><span style="opacity:0.6;flex-shrink:0;">1:12</span></div>
+ <div id="pod-episodes" style="display: flex; flex-direction: column; gap: 4px; font-size: 12px; line-height: 1.5;">
+ <div style="opacity: 0.5; font-style: italic;">loading…</div>
</div>
<div style="margin-top: 14px; display: flex; gap: 8px; flex-wrap: wrap;">
<a class="aqua sm" href="https://reelmouth.tv" style="text-decoration:none;">▶ reelmouth.tv</a>
- <a class="aqua sm" href="#" style="text-decoration:none;">apple</a>
- <a class="aqua sm" href="#" style="text-decoration:none;">spotify</a>
- <a class="aqua sm" href="#" style="text-decoration:none;">rss</a>
+ <a class="aqua sm" href="https://podcasts.apple.com/us/podcast/reel-mouth/id1709836497" style="text-decoration:none;">apple</a>
+ <a class="aqua sm" href="https://anchor.fm/s/e8438774/podcast/rss" style="text-decoration:none;">rss</a>
</div>
</div>
</div>
@@ -353,6 +349,40 @@
});
});
+ // podcast RSS
+ let podLoaded = false;
+ async function loadPodcast() {
+ if (podLoaded) return;
+ podLoaded = true;
+ try {
+ const { art, episodes } = await Aero.fetchReelMouthFeed(6);
+ if (art) {
+ const img = document.getElementById('pod-art');
+ const ph = document.getElementById('pod-art-placeholder');
+ img.src = art;
+ img.style.display = '';
+ if (ph) ph.style.display = 'none';
+ }
+ const container = document.getElementById('pod-episodes');
+ if (episodes.length) {
+ container.innerHTML = episodes.map(e =>
+ `<div style="display:flex;justify-content:space-between;gap:8px;">
+ <a href="${e.url}" target="_blank" rel="noopener" style="color:inherit;text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="${e.title}">${e.title.toLowerCase()}</a>
+ <span style="opacity:0.6;flex-shrink:0;">${e.duration}</span>
+ </div>`
+ ).join('');
+ } else {
+ container.innerHTML = '<div style="opacity:0.5;font-style:italic;">no episodes found</div>';
+ }
+ } catch (err) {
+ document.getElementById('pod-episodes').innerHTML = '<div style="opacity:0.5;font-style:italic;">couldn\'t load feed</div>';
+ }
+ }
+ document.querySelectorAll('.icon[data-open="podcast"]').forEach(ic => {
+ ic.addEventListener('click', loadPodcast);
+ ic.addEventListener('dblclick', loadPodcast);
+ });
+
// music toggle + volume slider
document.getElementById('mt').innerHTML = Aero.musicToggleHTML();
const mtDiv = document.getElementById('mt');