Skip to content

Global customization: startup route, default sorts, layout, icons, playbar labels, format templates, table columns#357

Merged
LargeModGames merged 4 commits into
mainfrom
feat/global-customization
Jul 9, 2026
Merged

Global customization: startup route, default sorts, layout, icons, playbar labels, format templates, table columns#357
LargeModGames merged 4 commits into
mainfrom
feat/global-customization

Conversation

@LargeModGames

@LargeModGames LargeModGames commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Makes nearly every part of the UI configurable via config.yml and the Settings screen.

What's new

  • Startup route (behavior.startup_route): open on Home, Recently Played, Podcasts, Discover, Artists, or Saved Albums. The screen's data is fetched at startup so it arrives populated.
  • Per-screen default sorting (default_sort_playlist_tracks / _saved_albums / _saved_artists / _recently_played): field or field:desc, validated against each screen's available fields. Recently Played gets real sort state (config-seeded, applied on fetch).
  • Layout arrangement: sidebar_position: left|right|hidden (hidden auto-reveals while the sidebar has focus), playbar_position: bottom|top, configurable responsive breakpoints (small_terminal_width/_height). Layout math is unified in core/layout.rs and shared by rendering and mouse hit-testing, so hitboxes match in every arrangement by construction.
  • Icons: new fields for the gauge fill, sort arrows, episode-played marker, active-source dot, and list cursor, plus a new Icons Settings tab. Fixed-cell glyphs are width-validated (one terminal column) where table alignment depends on it.
  • Playbar control labels (behavior.playbar_control_labels): relabel the clickable playbar buttons; hitboxes resize to fit.
  • Format templates (format:): the playbar status line and window title are {key} templates (new core/format.rs, zero deps); defaults reproduce the previous output.
  • Table columns (tables:): reorder, remove, rename, and resize the columns of every track/album/podcast table (new tui/ui/columns.rs registry).
  • Behavior constants: status_message_ttl_percent, playback_poll_seconds, table_scroll_padding, like_animation_frames.

Safe by default

Structural config errors (unknown sort field, bad template key, invalid column id, too-wide icon, unknown label key) warn and fall back to the built-in default instead of aborting startup, so a config typo can never brick the app. Only YAML syntax errors and the pre-existing numeric range checks remain fatal.

Docs

  • docs/configuration.md: full customization guide (valid values per field, template placeholder tables, column ids per table)
  • examples/config.example.yml: commented example covering every new section, guarded by a test that runs it through the real loader

Testing

  • cargo fmt / clippy -D warnings (slim) clean; full default-features build compiles
  • 384 tests pass, including new coverage: layout/hitbox alignment render tests (wide + narrow), degrade-instead-of-error loading, column width cross-validation (zero widths, >100% sums), recoverable missing column id, recently-played sort seeding, example-config round-trip
  • Manually smoke-tested: startup route with data, right sidebar + top playbar with mouse clicks, relabeled playbar buttons, custom templates/columns/icons, oversized scroll padding still scrolls, deliberate config typo degrades with a warning

@LargeModGames LargeModGames merged commit c90430e into main Jul 9, 2026
15 checks passed
@LargeModGames LargeModGames deleted the feat/global-customization branch July 9, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant