Fixed text alignment for 'Compact' theme

This commit is contained in:
nutty
2026-07-23 21:14:12 +10:00
parent 191e0ab504
commit f4406bbd45
6 changed files with 64 additions and 78 deletions
+4
View File
@@ -4,6 +4,7 @@ const urlParams = new URLSearchParams(queryString);
const settingsJson = urlParams.get("settingsJson") || ""; const settingsJson = urlParams.get("settingsJson") || "";
const widgetURL = urlParams.get("widgetURL") || ""; const widgetURL = urlParams.get("widgetURL") || "";
const showUnmuteIndicator = GetBooleanParam("showUnmuteIndicator", false); const showUnmuteIndicator = GetBooleanParam("showUnmuteIndicator", false);
const useStreamerBot = GetBooleanParam("usesStreamerBot", false);
// Page elements // Page elements
const widgetUrlInputWrapper = document.getElementById('widgetUrlInputWrapper'); const widgetUrlInputWrapper = document.getElementById('widgetUrlInputWrapper');
@@ -318,6 +319,9 @@ function RefreshWidgetPreview() {
} }
function UpdateStreamerBotConnection() { function UpdateStreamerBotConnection() {
if (!useStreamerBot)
return;
let addressElement = document.getElementById('address'); let addressElement = document.getElementById('address');
let portElement = document.getElementById('port'); let portElement = document.getElementById('port');
+2 -12
View File
@@ -75,18 +75,6 @@ else
// Set text alignment // Set text alignment
document.documentElement.style.setProperty('--text-alignment', `${textAlignment}`); document.documentElement.style.setProperty('--text-alignment', `${textAlignment}`);
switch (textAlignment)
{
case 'left':
document.documentElement.style.setProperty('--justify-content', `flex-start`);
break;
case 'center':
document.documentElement.style.setProperty('--justify-content', `center`);
break;
case 'right':
document.documentElement.style.setProperty('--justify-content', `flex-end`);
break;
}
// Set vertical alignment // Set vertical alignment
switch (verticalAlignment) { switch (verticalAlignment) {
@@ -199,11 +187,13 @@ async function FetchMedia() {
} }
window.addEventListener('DOMContentLoaded', () => { window.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
// Start polling every 1000 milliseconds // Start polling every 1000 milliseconds
setInterval(FetchMedia, 1000); setInterval(FetchMedia, 1000);
// Run once immediately on script load // Run once immediately on script load
FetchMedia(); FetchMedia();
}, 100);
}); });
+4 -1
View File
@@ -15,9 +15,12 @@ settingsJSON = "?settingsJson=" + baseURL + "settings.json";
const lastSlashIndex = baseURL.lastIndexOf("/"); const lastSlashIndex = baseURL.lastIndexOf("/");
let widgetURL = "&widgetURL=" + baseURL.replace("/settings", ""); let widgetURL = "&widgetURL=" + baseURL.replace("/settings", "");
const usesStreamerBot = "&usesStreamerBot=false";
console.debug("Window Ref: " + window.location.href); console.debug("Window Ref: " + window.location.href);
console.debug("Base URL: " + baseURL); console.debug("Base URL: " + baseURL);
console.debug("Settings JSON: " + settingsJSON); console.debug("Settings JSON: " + settingsJSON);
console.debug("Widget URL: " + widgetURL); console.debug("Widget URL: " + widgetURL);
console.debug("Uses Streamer Bot: " + usesStreamerBot);
widgetContainer.src = settingsPageURL + settingsJSON + widgetURL; widgetContainer.src = settingsPageURL + settingsJSON + widgetURL + usesStreamerBot;
+2 -8
View File
@@ -1,17 +1,11 @@
<div id="main-wrapper"> <div id="main-wrapper">
<div id="song-info-container"> <div id="song-info-container">
<div id="progress-bar-track" class="progress"> <div id="progress-bar-track" class="progress">
<label id="song-label-background" class="text-label"> <label id="song-label-background" class="text-label"></label>
<span id="track-label-background"></span>
<span id="artist-label-background"></span>
</label>
</div> </div>
<div id="progress-bar" class="progress"> <div id="progress-bar" class="progress">
<label id="song-label" class="text-label"> <label id="song-label" class="text-label"></label>
<span id="track-label"></span>
<span id="artist-label"></span>
</label>
</div> </div>
</div> </div>
</div> </div>
+25 -21
View File
@@ -7,10 +7,6 @@ const albumArtContainer = document.getElementById('album-art-container');
const songInfoContainer = document.getElementById('song-info-container'); const songInfoContainer = document.getElementById('song-info-container');
const progressBar = document.getElementById('progress-bar'); const progressBar = document.getElementById('progress-bar');
const progressBarTrack = document.getElementById('progress-bar-track'); const progressBarTrack = document.getElementById('progress-bar-track');
const trackLabel = document.getElementById('track-label');
const artistLabel = document.getElementById('artist-label');
const trackLabelBackground = document.getElementById('track-label-background');
const artistLabelBackground = document.getElementById('artist-label-background');
const songLabel = document.getElementById('song-label'); const songLabel = document.getElementById('song-label');
const songLabelBackground = document.getElementById('song-label-background'); const songLabelBackground = document.getElementById('song-label-background');
@@ -24,10 +20,10 @@ const songLabelBackground = document.getElementById('song-label-background');
const themeVariant = window.ThemeVariant ? window.ThemeVariant : ''; const themeVariant = window.ThemeVariant ? window.ThemeVariant : '';
// Set property visibility // Set property visibility
trackLabel.style.display = showPrimary ? '' : 'none'; if (!showPrimary)
artistLabel.style.display = showSecondary ? '' : 'none'; document.documentElement.style.setProperty('--show-primary', `none`);
trackLabelBackground.style.display = showPrimary ? '' : 'none'; if (!showSecondary)
artistLabelBackground.style.display = showSecondary ? '' : 'none'; document.documentElement.style.setProperty('--show-secondary', `none`);
// Set container width // Set container width
if (maxWidth > 0) if (maxWidth > 0)
@@ -48,10 +44,6 @@ async function ChangeTrack(mediaProps, accentColorPalette) {
// Wait for fade (0.5s), then swap the real text and hide overlay // Wait for fade (0.5s), then swap the real text and hide overlay
setTimeout(() => { setTimeout(() => {
// trackLabel.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title;
// artistLabel.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist;
// trackLabelBackground.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title;
// artistLabelBackground.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist;
if (swapArtistTrack) { if (swapArtistTrack) {
SetSongInfo(mediaProps.Artist, mediaProps.Title); SetSongInfo(mediaProps.Artist, mediaProps.Title);
} else { } else {
@@ -131,7 +123,13 @@ function UpdateSingleSongLabel(containerId, trackName, artistName) {
const container = document.getElementById(containerId); const container = document.getElementById(containerId);
if (!container) return; if (!container) return;
// 1. Structure the inner HTML with a wrapper so we can measure exact inline width let scrollContent = container.querySelector('.scroll-content');
// Only rebuild the HTML structure if the text content actually changed or doesn't exist yet
const currentTrackEl = container.querySelector('.track-label');
const currentArtistEl = container.querySelector('.artist-label');
if (!scrollContent || !currentTrackEl || currentTrackEl.textContent !== trackName || currentArtistEl.textContent !== artistName) {
container.classList.remove('is-overflowing'); container.classList.remove('is-overflowing');
container.innerHTML = ` container.innerHTML = `
<span class="scroll-content"> <span class="scroll-content">
@@ -139,30 +137,36 @@ function UpdateSingleSongLabel(containerId, trackName, artistName) {
<span class="artist-label">${artistName}</span> <span class="artist-label">${artistName}</span>
</span> </span>
`; `;
scrollContent = container.querySelector('.scroll-content');
}
const scrollContent = container.querySelector('.scroll-content'); // Encapsulate measurement logic so it can be called safely by the observer
const updateMetrics = () => {
scrollContent = container.querySelector('.scroll-content');
// 2. Measure total width of (Track + Artist) against parent width
const textWidth = scrollContent.scrollWidth; const textWidth = scrollContent.scrollWidth;
const containerWidth = container.clientWidth; const containerWidth = container.clientWidth;
const overflowDistance = textWidth - containerWidth; const overflowDistance = textWidth - containerWidth;
// 3. If the combined row overflows, set the CSS variables and add class
if (overflowDistance > 0) { if (overflowDistance > 0) {
const distancePercent = (overflowDistance / textWidth) * 100; const distancePercent = (overflowDistance / textWidth) * 100;
const travelTime = overflowDistance / SCROLL_SPEED_PX_PER_SEC; const travelTime = overflowDistance / SCROLL_SPEED_PX_PER_SEC;
const totalDuration = (travelTime * 2) + 3; // 3 seconds total for start/end pauses const totalDuration = (travelTime * 2) + 3;
scrollContent.style.setProperty('--scroll-distance', `-${distancePercent}%`); container.style.setProperty('--scroll-distance', `-${distancePercent}%`);
container.style.setProperty('--marquee-duration', `${totalDuration}s`); container.style.setProperty('--marquee-duration', `${totalDuration}s`);
container.classList.add('is-overflowing'); container.classList.add('is-overflowing');
} else {
container.classList.remove('is-overflowing');
} }
};
// 4. Attach ResizeObserver once to handle responsive window resizes updateMetrics();
// Attach ResizeObserver once to update metrics only (No recursive function resets!)
if (!container._resizeObserver) { if (!container._resizeObserver) {
container._resizeObserver = new ResizeObserver(() => { container._resizeObserver = new ResizeObserver(() => {
UpdateSingleSongLabel(containerId, trackName, artistName); updateMetrics();
}); });
container._resizeObserver.observe(container); container._resizeObserver.observe(container);
} }
+6 -15
View File
@@ -26,13 +26,10 @@
/* The content sits on top */ /* The content sits on top */
#progress-bar { #progress-bar {
grid-area: stack;
position: relative; position: relative;
z-index: 2; /* Sits above the progress bar */ z-index: 2; /* Sits above the progress bar */
transition: all 1s ease-in-out; transition: all 1s ease-in-out;
width: 100%; width: 100%;
/* mask-image: linear-gradient(to right, black calc(100% - 4em), transparent 100%);
-webkit-mask-image: linear-gradient(to right, black calc(100% - 4em), transparent 100%); */
} }
#progress-bar-track { #progress-bar-track {
@@ -44,20 +41,13 @@
padding: 0.25em 0.75em; padding: 0.25em 0.75em;
grid-area: stack; grid-area: stack;
display: flex; display: flex;
/* justify-content: center; */
min-width: 0; min-width: 0;
} }
#song-label, #song-label,
#song-label-background { #song-label-background {
font-size: 1em; width: 100%;
display: flex; text-align: var(--text-alignment);
flex-direction: row;
align-items: baseline;
gap: 0.5em;
min-width: 100%;
justify-content: var(--justify-content);
overflow: hidden;
} }
#artist-label, #artist-label,
@@ -67,8 +57,7 @@
opacity: 0.7; opacity: 0.7;
} }
#track-label, #track-label {
#track-label-background {
font-weight: 700; font-weight: 700;
} }
@@ -81,7 +70,7 @@
#song-label-background .scroll-content { #song-label-background .scroll-content {
display: inline-flex; display: inline-flex;
flex-direction: row; flex-direction: row;
align-items: baseline; align-items: center;
gap: 0.5em; /* Spacing between Track and Artist */ gap: 0.5em; /* Spacing between Track and Artist */
white-space: nowrap; white-space: nowrap;
will-change: transform; will-change: transform;
@@ -90,12 +79,14 @@
/* Preserve original font weights */ /* Preserve original font weights */
.track-label { .track-label {
font-weight: 700; font-weight: 700;
display: var(--show-primary);
} }
.artist-label { .artist-label {
font-size: 0.8em; font-size: 0.8em;
font-weight: 400; font-weight: 400;
opacity: 0.7; opacity: 0.7;
display: var(--show-secondary);
} }
/* Marquee scroll animation */ /* Marquee scroll animation */