[feat](trx-frontend-http): display RDS PS name overlay on overview strip
When a WFM/SDR spectrum stream carries RDS data, show the Program Service name (8-char station name) centered on the visible waveform area in DSEG14 monospace — the same font as the frequency display. - Add #rds-ps-overlay div inside .overview-strip (pointer-events: none, z-index: 2, absolutely positioned at the center of the visible canvas) - updateRdsPsOverlay(rds) shows/hides and updates text on every spectrum frame; trims trailing spaces common in RDS PS strings - Overlay cleared on spectrum disconnect / null frame - text-shadow uses CSS color-mix against --bg for legibility across all style/theme combinations Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -330,6 +330,7 @@ const overviewPeakHoldEl = document.getElementById("overview-peak-hold");
|
|||||||
const themeToggleBtn = document.getElementById("theme-toggle");
|
const themeToggleBtn = document.getElementById("theme-toggle");
|
||||||
const headerRigSwitchSelect = document.getElementById("header-rig-switch-select");
|
const headerRigSwitchSelect = document.getElementById("header-rig-switch-select");
|
||||||
const headerStylePickSelect = document.getElementById("header-style-pick-select");
|
const headerStylePickSelect = document.getElementById("header-style-pick-select");
|
||||||
|
const rdsPsOverlay = document.getElementById("rds-ps-overlay");
|
||||||
let overviewPeakHoldMs = Number(loadSetting("overviewPeakHoldMs", 2000));
|
let overviewPeakHoldMs = Number(loadSetting("overviewPeakHoldMs", 2000));
|
||||||
|
|
||||||
let overviewDrawPending = false;
|
let overviewDrawPending = false;
|
||||||
@@ -2793,6 +2794,7 @@ function startSpectrumStreaming() {
|
|||||||
overviewWaterfallRows = [];
|
overviewWaterfallRows = [];
|
||||||
scheduleOverviewDraw();
|
scheduleOverviewDraw();
|
||||||
clearSpectrumCanvas();
|
clearSpectrumCanvas();
|
||||||
|
updateRdsPsOverlay(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -2800,6 +2802,7 @@ function startSpectrumStreaming() {
|
|||||||
pushOverviewWaterfallFrame(lastSpectrumData);
|
pushOverviewWaterfallFrame(lastSpectrumData);
|
||||||
refreshCenterFreqDisplay();
|
refreshCenterFreqDisplay();
|
||||||
scheduleSpectrumDraw();
|
scheduleSpectrumDraw();
|
||||||
|
updateRdsPsOverlay(lastSpectrumData.rds);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
};
|
};
|
||||||
spectrumSource.onerror = () => {
|
spectrumSource.onerror = () => {
|
||||||
@@ -2824,6 +2827,7 @@ function stopSpectrumStreaming() {
|
|||||||
lastSpectrumData = null;
|
lastSpectrumData = null;
|
||||||
overviewWaterfallRows = [];
|
overviewWaterfallRows = [];
|
||||||
scheduleOverviewDraw();
|
scheduleOverviewDraw();
|
||||||
|
updateRdsPsOverlay(null);
|
||||||
clearSpectrumCanvas();
|
clearSpectrumCanvas();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2835,6 +2839,17 @@ function clearSpectrumCanvas() {
|
|||||||
ctx.fillRect(0, 0, spectrumCanvas.width, spectrumCanvas.height);
|
ctx.fillRect(0, 0, spectrumCanvas.width, spectrumCanvas.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateRdsPsOverlay(rds) {
|
||||||
|
if (!rdsPsOverlay) return;
|
||||||
|
const ps = rds?.program_service?.trim();
|
||||||
|
if (ps) {
|
||||||
|
rdsPsOverlay.textContent = ps;
|
||||||
|
rdsPsOverlay.style.display = "";
|
||||||
|
} else {
|
||||||
|
rdsPsOverlay.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function scheduleSpectrumDraw() {
|
function scheduleSpectrumDraw() {
|
||||||
if (spectrumDrawPending) return;
|
if (spectrumDrawPending) return;
|
||||||
spectrumDrawPending = true;
|
spectrumDrawPending = true;
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="overview-strip">
|
<div class="overview-strip">
|
||||||
<canvas id="overview-canvas" aria-hidden="true"></canvas>
|
<canvas id="overview-canvas" aria-hidden="true"></canvas>
|
||||||
|
<div id="rds-ps-overlay" aria-live="polite" aria-label="RDS station name"></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Auth gate (hidden by default, shown if auth is required) -->
|
<!-- Auth gate (hidden by default, shown if auth is required) -->
|
||||||
<div id="auth-gate" style="display:none; max-width: 30rem; margin: 0 auto 0.9rem; padding: 1.25rem 0 1.5rem; text-align: center;">
|
<div id="auth-gate" style="display:none; max-width: 30rem; margin: 0 auto 0.9rem; padding: 1.25rem 0 1.5rem; text-align: center;">
|
||||||
|
|||||||
@@ -411,6 +411,22 @@ small { color: var(--text-muted); }
|
|||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
#rds-ps-overlay {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(var(--header-waterfall-overlap) + clamp(4.2rem, 11vh, 6.25rem) / 2);
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 2;
|
||||||
|
pointer-events: none;
|
||||||
|
font-family: 'DSEG14 Classic', monospace;
|
||||||
|
font-size: 2rem;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
color: var(--text-heading);
|
||||||
|
opacity: 0.88;
|
||||||
|
text-shadow: 0 1px 8px color-mix(in srgb, var(--bg) 60%, transparent);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
.overview-toolbar {
|
.overview-toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user