Commit Graph

14 Commits

Author SHA1 Message Date
8049d02457 feat(player): persist volume across sessions, default to 100%
Store the playback volume in app settings (config.json) whenever it
changes and re-apply the previous session's level at boot, instead of
always starting at the old 70% fallback.

- AppSettings gains volume (default 1 = 100%); both default-settings
  copies and the volume signal default are raised from 0.7 to 1.
- doSetVolume persists via the app store (mirrors playbackSpeed).
- The boot sync awaits the app store's async config load (new
  whenReady()) so a persisted level is applied even when settings load
  finishes after useAudio mounts.
- tests/volume-persistence.test.ts: default, clamp, and cross-session
  reuse (fresh module instance simulates the next launch).
2026-08-11 13:30:01 -04:00
1b55b7117c feat(player): restore the last player session at boot
Reload the episode that was loaded in the player when the previous run
ended (persisted on play/load and synchronously at exit) into the Player
tab paused at its saved position — never autostarted. Episodes at or
above 98% completion are skipped, as are empty-player and unsubscribed
episodes.

- useAudio gains load(episode) (sets currentEpisode/position/Now Playing
  without starting the backend) and restoreLastSession(), triggered once
  at boot and serialized through a chain so a late-finishing boot restore
  can't clobber later state.
- togglePlayback branches on a startedPlayback flag: a restored episode
  starts the backend from the saved position; a paused one resumes.
- stop() clears the marker; the exit teardown writes it synchronously
  (process.exit bypasses async writes).
- feed/progress stores expose whenReady() so restore waits for the async
  boot loads; feed store gains findEpisode().
- app-persistence serializes last-player marker writes and exposes
  waitForLastPlayerWrite() for deterministic tests.
- tests/restore-session.test.ts: real modules + local RSS feed server;
  the real useAudio is imported via a ?restore-test query suffix to
  bypass the suite's mock.module leak across shared bun workers.
2026-08-11 13:18:00 -04:00
2d7d49b91c feat(feed): periodic background refresh with failed-fetch guard
Self-rescheduling refresh timer (default 30 min, configurable via a
Preferences item, re-read on every tick, skips in-flight refreshes).
fetchEpisodes returns null on network failure/timeout so a failed
refresh can never wipe a feed's episodes (addFeed/refreshFeed/
refreshAllFeeds all treat null as unchanged); feeds still refresh on
launch.
2026-08-11 13:11:20 -04:00
df9c519439 feat(search): persist recent searches between sessions
History used localStorage, which never exists in the Bun TUI, so nothing
survived a restart. Store the 10 most recent queries in config-dir
search-history.json (same fire-and-forget file pattern as audio-nav.json),
loaded asynchronously at store init. Dedupe case-insensitively, cap at 10.
2026-08-11 12:45:43 -04:00
6134dea044 feat(settings): configurable selection marker, default off
Adds a Selection Marker toggle under Settings → Preferences that
controls the ❯ cursor glyph on the focused row of every list.
Default off; rows keep a leading space for alignment either way.
Every list pane (tab strip, feed, my shows, discover, search,
settings, whitelist editor) reads the glyph through the shared
useSelectionMarker hook.

Also aligns the lead column across panes: page list rows drop
their extra box paddingLeft so labels start at the same column
as the tab strip (2 cells without nerd icons, 4 with), keeping
episode sub-rows aligned to the title.
2026-08-10 20:54:39 -04:00
eb220386ce feat: global auto-download with count/scope/whitelist + d/D/w keybinds 2026-08-10 15:53:25 -04:00
4a94ff5910 feat: labeled loading spinners + [Fetch More] pagination on the feed list
Loading indicators: the braille spinner now carries a contextual label
(Refreshing…, Fetching…, Loading more…, Discovering…, Searching…) and is
shown in every loading state that previously rendered nothing — Discover
results, Search results fallback, and the empty Feed list.

Feed pagination: a focusable "[Fetch More]" row at the bottom of the flat
feed list advances every feed's loaded window by 50 episodes via the new
loadMoreAllFeeds/hasMoreAcrossAll store API. Behavior is a setting
(Fetch More: manual|auto, default manual) persisted in config.json; auto
fetches when focus reaches the bottom row. The button row is excluded
from episode focus so no episode is double-highlighted while it is active.
2026-08-10 10:38:20 -04:00
25307f83e9 fix: up highlight made legible for transparent bg, bring back mouse nav 2026-08-09 22:21:30 -04:00
2abdbaa4e9 cleaning up code 2026-08-09 09:54:52 -04:00
3ef19f80b8 drop oauth plan (copy config) 2026-08-08 07:10:59 -04:00
8e0f90f449 nonworking keybinds 2026-02-13 17:25:32 -05:00
75f1f7d6af remove migration code 2026-02-06 15:00:21 -05:00
e1dc242b1d better visualizer 2026-02-06 11:08:41 -05:00
168e6d5a61 final feature set 2026-02-05 22:55:24 -05:00