WebUI: Retry/Quality settings as collapsible Downloads tiles; restore sidebar hover in reduce-effects

Settings reorg (Downloads page):
- Move the retry controls (retry next-best candidate, exhaustive retry,
  retries-per-query) out of the Post-Processing tile into a new collapsible
  "Retry Logic" tile on the Downloads tab (data-stg=downloads), collapsed by
  default. Also decouples them from the post-processing master toggle, which
  previously hid them when post-processing was disabled. Config keys are
  unchanged (still post_processing.*); settings.js binds by element id so the
  DOM move needs no JS change.
- Wrap the existing Quality Profile group in a matching collapsible tile,
  collapsed by default.

Sidebar (reduce-effects):
- The perf PR (#793) gated .nav-button hover/active-hover behind
  body:not(.reduce-effects), removing the highlight entirely in reduce-effects
  mode. Restore the highlight there using only cheap properties (flat
  background + border-color; the base already reserves a 1px transparent
  border so there's no layout shift) while keeping the expensive gradient /
  translateX transform / multi-layer box-shadow off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
dev 2026-06-05 22:05:10 +02:00
parent 6cb5d455f9
commit 63036a41ee
2 changed files with 60 additions and 19 deletions

View file

@ -4966,6 +4966,14 @@
</div>
<!-- ═══ QUALITY PROFILE ═══ -->
<div class="settings-section-header collapsed" data-stg="downloads" 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>Quality Profile</h3>
<span class="settings-section-hint">Format priorities, bitrate, bit depth</span>
</div>
<div class="settings-section-body collapsed" data-stg="downloads">
<!-- Quality Profile Settings (Soulseek only) -->
<div class="settings-group" id="quality-profile-section" data-stg="downloads">
<h3>🎵 Quality Profile</h3>
@ -5147,6 +5155,42 @@
</div>
</div>
</div><!-- end Quality Profile body -->
<!-- ═══ RETRY LOGIC ═══ -->
<div class="settings-section-header collapsed" data-stg="downloads" 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>Retry Logic</h3>
<span class="settings-section-hint">Next-best candidate, exhaustive per-source retry</span>
</div>
<div class="settings-section-body collapsed" data-stg="downloads">
<div class="settings-group" data-stg="downloads">
<h3>🔁 Retry Logic</h3>
<small class="settings-hint" style="margin-bottom: 10px; display: block;">Controls what happens when a downloaded file is rejected (AcoustID mismatch, wrong version, or duration/integrity failure). Independent of post-processing.</small>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="retry-next-candidate" checked>
Retry next-best candidate on mismatch
</label>
<small class="settings-hint">When a download is quarantined (AcoustID mismatch or duration/integrity failure), automatically try the next-best candidate instead of failing the track. Off = quarantine and fail immediately.</small>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="retry-exhaustive">
Exhaustive retry (separate budget per source)
</label>
<small class="settings-hint">Give every source (Soulseek, then HiFi/Tidal/…) its own retry budget. Each source spends <em>queries × retries-per-query</em> attempts before the track moves on. Worst case across two sources can mean many downloads — use for hard-to-match tracks (e.g. CJK artist names). Requires the option above.</small>
</div>
<div class="form-group">
<label for="retries-per-query">Retries per query (per source)</label>
<input type="number" id="retries-per-query" min="1" max="20" step="1" value="5" style="width: 100px;" autocomplete="off" data-bwignore="" data-1p-ignore="" data-lpignore="true">
<small class="settings-hint">In exhaustive mode, how many candidates to try per search query per source. The per-source budget is <em>number of search queries × this value</em>. Only used when Exhaustive retry is on.</small>
</div>
</div>
</div><!-- end Retry Logic body -->
<!-- ═══ INDEXERS & DOWNLOADERS ═══ -->
<!-- Intro hero — explains the search → fetch flow in one glance -->
<div class="settings-group ind-hero" data-stg="indexers">
@ -5563,25 +5607,6 @@
<input type="number" id="duration-tolerance-seconds" min="0" max="60" step="0.5" value="0" style="width: 100px;">
<small class="settings-hint">Maximum drift between the file's actual length and the metadata source's expected length before the file is quarantined. <strong>0 = auto</strong> (3s normal, 5s for tracks &gt;10min). Raise this if tracks routinely quarantine for being a few seconds off (live recordings, alternate masterings, etc). Capped at 60s.</small>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="retry-next-candidate" checked>
Retry next-best candidate on mismatch
</label>
<small class="settings-hint">When a download is quarantined (AcoustID mismatch or duration/integrity failure), automatically try the next-best candidate instead of failing the track. Off = quarantine and fail immediately.</small>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="retry-exhaustive">
Exhaustive retry (separate budget per source)
</label>
<small class="settings-hint">Give every source (Soulseek, then HiFi/Tidal/…) its own retry budget. Each source spends <em>queries × retries-per-query</em> attempts before the track moves on. Worst case across two sources can mean many downloads — use for hard-to-match tracks (e.g. CJK artist names). Requires the option above.</small>
</div>
<div class="form-group">
<label for="retries-per-query">Retries per query (per source)</label>
<input type="number" id="retries-per-query" min="1" max="20" step="1" value="5" style="width: 100px;" autocomplete="off" data-bwignore="" data-1p-ignore="" data-lpignore="true">
<small class="settings-hint">In exhaustive mode, how many candidates to try per search query per source. The per-source budget is <em>number of search queries × this value</em>. Only used when Exhaustive retry is on.</small>
</div>
</div>
<!-- Tag Embedding — per-tag toggles grouped by source -->

View file

@ -471,6 +471,22 @@ body:not(.reduce-effects) .nav-button.active:hover {
inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
/* Reduce-effects mode keeps the sidebar hover/active highlight the
feedback matters for navigation but only the CHEAP parts: a flat
background + border-color change (the base already reserves a 1px
transparent border, so no layout shift). The expensive full-effects
bits (gradient, transform/translateX, multi-layer box-shadow) stay
off so hovering doesn't trigger compositing/repaint churn. */
body.reduce-effects .nav-button:hover {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.08);
}
body.reduce-effects .nav-button.active:hover {
background: rgba(var(--accent-rgb), 0.18);
border-color: rgba(var(--accent-rgb), 0.3);
}
.nav-icon {
width: 40px;
height: 40px;