diff --git a/gui/src/bindings/HelpStrings.ts b/gui/src/bindings/HelpStrings.ts index 1ded308a..fdba8b68 100644 --- a/gui/src/bindings/HelpStrings.ts +++ b/gui/src/bindings/HelpStrings.ts @@ -1,3 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type HelpStrings = { arrow_key_template: string, key_alternative_template: string, next_page: string, previous_page: string, playlist_start: string, playlist_end: string, current_album: string, current_artist_albums: string, current_context: string, volume_up: string, volume_down: string, next_track: string, previous_track: string, force_previous_track: string, seek_backward: string, seek_forward: string, toggle_shuffle: string, copy_song_url: string, copy_album_url: string, cycle_repeat: string, move_left: string, move_down: string, move_up: string, move_right: string, list_top: string, list_middle: string, list_bottom: string, search: string, filter_help: string, search_playlist_picker: string, filter_settings: string, toggle_playback: string, active_mode: string, audio_analysis: string, visualizer_style: string, lyrics_view: string, lyrics_scroll: string, lyrics_follow: string, lyrics_timing: string, miniplayer: string, cover_art: string, back: string, source_device: string, settings_open: string, settings_save: string, settings_button: string, hover_mode: string, save_track: string, add_selected_to_playlist: string, add_playing_to_playlist: string, quick_add_playing: string, sidebar_narrower: string, sidebar_wider: string, panels_shorter: string, panels_taller: string, layout_reset: string, remove_playlist_track: string, search_playlist: string, clear_playlist_filter: string, play_selection: string, recommendations: string, artist_tracks: string, search_submit: string, cursor_left: string, cursor_right: string, input_clear: string, input_delete_before: string, input_delete_after: string, input_delete_word: string, input_start: string, input_end: string, input_escape: string, album_delete: string, artist_unfollow: string, show_remove: string, playlist_delete: string, playlist_mirror: string, radio_remove: string, follow_artist_playlist: string, album_save: string, playlist_random: string, episode_sort: string, show_follow: string, show_unfollow: string, queue_add: string, queue_show: string, queue_remove: string, queue_move: string, queue_play: string, toggle_saved: string, radio_favorite: string, listening_recap: string, stats_open: string, stats_period: string, stats_play: string, playlist_sync_open: string, playlist_sync_run: string, playlist_sync_remove: string, sort_open: string, party_open: string, dj_open: string, dj_auto_queue: string, dj_vibe: string, dj_fresh: string, dj_model: string, pane_detach: string, pane_close: string, pane_focus_left: string, pane_focus_down: string, pane_focus_up: string, pane_focus_right: string, pane_move_left: string, pane_move_down: string, pane_move_up: string, pane_move_right: string, pane_rotate: string, pane_grow: string, pane_shrink: string, pane_reset: string, context_pagination: string, context_general: string, context_general_playlist_search: string, context_help: string, context_playlist_picker: string, context_settings: string, context_lyrics: string, context_selected_block: string, context_add_track: string, context_playbar: string, context_global: string, context_layout: string, context_playlist_tracks: string, context_filtered_playlist_tracks: string, context_library_artists: string, context_search_input: string, context_library_albums: string, context_artist_unfollow: string, context_library_podcasts: string, context_playlist: string, context_radio: string, context_search_results: string, context_save_album: string, context_selected_playlist: string, context_selected_show: string, context_hovered_track: string, context_queue: string, context_stats: string, context_playlist_sync: string, context_sortable_lists: string, context_ai_dj: string, library_sidebar: string, title: string, column_description: string, column_event: string, column_context: string, no_matches_template: string, filter_prompt: string, filter_edit_hint: string, matches_template: string, filter_count_hint_template: string, filter_hint: string, needs_spotify: string, not_for_source_template: string, only_for_source_template: string, unavailable_description_template: string, }; +export type HelpStrings = { arrow_key_template: string, key_alternative_template: string, next_page: string, previous_page: string, playlist_start: string, playlist_end: string, current_album: string, current_artist_albums: string, current_context: string, volume_up: string, volume_down: string, next_track: string, previous_track: string, force_previous_track: string, seek_backward: string, seek_forward: string, toggle_shuffle: string, copy_song_url: string, copy_album_url: string, cycle_repeat: string, move_left: string, move_down: string, move_up: string, move_right: string, list_top: string, list_middle: string, list_bottom: string, search: string, filter_help: string, search_playlist_picker: string, filter_settings: string, toggle_playback: string, active_mode: string, audio_analysis: string, visualizer_style: string, lyrics_view: string, lyrics_scroll: string, lyrics_follow: string, lyrics_timing: string, lyrics_seek: string, miniplayer: string, cover_art: string, back: string, source_device: string, settings_open: string, settings_save: string, settings_button: string, hover_mode: string, save_track: string, add_selected_to_playlist: string, add_playing_to_playlist: string, quick_add_playing: string, sidebar_narrower: string, sidebar_wider: string, panels_shorter: string, panels_taller: string, layout_reset: string, remove_playlist_track: string, search_playlist: string, clear_playlist_filter: string, play_selection: string, recommendations: string, artist_tracks: string, search_submit: string, cursor_left: string, cursor_right: string, input_clear: string, input_delete_before: string, input_delete_after: string, input_delete_word: string, input_start: string, input_end: string, input_escape: string, album_delete: string, artist_unfollow: string, show_remove: string, playlist_delete: string, playlist_mirror: string, radio_remove: string, follow_artist_playlist: string, album_save: string, playlist_random: string, episode_sort: string, show_follow: string, show_unfollow: string, queue_add: string, queue_show: string, queue_remove: string, queue_move: string, queue_play: string, toggle_saved: string, radio_favorite: string, listening_recap: string, stats_open: string, stats_period: string, stats_play: string, playlist_sync_open: string, playlist_sync_run: string, playlist_sync_remove: string, sort_open: string, party_open: string, dj_open: string, dj_auto_queue: string, dj_vibe: string, dj_fresh: string, dj_model: string, pane_detach: string, pane_close: string, pane_focus_left: string, pane_focus_down: string, pane_focus_up: string, pane_focus_right: string, pane_move_left: string, pane_move_down: string, pane_move_up: string, pane_move_right: string, pane_rotate: string, pane_grow: string, pane_shrink: string, pane_reset: string, context_pagination: string, context_general: string, context_general_playlist_search: string, context_help: string, context_playlist_picker: string, context_settings: string, context_lyrics: string, context_selected_block: string, context_add_track: string, context_playbar: string, context_global: string, context_layout: string, context_playlist_tracks: string, context_filtered_playlist_tracks: string, context_library_artists: string, context_search_input: string, context_library_albums: string, context_artist_unfollow: string, context_library_podcasts: string, context_playlist: string, context_radio: string, context_search_results: string, context_save_album: string, context_selected_playlist: string, context_selected_show: string, context_hovered_track: string, context_queue: string, context_stats: string, context_playlist_sync: string, context_sortable_lists: string, context_ai_dj: string, library_sidebar: string, title: string, column_description: string, column_event: string, column_context: string, no_matches_template: string, filter_prompt: string, filter_edit_hint: string, matches_template: string, filter_count_hint_template: string, filter_hint: string, needs_spotify: string, not_for_source_template: string, only_for_source_template: string, unavailable_description_template: string, }; diff --git a/gui/src/bindings/strings.json b/gui/src/bindings/strings.json index f5f5c5be..5a97eb64 100644 --- a/gui/src/bindings/strings.json +++ b/gui/src/bindings/strings.json @@ -601,6 +601,7 @@ "listening_recap": "Generate listening recap card (selected period on Stats, 30 days elsewhere)", "lyrics_follow": "Resume following the current lyric line", "lyrics_scroll": "Scroll lyrics (pauses auto-follow)", + "lyrics_seek": "Seek to selected lyric line", "lyrics_timing": "Nudge lyric timing earlier/later", "lyrics_view": "Go to lyrics view", "matches_template": "matches for '{filter}'", @@ -1036,7 +1037,7 @@ "local_files_empty": "Local Files (no folders — set behavior.local_music_path)", "local_source_short": "Local", "log_location": "Log located in {path}", - "lyrics_browsing": "browsing · ↑/↓ scroll · Esc follow", + "lyrics_browsing": "browsing · ↑/↓ scroll · Esc follow · Enter seek", "lyrics_credit": "lyrics provided by LRCLIB", "lyrics_from": "from LRCLIB", "lyrics_loading": "Fetching lyrics…", @@ -2710,6 +2711,7 @@ "listening_recap": "生成收听回顾卡片(统计页用所选时间段,其他界面用 30 天)", "lyrics_follow": "恢复跟随当前歌词", "lyrics_scroll": "滚动歌词(暂停自动跟随)", + "lyrics_seek": "跳转到所选歌词行", "lyrics_timing": "微调歌词时间:提前或延后", "lyrics_view": "打开歌词界面", "matches_template": "“{filter}”的匹配项", @@ -3145,7 +3147,7 @@ "local_files_empty": "本地文件(没有文件夹,请设置 behavior.local_music_path)", "local_source_short": "本地", "log_location": "日志位于 {path}", - "lyrics_browsing": "浏览中 · ↑/↓ 滚动 · Esc 跟随", + "lyrics_browsing": "浏览中 · ↑/↓ 滚动 · Esc 跟随 · Enter 跳转", "lyrics_credit": "歌词由 LRCLIB 提供", "lyrics_from": "来自 LRCLIB", "lyrics_loading": "正在获取歌词…", @@ -4819,6 +4821,7 @@ "listening_recap": "產生聆聽回顧卡片(統計頁使用所選期間,其他畫面使用 30 天)", "lyrics_follow": "恢復跟隨目前歌詞", "lyrics_scroll": "捲動歌詞(暫停自動跟隨)", + "lyrics_seek": "跳轉到所選歌詞行", "lyrics_timing": "微調歌詞時間:提前或延後", "lyrics_view": "開啟歌詞畫面", "matches_template": "「{filter}」的符合項目", @@ -5254,7 +5257,7 @@ "local_files_empty": "本機檔案(無資料夾,請設定 behavior.local_music_path)", "local_source_short": "本機", "log_location": "日誌位於 {path}", - "lyrics_browsing": "瀏覽中 · ↑/↓ 捲動 · Esc 跟隨", + "lyrics_browsing": "瀏覽中 · ↑/↓ 捲動 · Esc 跟隨 · Enter 跳轉", "lyrics_credit": "歌詞由 LRCLIB 提供", "lyrics_from": "來自 LRCLIB", "lyrics_loading": "正在取得歌詞…", diff --git a/src/core/app/construction.rs b/src/core/app/construction.rs index c1122303..fc40e0d7 100644 --- a/src/core/app/construction.rs +++ b/src/core/app/construction.rs @@ -310,6 +310,13 @@ impl App { self } + /// This app with song progress seeded, for tests. + #[cfg(all(test, feature = "tui"))] + pub(crate) fn with_song_progress(mut self, progress_ms: u128) -> App { + self.song_progress_ms = progress_ms; + self + } + /// Mark the native backend parked with no player, for tests. #[cfg(all(test, feature = "streaming"))] pub(crate) fn seed_native_parked(&mut self) { diff --git a/src/core/i18n/help.rs b/src/core/i18n/help.rs index 21ec5a56..4e4ee553 100644 --- a/src/core/i18n/help.rs +++ b/src/core/i18n/help.rs @@ -44,6 +44,7 @@ pub struct HelpStrings { pub lyrics_scroll: &'static str, pub lyrics_follow: &'static str, pub lyrics_timing: &'static str, + pub lyrics_seek: &'static str, pub miniplayer: &'static str, pub cover_art: &'static str, pub back: &'static str, @@ -212,6 +213,7 @@ pub const EN: HelpStrings = HelpStrings { lyrics_scroll: "Scroll lyrics (pauses auto-follow)", lyrics_follow: "Resume following the current lyric line", lyrics_timing: "Nudge lyric timing earlier/later", + lyrics_seek: "Seek to selected lyric line", miniplayer: "Toggle miniplayer view", cover_art: "Go to cover art view", back: "Go back or exit when nowhere left to back to", @@ -381,6 +383,7 @@ pub const ZH_HANS: HelpStrings = HelpStrings { lyrics_scroll: "滚动歌词(暂停自动跟随)", lyrics_follow: "恢复跟随当前歌词", lyrics_timing: "微调歌词时间:提前或延后", + lyrics_seek: "跳转到所选歌词行", miniplayer: "切换迷你播放器", cover_art: "打开封面界面", back: "返回;无处可返回时退出", @@ -548,6 +551,7 @@ pub const ZH_HANT: HelpStrings = HelpStrings { lyrics_scroll: "捲動歌詞(暫停自動跟隨)", lyrics_follow: "恢復跟隨目前歌詞", lyrics_timing: "微調歌詞時間:提前或延後", + lyrics_seek: "跳轉到所選歌詞行", miniplayer: "切換迷你播放器", cover_art: "開啟封面畫面", back: "返回;無處可返回時離開", diff --git a/src/core/i18n/screens.rs b/src/core/i18n/screens.rs index 9b435ada..d8c5b471 100644 --- a/src/core/i18n/screens.rs +++ b/src/core/i18n/screens.rs @@ -317,7 +317,7 @@ pub const EN: ScreenStrings = ScreenStrings { no_devices: "No devices found: Make sure a device is active", timing_estimated: "timing estimated", lyrics_title: " Lyrics ", - lyrics_browsing: "browsing · ↑/↓ scroll · Esc follow", + lyrics_browsing: "browsing · ↑/↓ scroll · Esc follow · Enter seek", lyrics_loading: "Fetching lyrics…", lyrics_from: "from LRCLIB", lyrics_missing: "No lyrics for this track", @@ -582,7 +582,7 @@ pub const ZH_HANS: ScreenStrings = ScreenStrings { no_devices: "未找到设备:请确保有设备处于活动状态", timing_estimated: "时间为估算值", lyrics_title: " 歌词 ", - lyrics_browsing: "浏览中 · ↑/↓ 滚动 · Esc 跟随", + lyrics_browsing: "浏览中 · ↑/↓ 滚动 · Esc 跟随 · Enter 跳转", lyrics_loading: "正在获取歌词…", lyrics_from: "来自 LRCLIB", lyrics_missing: "此歌曲暂无歌词", @@ -849,7 +849,7 @@ pub const ZH_HANT: ScreenStrings = ScreenStrings { no_devices: "找不到裝置:請確認有裝置處於作用中", timing_estimated: "時間為估計值", lyrics_title: " 歌詞 ", - lyrics_browsing: "瀏覽中 · ↑/↓ 捲動 · Esc 跟隨", + lyrics_browsing: "瀏覽中 · ↑/↓ 捲動 · Esc 跟隨 · Enter 跳轉", lyrics_loading: "正在取得歌詞…", lyrics_from: "來自 LRCLIB", lyrics_missing: "此歌曲尚無歌詞", diff --git a/src/tui/handlers/lyrics_view.rs b/src/tui/handlers/lyrics_view.rs index 9bd194cb..656c3356 100644 --- a/src/tui/handlers/lyrics_view.rs +++ b/src/tui/handlers/lyrics_view.rs @@ -19,6 +19,7 @@ pub fn handler(key: Key, app: &mut App) { k if k == app.user_config.keys.previous_page => scroll_by(app, -5), k if k == app.user_config.keys.jump_to_start => jump_to(app, 0), k if k == app.user_config.keys.jump_to_end => jump_to(app, usize::MAX), + k if k == app.user_config.keys.submit || k == Key::Enter => seek_to_focused(app), _ => {} } } @@ -67,3 +68,134 @@ fn jump_to(app: &mut App, index: usize) { app.view.lyrics_view.manual_index = Some(index.min(lyrics.len() - 1)); app.view.lyrics_view.last_manual_input = Some(Instant::now()); } + +fn seek_to_focused(app: &mut App) { + if app.lyrics_status() != LyricsStatus::Found || !app.lyrics_synced() { + return; + } + let Some(lyrics) = app.lyrics() else { + return; + }; + if lyrics.is_empty() { + return; + } + let target_index = app + .view + .lyrics_view + .manual_index + .unwrap_or_else(|| active_lyric_index(lyrics, app.lyric_progress_ms())) + .min(lyrics.len() - 1); + + let target_time_ms = lyrics[target_index].0; + let seek_ms = (target_time_ms as i128 - i128::from(app.view.lyrics_view.timing_offset_ms)).max(0); + let target_u32 = u32::try_from(seek_ms).unwrap_or(u32::MAX); + + app.apply(crate::core::action::Action::SeekTo(target_u32)); + app.view.lyrics_view.manual_index = None; +} + +#[cfg(test)] +mod tests { + use super::*; + + fn playing_context() -> rspotify::model::CurrentPlaybackContext { + use rspotify::model::{ + context::Actions, CurrentlyPlayingType, Device, DeviceType, PlayableItem, RepeatState, + }; + rspotify::model::CurrentPlaybackContext { + device: Device { + id: Some("dev".to_string()), + is_active: true, + is_private_session: false, + is_restricted: false, + name: "Test Device".to_string(), + _type: DeviceType::Computer, + volume_percent: Some(50), + }, + repeat_state: RepeatState::Off, + shuffle_state: false, + context: None, + timestamp: chrono::Utc::now(), + progress: Some(chrono::Duration::milliseconds(0)), + is_playing: true, + item: Some(PlayableItem::Track(crate::core::test_helpers::full_track( + "4uLU6hMCjMI75M1A2tKUQC", + "Test Song", + ))), + currently_playing_type: CurrentlyPlayingType::Track, + actions: Actions::default(), + } + } + + fn app_with_sample_lyrics() -> App { + let mut app = App::default_connected().with_playback(playing_context()); + app.set_lyrics( + LyricsStatus::Found, + Some(vec![ + (0, "Line 0".to_string()), + (5_000, "Line 1".to_string()), + (10_000, "Line 2".to_string()), + ]), + true, + ); + app + } + + #[test] + fn enter_seeks_to_browsed_lyric_and_resumes_follow() { + let mut app = app_with_sample_lyrics(); + app.view.lyrics_view.timing_offset_ms = 500; + // Browse to Line 2 (at 10_000 ms) + scroll_by(&mut app, 2); + assert_eq!(app.view.lyrics_view.manual_index, Some(2)); + + handler(Key::Enter, &mut app); + + // 10_000 ms browsed lyric minus 500 ms timing offset + assert_eq!(app.song_progress_ms, 9_500); + // Manual browsing should be cleared (auto-follow resumes) + assert_eq!(app.view.lyrics_view.manual_index, None); + } + + #[test] + fn enter_without_browsing_seeks_to_active_lyric() { + let mut app = app_with_sample_lyrics().with_song_progress(6_000); + assert_eq!(app.view.lyrics_view.manual_index, None); + + handler(Key::Enter, &mut app); + + // Active line at 6_000 ms is Line 1 (5_000 ms) + assert_eq!(app.song_progress_ms, 5_000); + assert_eq!(app.view.lyrics_view.manual_index, None); + } + + #[test] + fn enter_does_nothing_when_lyrics_unsynced() { + let mut app = App::default() + .with_playback(playing_context()) + .with_song_progress(1_000); + app.set_lyrics( + LyricsStatus::Found, + Some(vec![(0, "Unsynced text".to_string())]), + false, + ); + app.view.lyrics_view.manual_index = Some(0); + + handler(Key::Enter, &mut app); + + assert_eq!(app.song_progress_ms, 1_000); + assert_eq!(app.view.lyrics_view.manual_index, Some(0)); + } + + #[test] + fn enter_does_nothing_when_lyrics_not_found() { + let mut app = App::default() + .with_playback(playing_context()) + .with_song_progress(1_000); + app.set_lyrics(LyricsStatus::NotFound, None, false); + + handler(Key::Enter, &mut app); + + assert_eq!(app.song_progress_ms, 1_000); + } +} diff --git a/src/tui/help_english_5d66123b.json b/src/tui/help_english_5d66123b.json index b60e7386..4042775b 100644 --- a/src/tui/help_english_5d66123b.json +++ b/src/tui/help_english_5d66123b.json @@ -37,6 +37,7 @@ ["Scroll lyrics (pauses auto-follow)", "k/j | / | ", "Lyrics view"], ["Resume following the current lyric line", "f or ", "Lyrics view"], ["Nudge lyric timing earlier/later", "l/h | / | /", "Lyrics view"], + ["Seek to selected lyric line", "", "Lyrics view"], ["Toggle miniplayer view", "T", "General"], ["Go to cover art view", "G", "General"], ["Go back or exit when nowhere left to back to", "q", "General"], @@ -119,19 +120,19 @@ ["Press the selected setting's button", "o", "Settings"] ], "views": [ - ["Spotify", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, [25, "Enter input for search (needs Spotify)"], 26, 27, [28, "Search playlists by name (needs Spotify)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (needs Spotify)"], 70, 74, 75, 76, 77, 78, 79, 80, 81, 82, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (needs Spotify)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 106, 107, 108, 109, [110, "Open Listening Party menu (needs Spotify)"], 111, 112, 113, 114, 115, 116]], - ["Local", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, [25, "Enter input for search (not for Local Files)"], 26, 27, [28, "Search playlists by name (not for Local Files)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 74, 75, 76, 77, 78, 79, 80, 81, 82, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Local Files)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 106, 107, 108, 109, [110, "Open Listening Party menu (needs Spotify)"], 111, 112, 113, 114, 115, 116]], - ["Subsonic", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, [28, "Search playlists by name (not for Subsonic)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Subsonic)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 106, 107, 108, 109, [110, "Open Listening Party menu (needs Spotify)"], 111, 112, 113, 114, 115, 116]], - ["Radio", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, [28, "Search playlists by name (not for Internet Radio)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 88, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Internet Radio)"], 101, 102, 103, 104, 106, 107, 108, 109, [110, "Open Listening Party menu (needs Spotify)"], 111, 112, 113, 114, 115, 116]], - ["YouTube", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 86, 87, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for YouTube)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 106, 107, 108, 109, [110, "Open Listening Party menu (needs Spotify)"], 111, 112, 113, 114, 115, 116]], - ["Qobuz", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, [28, "Search playlists by name (not for Qobuz)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Qobuz)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 106, 107, 108, 109, [110, "Open Listening Party menu (needs Spotify)"], 111, 112, 113, 114, 115, 116]], - ["AppleMusic", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, [28, "Search playlists by name (not for Apple Music)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Apple Music)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 106, 107, 108, 109, [110, "Open Listening Party menu (needs Spotify)"], 111, 112, 113, 114, 115, 116]], - ["Spotify", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]], - ["Local", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, [25, "Enter input for search (not for Local Files)"], 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 74, 75, 76, 77, 78, 79, 80, 81, 82, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Local Files)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]], - ["Subsonic", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Subsonic)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]], - ["Radio", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 88, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Internet Radio)"], 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]], - ["YouTube", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 86, 87, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for YouTube)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]], - ["Qobuz", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Qobuz)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]], - ["AppleMusic", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, [69, "Clear playlist track search filter (Spotify only)"], 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 91, 95, 96, 97, 98, 99, [100, "Toggle saved state for currently playing track/episode (not for Apple Music)"], [101, "Favorite highlighted/playing radio station (Internet Radio only)"], 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]] + ["Spotify", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, [25, "Enter input for search (needs Spotify)"], 26, 27, [28, "Search playlists by name (needs Spotify)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (needs Spotify)"], 71, 75, 76, 77, 78, 79, 80, 81, 82, 83, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (needs Spotify)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 107, 108, 109, 110, [111, "Open Listening Party menu (needs Spotify)"], 112, 113, 114, 115, 116, 117]], + ["Local", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, [25, "Enter input for search (not for Local Files)"], 26, 27, [28, "Search playlists by name (not for Local Files)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 75, 76, 77, 78, 79, 80, 81, 82, 83, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Local Files)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 107, 108, 109, 110, [111, "Open Listening Party menu (needs Spotify)"], 112, 113, 114, 115, 116, 117]], + ["Subsonic", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, [28, "Search playlists by name (not for Subsonic)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 88, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Subsonic)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 107, 108, 109, 110, [111, "Open Listening Party menu (needs Spotify)"], 112, 113, 114, 115, 116, 117]], + ["Radio", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, [28, "Search playlists by name (not for Internet Radio)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 89, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Internet Radio)"], 102, 103, 104, 105, 107, 108, 109, 110, [111, "Open Listening Party menu (needs Spotify)"], 112, 113, 114, 115, 116, 117]], + ["YouTube", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 87, 88, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for YouTube)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 107, 108, 109, 110, [111, "Open Listening Party menu (needs Spotify)"], 112, 113, 114, 115, 116, 117]], + ["Qobuz", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, [28, "Search playlists by name (not for Qobuz)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 88, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Qobuz)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 107, 108, 109, 110, [111, "Open Listening Party menu (needs Spotify)"], 112, 113, 114, 115, 116, 117]], + ["AppleMusic", false, [0, 1, 2, 3, [4, "Jump to currently playing album (needs Spotify)"], [5, "Jump to currently playing artist's album list (needs Spotify)"], [6, "Jump to current play context (needs Spotify)"], 7, 8, 9, 10, 11, 12, 13, 14, [15, "Copy url to currently playing song/episode (needs Spotify)"], [16, "Copy url to currently playing album/show (needs Spotify)"], 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, [28, "Search playlists by name (not for Apple Music)"], 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Apple Music)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 107, 108, 109, 110, [111, "Open Listening Party menu (needs Spotify)"], 112, 113, 114, 115, 116, 117]], + ["Spotify", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117]], + ["Local", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, [25, "Enter input for search (not for Local Files)"], 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 75, 76, 77, 78, 79, 80, 81, 82, 83, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Local Files)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117]], + ["Subsonic", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 88, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Subsonic)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117]], + ["Radio", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 89, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Internet Radio)"], 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117]], + ["YouTube", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 87, 88, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for YouTube)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117]], + ["Qobuz", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 88, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Qobuz)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117]], + ["AppleMusic", true, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, [70, "Clear playlist track search filter (Spotify only)"], 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 92, 96, 97, 98, 99, 100, [101, "Toggle saved state for currently playing track/episode (not for Apple Music)"], [102, "Favorite highlighted/playing radio station (Internet Radio only)"], 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117]] ] } diff --git a/src/tui/keymap.rs b/src/tui/keymap.rs index 2b888d16..8cd857e1 100644 --- a/src/tui/keymap.rs +++ b/src/tui/keymap.rs @@ -269,6 +269,18 @@ pub fn help_entries_for(strings: &crate::core::i18n::Strings) -> Vec }), help.context_lyrics, ), + row( + help.lyrics_seek, + Custom(|app| { + let submit = app.user_config.keys.submit; + if submit == Key::Enter { + "".to_string() + } else { + format!("{submit} | ") + } + }), + help.context_lyrics, + ), row( help.miniplayer, Binding(|k| k.miniplayer_view), @@ -1125,6 +1137,7 @@ mod tests { event(help.lyrics_follow), help.key_alternative("f", "") ); + assert_eq!(event(help.lyrics_seek), ""); } }