video: self-contained video Source section; hide music's server settings on video

Per the desired model: video Settings has its OWN server settings, separate from
music. The 'Video Source' group now holds the Plex/Jellyfin pick AND the Movies/TV
library mapping (moved out of music's Plex panel so it's not coupled to the music
active server). The whole MUSIC 'Server Connections' group is hidden on the video
side. Video reuses the shared Plex/Jellyfin credentials: the picker shows both
servers, the configured ones selectable, the rest 'not connected — set up in Music
settings'. Music settings keep their own server settings, untouched.
This commit is contained in:
BoulderBadgeDad 2026-06-15 15:10:53 -07:00
parent f93c211de3
commit 8f6f992670
3 changed files with 35 additions and 27 deletions

View file

@ -5133,12 +5133,23 @@
<!-- Video API Configuration (placeholders; shown only on the video
side in place of the music API services). Same structure as the
music service frames above. -->
<!-- Video Source (which Plex/Jellyfin the video side uses) -->
<!-- Video Source — the video side's OWN server pick + library
mapping, independent of the music server (it just reuses
the shared Plex/Jellyfin credentials). -->
<div class="settings-group" data-stg="connections" data-video-only>
<h3>Video Source</h3>
<div class="vid-source-panel" data-video-source-panel>
<div class="callback-help">Checking…</div>
</div>
<div class="form-group video-library-selectors" style="margin-top: 16px;">
<label>Movies Library:</label>
<select data-video-lib-select="movies"><option value="">Loading...</option></select>
<label style="margin-top: 12px;">TV Shows Library:</label>
<select data-video-lib-select="tv"><option value="">Loading...</option></select>
<small style="color: #999; font-size: 0.9em; display: block; margin-top: 5px;">
Which libraries the video side scans. <span data-video-lib-status></span>
</small>
</div>
</div>
<div class="settings-group" data-stg="connections" data-video-only>
<h3>API Configuration <button class="stg-accordion-toggle" onclick="toggleAllServiceAccordions(this)">Expand All</button></h3>
@ -5300,21 +5311,6 @@
Select which music library to use (doesn't affect config file)
</small>
</div>
<!-- Video side: which libraries are Movies / TV (shown only on the
video side; populated + saved by video/video-settings.js). -->
<div class="form-group video-library-selectors" data-video-only>
<label>Movies Library:</label>
<select data-video-lib-select="movies">
<option value="">Loading...</option>
</select>
<label style="margin-top: 12px;">TV Shows Library:</label>
<select data-video-lib-select="tv">
<option value="">Loading...</option>
</select>
<small style="color: #999; font-size: 0.9em; display: block; margin-top: 5px;">
Which libraries the video side scans. <span data-video-lib-status></span>
</small>
</div>
<div class="form-actions">
<button id="plex-config-action-button" class="detect-button" onclick="clearPlexConfiguration()">Clear Configuration</button>
</div>

View file

@ -28,24 +28,27 @@
.then(function (d) { renderServer(host, d || {}); })
.catch(function () { renderServer(host, {}); });
}
function srvBtn(id, label, active) {
return '<button class="vid-source-btn' + (id === active ? ' active' : '') +
function srvOpt(id, label, configured, selected) {
if (!configured) {
return '<button class="vid-source-btn vid-source-btn--off" type="button" disabled ' +
'title="Not connected — set it up in Music settings">' + label +
' <span class="vid-source-off">(not connected)</span></button>';
}
return '<button class="vid-source-btn' + (id === selected ? ' active' : '') +
'" type="button" data-video-server-pick="' + id + '">' + label + '</button>';
}
function renderServer(host, d) {
var plex = !!d.plex, jelly = !!d.jellyfin;
var html = '<div class="vid-source-pick">' +
srvOpt('plex', 'Plex', plex, d.server) + srvOpt('jellyfin', 'Jellyfin', jelly, d.server) + '</div>';
if (!plex && !jelly) {
host.innerHTML = '<div class="vid-source-none">No video server connected. ' +
'Connect <strong>Plex</strong> or <strong>Jellyfin</strong> under <em>Server Connections</em> ' +
'below to scan and browse your video library. <em>(Navidrome and Standalone are music-only.)</em></div>';
} else if (plex && jelly) {
host.innerHTML = '<div class="vid-source-pick">' +
srvBtn('plex', 'Plex', d.server) + srvBtn('jellyfin', 'Jellyfin', d.server) + '</div>' +
'<div class="callback-help">Both are connected — pick which one the video side uses.</div>';
html += '<div class="callback-help">Neither is connected yet. Set up Plex or Jellyfin in ' +
'<strong>Music &rarr; Settings &rarr; Server Connections</strong> — the video side reuses those credentials.</div>';
} else {
host.innerHTML = '<div class="vid-source-using"><span class="vid-source-check">✓</span> ' +
'Video uses <strong>' + (plex ? 'Plex' : 'Jellyfin') + '</strong></div>';
html += '<div class="callback-help">The video side uses this server, independent of Music. ' +
'Greyed-out options aren\'t connected — set them up in Music settings.</div>';
}
host.innerHTML = html;
}
function pickServer(id) {
fetch(SERVER_URL, {

View file

@ -140,6 +140,12 @@ body[data-side="video"] [data-music-only] {
body[data-side="video"] [data-stg="library"]:not([data-video-only]) {
display: none !important;
}
/* The video side has its OWN server section (Video Source above) and reuses the
shared Plex/Jellyfin credentials so hide music's Server Connections group
entirely on the video side. Video never configures or selects the MUSIC server. */
body[data-side="video"] .settings-group[data-stg="connections"]:not([data-video-only]) {
display: none !important;
}
/* ── Dashboard header: match music, minus the sweep animation ──────────── */
/* The header reuses music's .dashboard-header markup/CSS for an identical look;
@ -1479,6 +1485,9 @@ a.vd-guest:hover .vd-guest-name { color: rgb(var(--vd-accent-rgb)); }
}
.vid-source-btn:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.vid-source-btn.active { background: rgba(56, 189, 248, 0.9); border-color: transparent; color: #fff; }
.vid-source-btn--off { opacity: 0.45; cursor: not-allowed; }
.vid-source-btn--off:hover { background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.8); }
.vid-source-off { font-size: 11px; opacity: 0.85; }
/* library: no-server gate banner */
.video-noserver {