web/desktop: grid + subtitle fixes, comment toggle, faster startup

Several related UI and startup fixes from one session:

- Web grid: channel and music views rendered in a single column because
  their content was wrapped in one nested div that became a single cell of
  the outer CSS grid. Span the wrappers (and .empty) across all columns
  with grid-column:1/-1.

- Subtitles: route every track through /api/sub-vtt and strip per-cue
  position/alignment settings (align:start position:0% etc.) from both SRT
  and VTT, so auto-generated captions render centered instead of left-
  aligned. New strip_cue_settings/normalize_vtt + sub_vtt_url helpers.

- Comment downloads: add a global backup.fetch_comments toggle (the
  per-channel option already existed; it's now a tri-state override that
  defers to the global). Full five-touchpoint wiring across config,
  download_options, the downloader's apply_comments resolver, both UIs'
  global + per-channel controls, and downloader seeding.

- Desktop startup: run the initial library scan + search-index sync on a
  background thread (mirrors the web server's deferred bind) so the window
  appears immediately instead of blocking on a cold-cache scan; update()
  swaps the library in when it lands.

- Perceptual dedup: cap worker threads via fingerprint::default_workers()
  (~half the cores, always leaving at least one free) instead of using
  every core, so the hashing pass doesn't starve the UI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-06-10 01:43:50 -07:00
parent fdc7493eb9
commit aed577ea2f
7 changed files with 245 additions and 50 deletions

View file

@ -134,6 +134,13 @@ pub struct BackupSection {
/// overrides live in [`crate::download_options::DownloadOptions`].
#[serde(default = "default_sponsorblock_mode")]
pub sponsorblock_mode: String,
/// Download the comment tree into each video's info.json sidecar via
/// yt-dlp `--write-comments`. Off by default — comment download is slow
/// (yt-dlp paginates through thousands of replies on popular videos).
/// When on, the player's Comments tab is populated. Per-channel overrides
/// live in [`crate::download_options::DownloadOptions`].
#[serde(default)]
pub fetch_comments: bool,
}
fn default_max_concurrent() -> usize { 3 }
@ -273,6 +280,7 @@ impl Config {
use_pot_provider: false,
youtube_player_clients: String::new(),
sponsorblock_mode: default_sponsorblock_mode(),
fetch_comments: false,
},
player: PlayerSection::default(),
ui: UiSection::default(),