Spaces:
Running
Running
| // Shared JavaScript across all pages | |
| // Album data structure | |
| let albumData = { | |
| id: "still-lie-right-next-to-me", | |
| artist: "Mr.FLEN", | |
| title: "Still Lie Right Next to Me", | |
| description: "Intimate deep house for late lights and long shadows—warm pads, patient grooves, and urban after-hours emotion.", | |
| colors: { primary: "#0B2D2F", accent: "#FF914D", magenta: "#C5427A" }, | |
| tags: ["Deep House", "Melodic House", "AfterHours", "Hypnotic"], | |
| tracks: [ | |
| { | |
| no: "01", | |
| slug: "still-lie-right-next-to-me", | |
| title: "Still Lie Right Next to Me", | |
| desc: "The title track sets the mood with deep, atmospheric pads and a hypnotic groove that pulls you into the late-night world of Mr.FLEN.", | |
| duration: "5:24", | |
| bpm: 122, | |
| key: "Am", | |
| tags: ["Deep House", "Atmospheric", "Hypnotic"], | |
| cover: "http://static.photos/monochrome/200x200/1", | |
| embeds: [ | |
| { | |
| provider: "soundcloud", | |
| url: "https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1900000001&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true", | |
| label: "SoundCloud" | |
| } | |
| ] | |
| }, | |
| { | |
| no: "02", | |
| slug: "midnight-walks", | |
| title: "Midnight Walks", | |
| desc: "A journey through empty city streets with pulsing basslines and ethereal melodies.", | |
| duration: "6:12", | |
| bpm: 124, | |
| key: "Gm", | |
| tags: ["Deep House", "Melodic", "Urban"], | |
| cover: "http://static.photos/monochrome/200x200/2", | |
| embeds: [ | |
| { | |
| provider: "soundcloud", | |
| url: "https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1900000002&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true", | |
| label: "SoundCloud" | |
| } | |
| ] | |
| }, | |
| { | |
| no: "03", | |
| slug: "neon-reflections", | |
| title: "Neon Reflections", | |
| desc: "Capturing the glow of city lights in sound, with shimmering synths and deep grooves.", | |
| duration: "5:48", | |
| bpm: 123, | |
| key: "Bbm", | |
| tags: ["Deep House", "Atmospheric", "Urban"], | |
| cover: "http://static.photos/monochrome/200x200/3", | |
| embeds: [ | |
| { | |
| provider: "soundcloud", | |
| url: "https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1900000003&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true", | |
| label: "SoundCloud" | |
| } | |
| ] | |
| }, | |
| { | |
| no: "04", | |
| slug: "after-hours", | |
| title: "After Hours", | |
| desc: "The perfect soundtrack for those late-night sessions when the world is asleep.", | |
| duration: "6:35", | |
| bpm: 121, | |
| key: "Fm", | |
| tags: ["Deep House", "AfterHours", "Hypnotic"], | |
| cover: "http://static.photos/monochrome/200x200/4", | |
| embeds: [ | |
| { | |
| provider: "soundcloud", | |
| url: "https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1900000004&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true", | |
| label: "SoundCloud" | |
| } | |
| ] | |
| }, | |
| { | |
| no: "05", | |
| slug: "urban-dreams", | |
| title: "Urban Dreams", | |
| desc: "A dreamy exploration of city life with floating melodies and deep bass foundations.", | |
| duration: "5:59", | |
| bpm: 122, | |
| key: "Em", | |
| tags: ["Deep House", "Melodic", "Atmospheric"], | |
| cover: "http://static.photos/monochrome/200x200/5", | |
| embeds: [ | |
| { | |
| provider: "soundcloud", | |
| url: "https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1900000005&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true", | |
| label: "SoundCloud" | |
| } | |
| ] | |
| } | |
| ] | |
| }; | |
| // Initialize app | |
| document.addEventListener('DOMContentLoaded', function() { | |
| console.log('Neon Noir Soundscapes loaded'); | |
| loadAlbumData(); | |
| initializeAnalytics(); | |
| }); | |
| // Load album data from localStorage or default | |
| function loadAlbumData() { | |
| const savedData = localStorage.getItem('mrflen_album_data'); | |
| if (savedData) { | |
| try { | |
| albumData = JSON.parse(savedData); | |
| } catch (e) { | |
| console.error('Error loading album data:', e); | |
| } | |
| } | |
| return albumData; | |
| } | |
| // Save album data to localStorage | |
| function saveAlbumData() { | |
| localStorage.setItem('mrflen_album_data', JSON.stringify(albumData)); | |
| } | |
| // Load featured tracks on homepage | |
| function loadFeaturedTracks() { | |
| const featuredContainer = document.querySelector('.grid'); | |
| if (!featuredContainer) return; | |
| // Show loading state | |
| featuredContainer.innerHTML = ` | |
| <div class="col-span-full text-center py-8"> | |
| <div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-accent"></div> | |
| </div> | |
| `; | |
| // Simulate API call delay | |
| setTimeout(() => { | |
| const featuredTracks = albumData.tracks.slice(0, 6); | |
| renderTrackCards(featuredTracks, featuredContainer); | |
| }, 1000); | |
| } | |
| // Render track cards | |
| function renderTrackCards(tracks, container) { | |
| if (!tracks || tracks.length === 0) { | |
| container.innerHTML = ` | |
| <div class="col-span-full text-center py-8"> | |
| <p class="text-gray-400">No tracks available</p> | |
| </div> | |
| `; | |
| return; | |
| } | |
| container.innerHTML = tracks.map(track => ` | |
| <div class="bg-primary/20 rounded-2xl p-6 backdrop-blur-sm border border-accent/20 hover:border-accent/50 transition-all duration-300 cursor-pointer" | |
| onclick="window.location.href='/track-detail.html?slug=${track.slug}'"> | |
| <div class="flex items-start gap-4"> | |
| <div class="flex-shrink-0"> | |
| <img src="${track.cover || 'http://static.photos/monochrome/200x200/' + track.no}" | |
| alt="${track.title}" | |
| class="w-16 h-16 rounded-lg object-cover"> | |
| </div> | |
| <div class="flex-1"> | |
| <h3 class="font-bold text-lg mb-2">${track.no}. ${track.title}</h3> | |
| ${track.desc ? `<p class="text-gray-400 text-sm mb-3">${track.desc}</p>` : ''} | |
| ${track.tags && track.tags.length > 0 ? ` | |
| <div class="flex flex-wrap gap-1"> | |
| ${track.tags.map(tag => ` | |
| <span class="bg-magenta/20 text-magenta text-xs px-2 py-1 rounded-full"> | |
| ${tag} | |
| </span> | |
| `).join('')} | |
| </div> | |
| ` : ''} | |
| </div> | |
| </div> | |
| <div class="mt-4 flex items-center justify-between"> | |
| <span class="text-accent text-sm"> | |
| <i data-feather="play" class="inline w-4 h-4"></i> | |
| Play | |
| </span> | |
| ${track.embeds && track.embeds.length > 1 ? ` | |
| <span class="text-gray-400 text-sm"> | |
| +${track.embeds.length - 1} more | |
| </span> | |
| ` : ''} | |
| </div> | |
| </div> | |
| `).join(''); | |
| feather.replace(); | |
| } | |
| // Analytics functions | |
| function initializeAnalytics() { | |
| // Track page views | |
| trackEvent('page_view', { page: window.location.pathname }); | |
| } | |
| function trackEvent(eventName, properties = {}) { | |
| const eventData = { | |
| event: eventName, | |
| timestamp: new Date().toISOString(), | |
| ...properties | |
| }; | |
| console.log('Analytics Event:', eventData); | |
| // Here you would send to your analytics service | |
| // Example: gtag('event', eventName, properties); | |
| } | |
| // Provider switching functionality | |
| function switchProvider(trackSlug, provider, embedUrl) { | |
| trackEvent('provider_switch', { | |
| trackSlug: trackSlug, | |
| provider: provider | |
| }); | |
| // Update iframe source | |
| const iframe = document.querySelector(`[data-track="${trackSlug}"] iframe`); | |
| if (iframe) { | |
| iframe.src = embedUrl; | |
| } | |
| } | |
| // Share functionality | |
| function shareTrack(trackSlug, platform = 'copy') { | |
| const trackUrl = `${window.location.origin}/track-detail.html?slug=${trackSlug}`; | |
| trackEvent('share_click', { | |
| trackSlong: trackSlug, | |
| network: platform | |
| }); | |
| if (platform === 'copy') { | |
| navigator.clipboard.writeText(trackUrl).then(() => { | |
| alert('Track link copied to clipboard!'); | |
| }); | |
| } else if (platform === 'twitter') { | |
| window.open(`https://twitter.com/intent/tweet?text=Check out this track from Mr.FLEN's album "Still Lie Right Next to Me"&url=${encodeURIComponent(trackUrl)}`, '_blank'); | |
| } | |
| } | |
| // Admin functions | |
| function exportAlbumData() { | |
| const dataStr = JSON.stringify(albumData, null, 2); | |
| const dataBlob = new Blob([dataStr], { type: 'application/json' }); | |
| const url = URL.createObjectURL(dataBlob); | |
| const link = document.createElement('a'); | |
| link.href = url; | |
| link.download = 'album.json'; | |
| document.body.appendChild(link); | |
| link.click(); | |
| document.body.removeChild(link); | |
| trackEvent('admin_export_json'); | |
| } | |
| // Utility function to format duration | |
| function formatDuration(seconds) { | |
| const mins = Math.floor(seconds / 60); | |
| const secs = seconds % 60; | |
| return `${mins}:${secs.toString().padStart(2, '0')}`; | |
| } |