mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
feat(audio): rust track preview engine + inline play/preview buttons (#392)
* feat(audio): rust preview engine with secondary sink Adds a parallel rodio Sink on the existing OutputStream for 30s mid-track previews. Two new Tauri commands (audio_preview_play, audio_preview_stop) plus three events (audio:preview-start / -progress / -end). The main sink is paused with Sink::pause() and auto-resumed on preview end iff it was playing beforehand. * feat(playlists): migrate suggestion preview to rust audio engine Replaces the HTML5 <audio> path with the new rust preview engine. previewStore mirrors the engine's start/progress/end events so any tracklist row can render preview UI from a single source of truth. Spacebar redirects to stopPreview while a preview plays, hardware mediakeys are silently dropped (Q5), and tray clicks cancel the preview before forwarding the original action. * feat(albums): inline play + preview buttons in tracklist rows Track number stays static on hover instead of swapping to a play icon — the dedicated Play and Preview buttons in the title cell take over click-to-play and click-to-preview. Active+playing rows keep the eq-bars (also on hover), active+paused rows fall back to the static accent-coloured number. Pilot for the wider rollout to other tracklists. * feat(tracklists): roll out inline play + preview buttons Mirrors the AlbumTrackList pilot across the remaining track-row based lists: PlaylistDetail main tracks, Favorites, ArtistDetail top tracks, RandomMix (both genre-mix and filtered-songs lists). Track number stays static, the dedicated Play + Preview buttons in the title cell take over click-to-play and click-to-preview. * feat(settings): track preview toggle + configurable position and duration Adds an opt-out switch and two sliders to Settings → Audio: start position (0-90 % of track length, default 33 %) and preview duration (5-60 s, default 30 s). The progress-ring animation follows the duration via a CSS variable so the visual matches the engine's auto-stop. Disabling the feature hides every inline preview button via a single root-level data attribute, no per-row conditional rendering required. i18n keys added in all 8 locales. * fix(audio): cancel preview when main playback (re)starts audio_play, audio_play_radio, audio_resume and audio_stop did not know about the parallel preview sink, so clicking Play on a track that was currently being previewed left the preview running on top of the freshly started main playback. New helper clears the resume flag, bumps the preview generation, drops the sink and emits an 'interrupted' end event before any of those commands touches the main sink. * feat(settings): per-location track preview toggles Splits the single trackPreviewsEnabled toggle into a master + 6 per-location sub-toggles (suggestions, albums, playlists, favorites, artist, randomMix). Master remains the kill switch; sub-toggles are only honoured when master is on. Each tracklist container is marked with `data-preview-loc="<id>"` and hidden via scoped CSS when the matching root attribute is "off". startPreview now takes a location argument so the store can guard logic too. i18n added in all 8 locales. * fix(contextmenu): use ChevronsRight for Play Next to distinguish from preview
This commit is contained in:
committed by
GitHub
parent
ff47170736
commit
a14dba8167
@@ -870,6 +870,22 @@ export const deTranslation = {
|
||||
notWithCrossfade: 'Nicht verfügbar wenn Crossfade aktiv ist',
|
||||
gapless: 'Nahtlose Wiedergabe',
|
||||
gaplessDesc: 'Nächsten Track vorpuffern um Lücken zwischen Songs zu vermeiden',
|
||||
trackPreviewsTitle: 'Track-Vorschau',
|
||||
trackPreviewsToggle: 'Track-Vorschau aktivieren',
|
||||
trackPreviewsDesc: 'Inline Play- und Vorschau-Buttons in den Tracklisten anzeigen für eine kurze Hörprobe mitten im Song.',
|
||||
trackPreviewStart: 'Startposition',
|
||||
trackPreviewStartDesc: 'Wie weit der Track schon gespielt sein soll wenn die Vorschau startet (% der Länge).',
|
||||
trackPreviewDuration: 'Dauer',
|
||||
trackPreviewDurationDesc: 'Wie lange jede Vorschau spielt bevor sie automatisch stoppt.',
|
||||
trackPreviewDurationSecs: '{{n}} s',
|
||||
trackPreviewLocationsTitle: 'Wo Vorschauen erscheinen',
|
||||
trackPreviewLocationsDesc: 'Wähle aus, in welchen Listen die Vorschau-Buttons angezeigt werden.',
|
||||
trackPreviewLocation_suggestions: 'In Playlist-Vorschlägen',
|
||||
trackPreviewLocation_albums: 'In Album-Tracklisten',
|
||||
trackPreviewLocation_playlists: 'In Playlists',
|
||||
trackPreviewLocation_favorites: 'In Favoriten',
|
||||
trackPreviewLocation_artist: 'In Künstler-Top-Tracks',
|
||||
trackPreviewLocation_randomMix: 'In Random Mix',
|
||||
preloadMode: 'Nächsten Track vorpuffern',
|
||||
preloadModeDesc: 'Wann mit dem Puffern des nächsten Tracks begonnen werden soll',
|
||||
nextTrackBufferingTitle: 'Pufferung',
|
||||
|
||||
@@ -876,6 +876,22 @@ export const enTranslation = {
|
||||
notWithCrossfade: 'Not available while Crossfade is active',
|
||||
gapless: 'Gapless Playback',
|
||||
gaplessDesc: 'Pre-buffer next track to eliminate gaps between songs',
|
||||
trackPreviewsTitle: 'Track Previews',
|
||||
trackPreviewsToggle: 'Enable track previews',
|
||||
trackPreviewsDesc: 'Show inline Play and Preview buttons in tracklists for a quick mid-song sample.',
|
||||
trackPreviewStart: 'Start position',
|
||||
trackPreviewStartDesc: 'How far into the track the preview starts (% of track length).',
|
||||
trackPreviewDuration: 'Duration',
|
||||
trackPreviewDurationDesc: 'How long each preview plays before it stops.',
|
||||
trackPreviewDurationSecs: '{{n}} s',
|
||||
trackPreviewLocationsTitle: 'Where previews appear',
|
||||
trackPreviewLocationsDesc: 'Pick which lists show inline preview buttons.',
|
||||
trackPreviewLocation_suggestions: 'In playlist suggestions',
|
||||
trackPreviewLocation_albums: 'In album tracklists',
|
||||
trackPreviewLocation_playlists: 'In playlists',
|
||||
trackPreviewLocation_favorites: 'In favorites',
|
||||
trackPreviewLocation_artist: 'In artist top tracks',
|
||||
trackPreviewLocation_randomMix: 'In Random Mix',
|
||||
preloadMode: 'Preload Next Track',
|
||||
preloadModeDesc: 'When to start buffering the next track in the queue',
|
||||
nextTrackBufferingTitle: 'Buffering',
|
||||
|
||||
@@ -863,6 +863,22 @@ export const esTranslation = {
|
||||
notWithCrossfade: 'No disponible mientras Crossfade está activo',
|
||||
gapless: 'Reproducción Gapless',
|
||||
gaplessDesc: 'Precarga siguiente pista para eliminar silencios entre canciones',
|
||||
trackPreviewsTitle: 'Previsualizaciones de pistas',
|
||||
trackPreviewsToggle: 'Activar previsualizaciones',
|
||||
trackPreviewsDesc: 'Mostrar botones de Reproducir y Previsualización en las listas de pistas para una muestra rápida a mitad de canción.',
|
||||
trackPreviewStart: 'Posición inicial',
|
||||
trackPreviewStartDesc: 'Cuánto avanza la pista antes de iniciar la previsualización (% de la duración).',
|
||||
trackPreviewDuration: 'Duración',
|
||||
trackPreviewDurationDesc: 'Cuánto dura cada previsualización antes de detenerse.',
|
||||
trackPreviewDurationSecs: '{{n}} s',
|
||||
trackPreviewLocationsTitle: 'Dónde aparecen las previsualizaciones',
|
||||
trackPreviewLocationsDesc: 'Elige en qué listas se muestran los botones de previsualización.',
|
||||
trackPreviewLocation_suggestions: 'En sugerencias de listas',
|
||||
trackPreviewLocation_albums: 'En listas de pistas de álbum',
|
||||
trackPreviewLocation_playlists: 'En listas de reproducción',
|
||||
trackPreviewLocation_favorites: 'En favoritos',
|
||||
trackPreviewLocation_artist: 'En las mejores pistas del artista',
|
||||
trackPreviewLocation_randomMix: 'En Random Mix',
|
||||
preloadMode: 'Precargar Siguiente Pista',
|
||||
preloadModeDesc: 'Cuándo comenzar a cargar la siguiente pista en cola',
|
||||
nextTrackBufferingTitle: 'Buffer',
|
||||
|
||||
@@ -858,6 +858,22 @@ export const frTranslation = {
|
||||
notWithCrossfade: 'Non disponible quand le fondu enchaîné est actif',
|
||||
gapless: 'Lecture sans blanc',
|
||||
gaplessDesc: 'Préparer la piste suivante pour éliminer les silences entre les morceaux',
|
||||
trackPreviewsTitle: 'Aperçus de pistes',
|
||||
trackPreviewsToggle: 'Activer les aperçus de pistes',
|
||||
trackPreviewsDesc: 'Affiche les boutons Lecture et Aperçu dans les listes pour un court extrait au milieu du morceau.',
|
||||
trackPreviewStart: 'Position de départ',
|
||||
trackPreviewStartDesc: 'À quel point du morceau l\'aperçu commence (% de la durée).',
|
||||
trackPreviewDuration: 'Durée',
|
||||
trackPreviewDurationDesc: 'Combien de temps chaque aperçu joue avant de s\'arrêter.',
|
||||
trackPreviewDurationSecs: '{{n}} s',
|
||||
trackPreviewLocationsTitle: 'Où afficher les aperçus',
|
||||
trackPreviewLocationsDesc: 'Choisissez dans quelles listes afficher les boutons d\'aperçu.',
|
||||
trackPreviewLocation_suggestions: 'Dans les suggestions de playlist',
|
||||
trackPreviewLocation_albums: 'Dans les listes d\'albums',
|
||||
trackPreviewLocation_playlists: 'Dans les playlists',
|
||||
trackPreviewLocation_favorites: 'Dans les favoris',
|
||||
trackPreviewLocation_artist: 'Dans les meilleurs morceaux de l\'artiste',
|
||||
trackPreviewLocation_randomMix: 'Dans Random Mix',
|
||||
preloadMode: 'Précharger la piste suivante',
|
||||
preloadModeDesc: 'Quand commencer à mettre en mémoire tampon la piste suivante',
|
||||
nextTrackBufferingTitle: 'Mise en mémoire tampon',
|
||||
|
||||
@@ -857,6 +857,22 @@ export const nbTranslation = {
|
||||
notWithCrossfade: 'Ikke tilgjengelig mens Crossfade er aktiv',
|
||||
gapless: 'Gapless avspilling',
|
||||
gaplessDesc: 'Forhåndsbuffer neste spor for å eliminere mellomrom mellom sanger',
|
||||
trackPreviewsTitle: 'Sporforhåndsvisning',
|
||||
trackPreviewsToggle: 'Aktiver sporforhåndsvisning',
|
||||
trackPreviewsDesc: 'Vis innebygde Spill- og Forhåndsvisning-knapper i sporlister for en kort smakebit fra midten av sangen.',
|
||||
trackPreviewStart: 'Startposisjon',
|
||||
trackPreviewStartDesc: 'Hvor langt inn i sporet forhåndsvisningen starter (% av lengden).',
|
||||
trackPreviewDuration: 'Varighet',
|
||||
trackPreviewDurationDesc: 'Hvor lenge hver forhåndsvisning spiller før den stopper.',
|
||||
trackPreviewDurationSecs: '{{n}} s',
|
||||
trackPreviewLocationsTitle: 'Hvor forhåndsvisninger vises',
|
||||
trackPreviewLocationsDesc: 'Velg hvilke lister som viser forhåndsvisningsknapper.',
|
||||
trackPreviewLocation_suggestions: 'I spillelisteforslag',
|
||||
trackPreviewLocation_albums: 'I albumsporlister',
|
||||
trackPreviewLocation_playlists: 'I spillelister',
|
||||
trackPreviewLocation_favorites: 'I favoritter',
|
||||
trackPreviewLocation_artist: 'I artistens toppspor',
|
||||
trackPreviewLocation_randomMix: 'I Random Mix',
|
||||
infiniteQueue: 'Uendelig kø',
|
||||
infiniteQueueDesc: 'Legg automatisk til tilfeldige spor når køen går tom',
|
||||
experimental: 'Eksperimentell',
|
||||
|
||||
@@ -857,6 +857,22 @@ export const nlTranslation = {
|
||||
notWithCrossfade: 'Niet beschikbaar als overgang actief is',
|
||||
gapless: 'Naadloos afspelen',
|
||||
gaplessDesc: 'Volgend nummer vooraf bufferen om stiltes tussen nummers te elimineren',
|
||||
trackPreviewsTitle: 'Track-voorvertoning',
|
||||
trackPreviewsToggle: 'Track-voorvertoning inschakelen',
|
||||
trackPreviewsDesc: 'Inline Play- en Voorvertoning-knoppen in trackslijsten tonen voor een korte sample midden in het nummer.',
|
||||
trackPreviewStart: 'Startpositie',
|
||||
trackPreviewStartDesc: 'Hoever in de track de voorvertoning start (% van de duur).',
|
||||
trackPreviewDuration: 'Duur',
|
||||
trackPreviewDurationDesc: 'Hoe lang elke voorvertoning speelt voordat hij stopt.',
|
||||
trackPreviewDurationSecs: '{{n}} s',
|
||||
trackPreviewLocationsTitle: 'Waar voorvertoningen verschijnen',
|
||||
trackPreviewLocationsDesc: 'Kies in welke lijsten de voorvertoning-knoppen worden weergegeven.',
|
||||
trackPreviewLocation_suggestions: 'In playlist-suggesties',
|
||||
trackPreviewLocation_albums: 'In albumlijsten',
|
||||
trackPreviewLocation_playlists: 'In playlists',
|
||||
trackPreviewLocation_favorites: 'In favorieten',
|
||||
trackPreviewLocation_artist: 'In top-tracks van artiest',
|
||||
trackPreviewLocation_randomMix: 'In Random Mix',
|
||||
preloadMode: 'Volgend nummer vooraf laden',
|
||||
preloadModeDesc: 'Wanneer met het bufferen van het volgende nummer wordt begonnen',
|
||||
nextTrackBufferingTitle: 'Buffering',
|
||||
|
||||
@@ -909,6 +909,22 @@ export const ruTranslation = {
|
||||
notWithCrossfade: 'Недоступно при включённом кроссфейде',
|
||||
gapless: 'Без пауз между треками',
|
||||
gaplessDesc: 'Заранее подгружать следующий трек, чтобы не было тишины',
|
||||
trackPreviewsTitle: 'Превью треков',
|
||||
trackPreviewsToggle: 'Включить превью треков',
|
||||
trackPreviewsDesc: 'Показывать встроенные кнопки воспроизведения и превью в списках треков для быстрого прослушивания фрагмента.',
|
||||
trackPreviewStart: 'Начальная позиция',
|
||||
trackPreviewStartDesc: 'С какого момента трека начинается превью (% от длительности).',
|
||||
trackPreviewDuration: 'Длительность',
|
||||
trackPreviewDurationDesc: 'Сколько играет каждое превью до автоматической остановки.',
|
||||
trackPreviewDurationSecs: '{{n}} с',
|
||||
trackPreviewLocationsTitle: 'Где показывать превью',
|
||||
trackPreviewLocationsDesc: 'Выберите, в каких списках показывать кнопки превью.',
|
||||
trackPreviewLocation_suggestions: 'В предложениях плейлиста',
|
||||
trackPreviewLocation_albums: 'В списках треков альбома',
|
||||
trackPreviewLocation_playlists: 'В плейлистах',
|
||||
trackPreviewLocation_favorites: 'В избранном',
|
||||
trackPreviewLocation_artist: 'В топ-треках исполнителя',
|
||||
trackPreviewLocation_randomMix: 'В Random Mix',
|
||||
preloadMode: 'Предзагрузка следующего трека',
|
||||
preloadModeDesc: 'Когда начинать буферизацию следующего в очереди',
|
||||
nextTrackBufferingTitle: 'Буферизация',
|
||||
|
||||
@@ -852,6 +852,22 @@ export const zhTranslation = {
|
||||
notWithCrossfade: '交叉淡入淡出开启时不可用',
|
||||
gapless: '无缝播放',
|
||||
gaplessDesc: '预缓冲下一首曲目以消除歌曲间的间隙',
|
||||
trackPreviewsTitle: '曲目预览',
|
||||
trackPreviewsToggle: '启用曲目预览',
|
||||
trackPreviewsDesc: '在曲目列表中显示内联播放与预览按钮,可快速试听歌曲中段。',
|
||||
trackPreviewStart: '起始位置',
|
||||
trackPreviewStartDesc: '预览从曲目何处开始(占总时长的百分比)。',
|
||||
trackPreviewDuration: '时长',
|
||||
trackPreviewDurationDesc: '每段预览自动停止前的播放时长。',
|
||||
trackPreviewDurationSecs: '{{n}} 秒',
|
||||
trackPreviewLocationsTitle: '预览显示位置',
|
||||
trackPreviewLocationsDesc: '选择在哪些列表中显示预览按钮。',
|
||||
trackPreviewLocation_suggestions: '播放列表建议中',
|
||||
trackPreviewLocation_albums: '专辑曲目列表中',
|
||||
trackPreviewLocation_playlists: '播放列表中',
|
||||
trackPreviewLocation_favorites: '收藏中',
|
||||
trackPreviewLocation_artist: '艺人热门曲目中',
|
||||
trackPreviewLocation_randomMix: 'Random Mix 中',
|
||||
preloadMode: '预加载下一曲目',
|
||||
preloadModeDesc: '何时开始缓冲队列中的下一曲目',
|
||||
nextTrackBufferingTitle: '缓冲',
|
||||
|
||||
Reference in New Issue
Block a user