Reorganize Settings Library tab with collapsible sections

Three collapsible categories, collapsed by default:
- Paths & Organization (file templates + music library paths)
- Post-Processing (metadata, tags, conversion, lyrics)
- Library Preferences (import, content filter, stats, playlists, M3U)

Section headers have data-stg=library so they only appear on the
Library tab. Bolder headers with accent-colored arrows and subtle
border. Collapse state preserved when switching settings tabs.
pull/324/head
Broque Thomas 1 month ago
parent 841ad42fdd
commit f4aaab8a66

@ -5061,6 +5061,14 @@
</div>
</div>
<!-- ═══ PATHS & ORGANIZATION ═══ -->
<div class="settings-section-header collapsed" data-stg="library" onclick="this.classList.toggle('collapsed'); const b=this.nextElementSibling; b.classList.toggle('collapsed'); b.style.display=b.classList.contains('collapsed')?'none':''">
<span class="settings-section-arrow">&#9660;</span>
<h3>Paths &amp; Organization</h3>
<span class="settings-section-hint">File templates, music library paths</span>
</div>
<div class="settings-section-body collapsed" data-stg="library">
<!-- File Organization Settings -->
<div class="settings-group" data-stg="library">
<h3>📁 File Organization</h3>
@ -5135,6 +5143,34 @@
</div>
</div>
<!-- Music Library Paths (moved into Paths & Organization) -->
<div class="settings-group" data-stg="library">
<h3>📂 Music Library Paths</h3>
<div class="help-text" style="margin-bottom: 12px;">
Tell SoulSync where your music files live. Required for tag writing, streaming, and file detection
when your media server stores files at a different path than SoulSync can see.
<strong>Docker users:</strong> mount your music folder(s) into the SoulSync container with read-write access,
then add the <em>container-side</em> path here (e.g. <code>/music</code>).
</div>
<div id="music-paths-list"></div>
<div class="form-actions" style="margin-top: 8px;">
<button class="test-button" onclick="addMusicPathRow()">+ Add Path</button>
</div>
</div>
</div><!-- end Paths & Organization body -->
<!-- ═══ POST-PROCESSING ═══ -->
<div class="settings-section-header collapsed" data-stg="library" onclick="this.classList.toggle('collapsed'); const b=this.nextElementSibling; b.classList.toggle('collapsed'); b.style.display=b.classList.contains('collapsed')?'none':''">
<span class="settings-section-arrow">&#9660;</span>
<h3>Post-Processing</h3>
<span class="settings-section-hint">Metadata, tags, conversion, lyrics</span>
</div>
<div class="settings-section-body collapsed" data-stg="library">
<!-- Metadata Enhancement Settings -->
<div class="settings-group" data-stg="library">
<h3>🎵 Post-Processing</h3>
@ -5430,6 +5466,16 @@
</div>
</div>
</div><!-- end Post-Processing body -->
<!-- ═══ LIBRARY PREFERENCES ═══ -->
<div class="settings-section-header collapsed" data-stg="library" onclick="this.classList.toggle('collapsed'); const b=this.nextElementSibling; b.classList.toggle('collapsed'); b.style.display=b.classList.contains('collapsed')?'none':''">
<span class="settings-section-arrow">&#9660;</span>
<h3>Library Preferences</h3>
<span class="settings-section-hint">Import, content filter, playlists, stats</span>
</div>
<div class="settings-section-body collapsed" data-stg="library">
<!-- Listening Stats Settings -->
<div class="settings-group" data-stg="library">
<h3>📊 Listening Stats</h3>
@ -5627,25 +5673,6 @@
</div>
<!-- Music Library Paths -->
<div class="settings-group" data-stg="library">
<h3>📂 Music Library Paths</h3>
<div class="help-text" style="margin-bottom: 12px;">
Tell SoulSync where your music files live. Required for tag writing, streaming, and file detection
when your media server stores files at a different path than SoulSync can see.
<strong>Docker users:</strong> mount your music folder(s) into the SoulSync container with read-write access,
then add the <em>container-side</em> path here (e.g. <code>/music</code>).
</div>
<div id="music-paths-list"></div>
<div class="form-actions" style="margin-top: 8px;">
<button class="test-button" onclick="addMusicPathRow()">+ Add Path</button>
</div>
</div>
<!-- Content Filter Settings -->
<div class="settings-group" data-stg="library">
<h3>🔞 Content Filter</h3>
@ -5708,6 +5735,8 @@
</div>
</div>
</div><!-- end Library Preferences body -->
<!-- Logging Information (Read-only) -->
<div class="settings-group" data-stg="advanced">
<h3>Logging Information</h3>

@ -5737,10 +5737,14 @@ function validateFileOrganizationTemplates() {
function switchSettingsTab(tab) {
// Update tab bar
document.querySelectorAll('.stg-tab').forEach(t => t.classList.toggle('active', t.dataset.tab === tab));
// Show/hide settings groups by data-stg attribute
document.querySelectorAll('#settings-page .settings-group[data-stg]').forEach(g => {
// Show/hide settings groups and section headers by data-stg attribute
document.querySelectorAll('#settings-page [data-stg]').forEach(g => {
g.style.display = g.dataset.stg === tab ? '' : 'none';
});
// Re-apply collapsed state on section bodies (tab switch resets inline display)
document.querySelectorAll('#settings-page .settings-section-body.collapsed').forEach(b => {
b.style.display = 'none';
});
// Also hide/show the column wrappers if they're empty in this tab
document.querySelectorAll('#settings-page .settings-left-column, #settings-page .settings-right-column, #settings-page .settings-third-column').forEach(col => {
const hasVisible = Array.from(col.querySelectorAll('.settings-group[data-stg]')).some(g => g.style.display !== 'none');

@ -2993,6 +2993,59 @@ body.helper-mode-active #dashboard-activity-feed:hover {
}
/* Glassmorphic cards */
/* Collapsible settings section headers */
.settings-section-header {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 18px;
margin-bottom: 4px;
cursor: pointer;
border-radius: 12px;
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(255, 255, 255, 0.05);
transition: all 0.15s;
user-select: none;
}
.settings-section-header:hover {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.08);
}
.settings-section-header h3 {
margin: 0;
font-size: 17px;
font-weight: 700;
color: rgba(255, 255, 255, 0.95);
letter-spacing: 0.3px;
}
.settings-section-arrow {
font-size: 11px;
color: rgba(var(--accent-rgb), 0.7);
transition: transform 0.2s;
flex-shrink: 0;
}
.settings-section-header.collapsed .settings-section-arrow {
transform: rotate(-90deg);
}
.settings-section-hint {
font-size: 12px;
color: rgba(255, 255, 255, 0.35);
margin-left: auto;
}
.settings-section-body {
transition: all 0.2s ease;
}
.settings-section-body.collapsed {
display: none;
}
.settings-group {
background: linear-gradient(135deg, rgba(35, 35, 35, 0.6), rgba(20, 20, 20, 0.8));
border: 1px solid rgba(255, 255, 255, 0.08);

Loading…
Cancel
Save