Search now covers individual episodes, not just shows: the iTunes Search API (entity=podcastEpisode) matches episode titles and show notes, so a guest or topic finds the episodes they appear in across shows. Enter on an episode result subscribes to the parent show. - types: SearchResult becomes a kind-discriminated union (podcast | episode); EpisodeSearchResult carries the parent show so existing consumers compile unchanged - source-searcher: searchEpisodesByType (RSS/CUSTOM return []), buildItunesEpisodeUrl, cleanDescription (HTML -> text), mapItunesEpisodeResult (episode id/duration ms->s/audioUrl, reuses mapItunesResult so delisted shows keep a directoryUrl) - search: searchEpisodes with an 'episode' cache/dedupe namespace so shows and episodes for the same query never mix - stores/search: scope signal (podcast | episode) persisted to podtui_search_scope; search() branches on scope - SearchPage: Shows/Episodes pills row with 'tab to toggle', scope- aware placeholder/empty state/result rows (episode row = title + Show · date) and preview; toggling re-runs the current query - keybinds: search-scope-toggle bound to tab (keybinds.jsonc AND the runtime DEFAULT_KEYBINDS merge so the binding exists for users with a pre-existing config file); while the input is focused the Shell router never sees Tab, so the input handles it via onKeyDown + preventDefault (no double-toggle: the router path only fires when the input is defocused) - Shell help overlay documents [tab] shows/episodes
86 lines
4.6 KiB
JSON
86 lines
4.6 KiB
JSON
{
|
|
// ── Yazi-style keybinds for PodTui ──────────────────────────────────────
|
|
// Notation:
|
|
// "j" single lowercase key
|
|
// "G" shift + g (uppercase letter = shift)
|
|
// "ctrl-d" ctrl modifier
|
|
// "shift-j" shift modifier (equivalent to "J")
|
|
// "meta-x" alt/meta modifier (macOS users: map Option to Alt)
|
|
// ["g","g"] a two-key sequence (matches only when pressed in order)
|
|
// "return" special key (also: escape tab space backspace up down left right)
|
|
//
|
|
// Yazi heritage: j/k move, h/l swipe between panes, Enter open, Space select,
|
|
// v visual mode, gg/G top/bottom, [ ] switch tabs, 1-6 goto tab,
|
|
// : / q command palette (q + Enter quits there), Q quick quit, ~ help.
|
|
// Audio transport kept on shifted keys / ctrl.
|
|
|
|
// ── Movement (within a pane) ─────────────────────────────────────────────
|
|
"move-down": ["j", "down"],
|
|
"move-up": ["k", "up"],
|
|
"page-down": ["ctrl-d"],
|
|
"page-up": ["ctrl-u"],
|
|
"full-down": ["ctrl-f"],
|
|
"full-up": ["ctrl-b"],
|
|
"jump-down": ["J"], // 5 lines down (shift+j)
|
|
"jump-up": ["K"], // 5 lines up (shift+k)
|
|
"goto-top": [["g", "g"]],
|
|
"goto-bottom": ["G"],
|
|
|
|
// ── Pane focus / swipe (yazi h/l) ────────────────────────────────────────
|
|
"swipe-prev": ["h", "left"], // focus left pane (parent)
|
|
"swipe-next": ["l", "right"], // focus right pane (preview)
|
|
|
|
// ── Open / activate ──────────────────────────────────────────────────────
|
|
"open": ["return", "enter"],
|
|
"open-interactive": ["shift-return"],
|
|
|
|
// ── Selection & visual mode ──────────────────────────────────────────────
|
|
"toggle-select": ["space"],
|
|
"visual-mode": ["v"],
|
|
"toggle-all": ["ctrl-a"],
|
|
"invert-all": ["ctrl-r"],
|
|
"escape": ["escape", "ctrl-["],
|
|
|
|
// ── Tabs ──────────────────────────────────────────────────────────────────
|
|
"tab-prev": ["["],
|
|
"tab-next": ["]"],
|
|
"tab-goto-1": ["1"],
|
|
"tab-goto-2": ["2"],
|
|
"tab-goto-3": ["3"],
|
|
"tab-goto-4": ["4"],
|
|
"tab-goto-5": ["5"],
|
|
"tab-goto-6": ["6"],
|
|
|
|
// ── Command palette & help & quit ────────────────────────────────────────
|
|
// q opens the command palette (neovim-style: type q + Enter to quit there).
|
|
// Q (shift+q) is the instant quick quit. ctrl-c also quits.
|
|
"command": [":", "q"],
|
|
"quit": ["Q", "ctrl-c"],
|
|
"help": ["~", "f1"],
|
|
|
|
// ── List operations (yazi: s search, f filter, , sort, . hidden, r refresh)
|
|
"search": ["s"],
|
|
// tab toggles the Search page between show and episode scope (re-runs the
|
|
// current query when viewing results)
|
|
"search-scope-toggle": ["tab"],
|
|
"filter": ["f"],
|
|
"sort": [","],
|
|
"toggle-hidden": ["."],
|
|
"refresh": ["r"],
|
|
"unsubscribe": ["x"], // unsubscribe focused show in My Shows
|
|
|
|
// ── Downloads & auto-download whitelist ───────────────────────────────────
|
|
"download": ["d"], // download the focused episode (detail pane)
|
|
"delete-download": ["D"], // delete the focused episode's download (if any)
|
|
"whitelist-toggle": ["w"], // add/remove the focused show from the auto-download whitelist (My Shows)
|
|
|
|
// ── Audio transport (preserved) ──────────────────────────────────────────
|
|
// Kept on shifted single keys so they never collide with the yazi core
|
|
// (space=select, s=search, f=filter, etc.). Edit freely in this file.
|
|
"audio-toggle": ["P"], // play / pause (shift+p)
|
|
"audio-next": ["N"], // next episode (shift+n)
|
|
"audio-prev": ["B"], // prev episode (shift+b)
|
|
"audio-seek-forward": ["shift-."], // seek forward (> = shift+.)
|
|
"audio-seek-backward": ["shift-,"] // seek backward (< = shift+,)
|
|
}
|