diff --git a/assets/js/lastfm-utils.js b/assets/js/lastfm-utils.js new file mode 100644 index 0000000..37f4a2d --- /dev/null +++ b/assets/js/lastfm-utils.js @@ -0,0 +1,68 @@ +// Shared Last.fm utilities - using global namespace pattern +(function(window) { + 'use strict'; + + // Create global LastFmUtils namespace + window.LastFmUtils = { + // Last.fm API configuration + LASTFM_API_URL: "https://ws.audioscrobbler.com/2.0/", + LASTFM_USER: "ritualplays", + LASTFM_API_KEY: "3a4fef48fecc593d25e0f9a40df1fefe", + + // Format time difference + getTimeAgo: function(timestamp) { + const now = Date.now() / 1000; + const diff = now - timestamp; + + if (diff < 60) return "Just now"; + if (diff < 3600) return `${Math.floor(diff / 60)}m ago`; + if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`; + if (diff < 604800) return `${Math.floor(diff / 86400)}d ago`; + return `${Math.floor(diff / 604800)}w ago`; + }, + + // Fetch recent tracks from Last.fm + fetchRecentTracks: async function(limit = 10) { + const url = `${this.LASTFM_API_URL}?method=user.getrecenttracks&user=${this.LASTFM_USER}&api_key=${this.LASTFM_API_KEY}&format=json&limit=${limit}`; + + try { + const response = await fetch(url); + if (!response.ok) throw new Error("Failed to fetch tracks"); + + const data = await response.json(); + return data.recenttracks.track; + } catch (error) { + console.error("Error fetching Last.fm data:", error); + return null; + } + }, + + // Filter tracks to remove duplicates of now playing track + // Returns a limited number of unique tracks + filterAndLimitTracks: function(tracks, maxTracks = 5) { + if (!tracks || tracks.length === 0) { + return []; + } + + // Check if first track is now playing + const hasNowPlaying = tracks[0] && tracks[0]["@attr"] && tracks[0]["@attr"].nowplaying; + + if (hasNowPlaying) { + // Show now playing + (maxTracks - 1) latest (excluding duplicates of now playing) + const nowPlayingTrack = tracks[0]; + const nowPlayingId = `${nowPlayingTrack.name}-${nowPlayingTrack.artist["#text"]}`; + + // Get remaining tracks, excluding duplicates of now playing + const remainingTracks = tracks.slice(1).filter(track => { + const trackId = `${track.name}-${track.artist["#text"]}`; + return trackId !== nowPlayingId; + }); + + return [nowPlayingTrack, ...remainingTracks.slice(0, maxTracks - 1)]; + } else { + // No now playing, show maxTracks latest + return tracks.slice(0, maxTracks); + } + } + }; +})(window); diff --git a/assets/js/pages/audio.js b/assets/js/pages/audio.js index 07c36c7..51c2062 100644 --- a/assets/js/pages/audio.js +++ b/assets/js/pages/audio.js @@ -83,27 +83,8 @@ if (document.getElementById("starfield")) { const container = document.getElementById("recent-tracks"); if (!container) return; - const AUDIO_LASTFM_API_URL = "https://ws.audioscrobbler.com/2.0/"; - const AUDIO_LASTFM_USER = "ritualplays"; - const AUDIO_LASTFM_API_KEY = "3a4fef48fecc593d25e0f9a40df1fefe"; const AUDIO_TRACK_LIMIT = 6; // Fetch 6 to have enough after filtering - // Fetch recent tracks from Last.fm for audio page - async function fetchAudioRecentTracks() { - const url = `${AUDIO_LASTFM_API_URL}?method=user.getrecenttracks&user=${AUDIO_LASTFM_USER}&api_key=${AUDIO_LASTFM_API_KEY}&format=json&limit=${AUDIO_TRACK_LIMIT}`; - - try { - const response = await fetch(url); - if (!response.ok) throw new Error("Failed to fetch tracks"); - - const data = await response.json(); - return data.recenttracks.track; - } catch (error) { - console.error("Error fetching Last.fm data:", error); - return null; - } - } - // Render recent tracks for audio page (horizontal layout) function renderRecentTracks(tracks) { if (!tracks || tracks.length === 0) { @@ -114,27 +95,8 @@ if (document.getElementById("starfield")) { container.innerHTML = ""; - // Check if first track is now playing - const hasNowPlaying = tracks[0] && tracks[0]["@attr"] && tracks[0]["@attr"].nowplaying; - - // Filter and limit tracks - let tracksToShow; - if (hasNowPlaying) { - // Show now playing + 4 latest (excluding duplicates of now playing) - const nowPlayingTrack = tracks[0]; - const nowPlayingId = `${nowPlayingTrack.name}-${nowPlayingTrack.artist["#text"]}`; - - // Get remaining tracks, excluding duplicates of now playing - const remainingTracks = tracks.slice(1).filter(track => { - const trackId = `${track.name}-${track.artist["#text"]}`; - return trackId !== nowPlayingId; - }); - - tracksToShow = [nowPlayingTrack, ...remainingTracks.slice(0, 4)]; - } else { - // No now playing, show 5 latest - tracksToShow = tracks.slice(0, 5); - } + // Filter and limit tracks to 5 (excluding duplicates) + const tracksToShow = LastFmUtils.filterAndLimitTracks(tracks, 5); tracksToShow.forEach((track) => { const isNowPlaying = track["@attr"] && track["@attr"].nowplaying; @@ -164,12 +126,12 @@ if (document.getElementById("starfield")) { // Initialize Last.fm feed for audio page async function initAudioRecentTracks() { - const tracks = await fetchAudioRecentTracks(); + const tracks = await LastFmUtils.fetchRecentTracks(AUDIO_TRACK_LIMIT); renderRecentTracks(tracks); // Update every 30 seconds setInterval(async () => { - const updatedTracks = await fetchAudioRecentTracks(); + const updatedTracks = await LastFmUtils.fetchRecentTracks(AUDIO_TRACK_LIMIT); renderRecentTracks(updatedTracks); }, 30000); } diff --git a/assets/js/pages/media.js b/assets/js/pages/media.js index f4548b6..c57c5b1 100644 --- a/assets/js/pages/media.js +++ b/assets/js/pages/media.js @@ -82,39 +82,8 @@ function initMatrixRain() { }); } -// Last.fm API configuration -const LASTFM_API_URL = "https://ws.audioscrobbler.com/2.0/"; -const LASTFM_USER = "ritualplays"; -const LASTFM_API_KEY = "3a4fef48fecc593d25e0f9a40df1fefe"; -const TRACK_LIMIT = 10; - -// Format time difference -function getTimeAgo(timestamp) { - const now = Date.now() / 1000; - const diff = now - timestamp; - - if (diff < 60) return "Just now"; - if (diff < 3600) return `${Math.floor(diff / 60)}m ago`; - if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`; - if (diff < 604800) return `${Math.floor(diff / 86400)}d ago`; - return `${Math.floor(diff / 604800)}w ago`; -} - -// Fetch recent tracks from Last.fm -async function fetchRecentTracks() { - const url = `${LASTFM_API_URL}?method=user.getrecenttracks&user=${LASTFM_USER}&api_key=${LASTFM_API_KEY}&format=json&limit=${TRACK_LIMIT}`; - - try { - const response = await fetch(url); - if (!response.ok) throw new Error("Failed to fetch tracks"); - - const data = await response.json(); - return data.recenttracks.track; - } catch (error) { - console.error("Error fetching Last.fm data:", error); - return null; - } -} +// Media page configuration +const TRACK_LIMIT = 12; // Fetch 12 to have enough after filtering // Render tracks to the DOM function renderTracks(tracks) { @@ -129,7 +98,10 @@ function renderTracks(tracks) { container.innerHTML = ""; - tracks.forEach((track) => { + // Filter and limit tracks to 10 (excluding duplicates of now playing) + const tracksToShow = LastFmUtils.filterAndLimitTracks(tracks, 10); + + tracksToShow.forEach((track) => { const isNowPlaying = track["@attr"] && track["@attr"].nowplaying; const trackElement = document.createElement("a"); trackElement.href = track.url; @@ -143,7 +115,7 @@ function renderTracks(tracks) { // Get timestamp const timestamp = track.date ? track.date.uts : null; - const timeAgo = timestamp ? getTimeAgo(timestamp) : ""; + const timeAgo = timestamp ? LastFmUtils.getTimeAgo(timestamp) : ""; trackElement.innerHTML = `