// =============================== // INITIAL SETUP // =============================== let currentSongIndex = 0; let SONG_LINKS = []; let PLAYLIST = document.getElementById("playlistLeft"); let AUDIO_PLAYER = document.getElementById("navMusic"); let TRACK_NAME_DISPLAY = document.getElementById("currentSongInfo"); let NAV_PLAY = document.getElementById("navMusicPlay"); let NAV_PAUSE = document.getElementById("navMusicPause"); let NAV_NEXT = document.getElementById("navMusicNext"); let NAV_PREV = document.getElementById("navMusicPrevious"); // =============================== // LOAD MUSIC DATA // =============================== async function loadMusicData() { const response = await fetch("https://frutigeraeroarchive.org/data/music.min.json"); const data = await response.json(); const section = data.ols.find(item => item["@id"] === "frutigerAeroBliss"); if (!section) return []; // KEEP JSON ORDER EXACTLY return section.li.map(item => ({ title: item.a.title, url: item.a["@data-src-mp3"], background: item.a["@data-background"] || "", artist: item.a["@data-artist"] || "", spotify: item.a["@data-spotify"] || "", youtube: item.a["@data-youtube"] || "", description: item.a["@data-description"] || "", copyright: item.a["@data-copyright"] || "", date: item.a["@data-date"] || "" })); } // =============================== // CREATE PLAYLIST // =============================== function createAlbum(album) { if (!PLAYLIST) return; const existing = PLAYLIST.querySelector("ol"); if (existing) existing.remove(); const list = document.createElement("ol"); list.id = album["@id"]; const title = document.createElement("span"); title.textContent = album.span; list.appendChild(title); const small = document.createElement("small"); small.textContent = album.small; list.appendChild(small); // Build playlist in EXACT JSON ORDER album.li.forEach((song, index) => { const li = document.createElement("li"); const a = document.createElement("a"); a.textContent = song.a.title; a.href = "#"; // Apply metadata for (const key in song.a) { if (key.startsWith("@data-")) { a.setAttribute(key.replace("@", ""), song.a[key]); } } li.appendChild(a); list.appendChild(li); }); PLAYLIST.appendChild(list); SONG_LINKS = PLAYLIST.querySelectorAll("a[data-src-mp3]"); SONG_LINKS.forEach((song, index) => { song.addEventListener("click", (e) => { e.preventDefault(); currentSongIndex = index; updateSong(index); }); }); // ALWAYS START AT SONG 0 currentSongIndex = 0; updateSong(0); } // =============================== // UPDATE SONG // =============================== function updateSong(index) { SONG_LINKS.forEach((song, i) => { song.classList.toggle("activeSong", i === index); }); const song = SONG_LINKS[index]; AUDIO_PLAYER.src = song.getAttribute("data-src-mp3"); TRACK_NAME_DISPLAY.textContent = song.getAttribute("data-title"); AUDIO_PLAYER.play().catch(console.error); } // =============================== // NEXT / PREVIOUS // =============================== function nextTrack() { currentSongIndex = (currentSongIndex + 1) % SONG_LINKS.length; updateSong(currentSongIndex); } function previousTrack() { currentSongIndex = (currentSongIndex - 1 + SONG_LINKS.length) % SONG_LINKS.length; updateSong(currentSongIndex); } AUDIO_PLAYER.addEventListener("ended", nextTrack); // =============================== // NAV BUTTONS // =============================== NAV_PLAY.addEventListener("click", () => AUDIO_PLAYER.play()); NAV_PAUSE.addEventListener("click", () => AUDIO_PLAYER.pause()); NAV_NEXT.addEventListener("click", nextTrack); NAV_PREV.addEventListener("click", previousTrack); // =============================== // LOAD ON STARTUP // =============================== window.addEventListener("load", async () => { const songs = await loadMusicData(); if (songs.length > 0) { createAlbum({ "@id": "frutigerAeroBliss", span: "Frutiger Aero Bliss", small: "Music that fits well with Frutiger Aero.", li: songs.map(song => ({ a: song })) }); } });