added files

This commit is contained in:
minster586
2026-04-12 21:41:35 -04:00
parent 0bf58be735
commit a5b9e87eb9
3 changed files with 307 additions and 0 deletions

36
index.html Normal file
View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Radio DJ Now Playing</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="widget-container">
<!-- Blurred background layer -->
<div class="background-blur">
<img class="background-image" src="Album-Art.png" alt="Album backdrop">
</div>
<!-- Dark overlay for contrast -->
<div class="overlay"></div>
<!-- Content layer -->
<div class="widget-content">
<!-- Album art (left) -->
<div class="album-art-box">
<img class="album-art" src="Album-Art.png" alt="Album art">
</div>
<!-- Song info (right) -->
<div class="song-info">
<div class="song-title">Loading...</div>
<div class="song-artist">Loading...</div>
</div>
</div>
</div>
<script src="./script.js"></script>
</body>
</html>

128
script.js Normal file
View File

@@ -0,0 +1,128 @@
///////////////
// PARAMETERS //
///////////////
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const refreshRate = parseInt(urlParams.get("refreshrate")) || 6; // Default 6 seconds
// Image filename - update this if the backend changes the image path
const IMAGE_FILENAME = "Album-Art.png";
//////////////////
// GLOBAL STATE //
//////////////////
let currentArtist = "";
let currentTitle = "";
let refreshInterval = null;
//////////////////
// REFRESH LOGIC //
//////////////////
/**
* Fetches the artist and title from text files
*/
async function fetchSongData() {
try {
const artistResponse = await fetch("artist.txt");
const titleResponse = await fetch("title.txt");
if (!artistResponse.ok || !titleResponse.ok) {
console.error("Failed to fetch song data");
return null;
}
const artist = (await artistResponse.text()).trim();
const title = (await titleResponse.text()).trim();
return { artist, title };
} catch (error) {
console.error("Error fetching song data:", error);
return null;
}
}
/**
* Updates the DOM elements if the song data has changed
*/
function updateSongDisplay(artist, title) {
const titleElement = document.querySelector(".song-title");
const artistElement = document.querySelector(".song-artist");
let trackChanged = false;
// Only update if data has actually changed
if (title !== currentTitle) {
currentTitle = title;
titleElement.classList.add("updating");
titleElement.textContent = title || "Unknown Title";
trackChanged = true;
setTimeout(() => {
titleElement.classList.remove("updating");
}, 400);
}
if (artist !== currentArtist) {
currentArtist = artist;
artistElement.classList.add("updating");
artistElement.textContent = artist || "Unknown Artist";
trackChanged = true;
setTimeout(() => {
artistElement.classList.remove("updating");
}, 400);
}
// Return whether track changed (to trigger image update)
return trackChanged;
}
/**
* Updates both the album art and background image with cache-busting timestamp
* Only called when track actually changes
*/
function updateAlbumArt() {
const albumArt = document.querySelector(".album-art");
const backgroundImage = document.querySelector(".background-image");
const timestamp = new Date().getTime();
const imageUrl = `${IMAGE_FILENAME}?v=${timestamp}`;
albumArt.src = imageUrl;
backgroundImage.src = imageUrl;
}
/**
* Main refresh function - fetches data and updates if changed
*/
async function refresh() {
const data = await fetchSongData();
if (data) {
const trackChanged = updateSongDisplay(data.artist, data.title);
// Only update images when track actually changes
if (trackChanged) {
updateAlbumArt();
}
}
}
///////////////
// INITIALIZE //
///////////////
function init() {
// Load initial data immediately
refresh();
// Set up refresh interval based on URL parameter or default
refreshInterval = setInterval(refresh, refreshRate * 1000);
console.log(`Radio DJ widget initialized - refreshing every ${refreshRate}s`);
}
// Start when DOM is ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}

143
style.css Normal file
View File

@@ -0,0 +1,143 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #000;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
}
/* Main widget container */
.widget-container {
position: relative;
display: flex;
width: 100%;
max-width: 650px;
aspect-ratio: auto;
height: 200px;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.95);
margin: 20px;
}
/* Blurred background layer (z-index: 0) */
.background-blur {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
overflow: hidden;
}
.background-image {
width: 100%;
height: 100%;
object-fit: cover;
filter: blur(40px) brightness(0.6);
}
/* Dark overlay (z-index: 1) */
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1;
pointer-events: none;
}
/* Content layer (z-index: 2) */
.widget-content {
position: relative;
display: flex;
gap: 24px;
padding: 20px;
z-index: 2;
width: 100%;
height: 100%;
align-items: center;
}
/* Album art box (left) */
.album-art-box {
flex-shrink: 0;
width: 140px;
height: 140px;
border-radius: 10px;
overflow: hidden;
background: rgba(60, 60, 60, 0.5);
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.6);
}
.album-art {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Song info box (right) */
.song-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
gap: 4px;
min-width: 0;
padding: 0 12px;
}
/* Song title */
.song-title {
font-size: 30px;
font-weight: 700;
color: #ffffff;
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.9);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
letter-spacing: -0.5px;
line-height: 1.1;
}
/* Song artist */
.song-artist {
font-size: 22px;
font-weight: 500;
color: #ffffff;
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.9);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
letter-spacing: -0.3px;
line-height: 1.1;
opacity: 1;
}
/* Smooth fade animation for updates */
@keyframes fadeIn {
from {
opacity: 0.5;
}
to {
opacity: 1;
}
}
.song-title.updating,
.song-artist.updating {
animation: fadeIn 0.4s ease-in-out;
}