Skip to content

Quality badge primitives + Settings thresholds

Stacked on PR #39. Adds the visual layer that the upcoming Library page (PR 3) and artist detail page (PR 4) will lean on, plus a small immediate win on the existing List view.

What changes

  • $lib/qualityColor.ts — shared util mapping a score to green | yellow | red | gray against configurable thresholds. Defaults match the cutoffs already used by computeQualityScore (FLAC 16-bit = 80 → green, MP3 320 = 50 → yellow, lower → red, score 0 / null → gray).
  • getQualityThresholds / setQualityThresholds — backed by the existing settings key/value table (JSON-serialized).
  • +layout.server.ts — exposes thresholds on every page's load data so the badge can color itself without a fetch.
  • /api/settings/quality-thresholds — GET/POST. Server validates greenMin > yellowMin.
  • <QualityBadge> — three sizes:
    • dot (10px ring) for cramped overlay placements like cover thumbnails
    • sm (10px text pill) for list rows
    • md (12px text pill) for headers
  • <SegmentedControl> — extracted from the inline pill-button pattern in AlbumList.svelte, generic over the value type. PR 3 needs three of these stacked (Source, Type, View) so consolidating here.
  • Settings: Quality thresholds card — two number inputs with a four-badge live preview (Lossless / MP3 320 / MP3 192 / Unknown) that recolors as you adjust the cutoffs.
  • AlbumCard — gets a colored dot on the cover and the quality label appended to the artist/year metadata line. Immediate visual upgrade on the existing List view; the dot is dimensioned to fit the 48px cover.

Verification

  • pnpm run build passes.
  • / shows colored dots on cards. Albums without a quality_score show gray (covered by the score === 0 branch).
  • Open /settings, scroll to Quality thresholds, change the green min to 90, save, reload /. Cards previously green at 80 should now show as yellow.
  • POST /api/settings/quality-thresholds with {greenMin: 50, yellowMin: 60} returns 400.

Risk

UI-only and additive. Nothing existing reads qualityColor or thresholds yet, so the worst-case regression is the dot rendering at the wrong corner of a card. The Settings page picks up one new card between Playback and API Connections — no removals.

Merge request reports

Loading