feat(player): answer transport keys with transient indicators, not the chrome
Pressing pause or seeking while the player's on-screen controls were hidden raised the entire OSD, covering the subtitles the viewer was rewinding to read. Transport keys now answer with a transient indicator and leave the chrome down; Select, D-pad Center and a centre tap remain the deliberate way to bring the controls back. Play/pause confirms with an icon-only translucent disc at the centre of the frame, 72px around a 44px glyph, which grows and fades in, holds half a second at rest, then runs the same motion in reverse. Seeking shows the amount plus a single chevron on the same line at the edge it travels toward, with no backdrop at all: anything large enough to read as a surface is large enough to cover picture and subtitles, so legibility comes from shadows instead. Only the chevron moves, and it eases outward across most of its cycle and returns briefly, holding a visible opacity floor rather than blinking out. Type is scaled per platform, since a television is read from across the room. The existing text pill stays for genuine notices - rate changes, chapter titles, zoom, errors - because an earlier centred pill overlapped ASS \an8 subtitle placement, which is the readability complaint this feedback exists to answer. Every relative seek entry point now shares one coalescing primitive. The keyboard shortcuts fell through to KeyboardShortcutsService and previously reported nothing, and both they and the remote's chapter fallback rebased each press off player.state.position, so a burst against a slow backend pinned every request near one step while the indicator climbed to a total that was never committed. A released key commits its pending target immediately and resets the acceleration tier, including on live TV where seeks bypass the accumulator. A chapter seek with nowhere to go, past the last chapter or already at the start, no longer announces a jump it does not perform. Rewind-on-resume follows the resolved intent rather than the current state, so a directed pause on an already-paused video neither resumes nor rewinds. Indicators carry their own liveRegion semantics nodes: their labels previously merged into the full-screen "show playback controls" target, corrupting its accessible name, and they keep announcing "Paused"/"Playing" and the seek amount from icon-only visuals. close #1676
This commit is contained in:
@@ -493,6 +493,8 @@
|
||||
"playNext": "Növbətini oynat",
|
||||
"playButton": "Oynat",
|
||||
"pauseButton": "Fasilə",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Oynatma idarəetmələrini göstər",
|
||||
"hidePlaybackControls": "Oynatma idarəetmələrini gizlət",
|
||||
"seekBackwardButton": "${seconds} saniyə geri sar",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Пусни следващото",
|
||||
"playButton": "Пусни",
|
||||
"pauseButton": "Пауза",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Покажи контролите за възпроизвеждане",
|
||||
"hidePlaybackControls": "Скрий контролите за възпроизвеждане",
|
||||
"seekBackwardButton": "Превърти назад ${seconds} секунди",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Afspil næste",
|
||||
"playButton": "Afspil",
|
||||
"pauseButton": "Pause",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Vis afspilningsknapper",
|
||||
"hidePlaybackControls": "Skjul afspilningsknapper",
|
||||
"seekBackwardButton": "Spol ${seconds} sekunder tilbage",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Nächstes abspielen",
|
||||
"playButton": "Abspielen",
|
||||
"pauseButton": "Pause",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Wiedergabesteuerung anzeigen",
|
||||
"hidePlaybackControls": "Wiedergabesteuerung ausblenden",
|
||||
"seekBackwardButton": "${seconds} Sekunden zurück",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Play Next",
|
||||
"playButton": "Play",
|
||||
"pauseButton": "Pause",
|
||||
"playbackPaused": "Paused",
|
||||
"playbackResumed": "Playing",
|
||||
"showPlaybackControls": "Show playback controls",
|
||||
"hidePlaybackControls": "Hide playback controls",
|
||||
"seekBackwardButton": "Seek backward ${seconds} seconds",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Reproducir siguiente",
|
||||
"playButton": "Reproducir",
|
||||
"pauseButton": "Pausar",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Mostrar controles de reproducción",
|
||||
"hidePlaybackControls": "Ocultar controles de reproducción",
|
||||
"seekBackwardButton": "Retroceder ${seconds} segundos",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Lire l'épisode suivant",
|
||||
"playButton": "Lire",
|
||||
"pauseButton": "Pause",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Afficher les commandes de lecture",
|
||||
"hidePlaybackControls": "Masquer les commandes de lecture",
|
||||
"seekBackwardButton": "Reculer de ${seconds} secondes",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Következő lejátszása",
|
||||
"playButton": "Lejátszás",
|
||||
"pauseButton": "Szünet",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Lejátszásvezérlők megjelenítése",
|
||||
"hidePlaybackControls": "Lejátszásvezérlők elrejtése",
|
||||
"seekBackwardButton": "Tekerés hátra ${seconds} másodperccel",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Riproduci il successivo",
|
||||
"playButton": "Riproduci",
|
||||
"pauseButton": "Pausa",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Mostra i controlli di riproduzione",
|
||||
"hidePlaybackControls": "Nascondi i controlli di riproduzione",
|
||||
"seekBackwardButton": "Riavvolgi di ${seconds} secondi",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "次を再生",
|
||||
"playButton": "再生",
|
||||
"pauseButton": "一時停止",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "再生コントロールを表示",
|
||||
"hidePlaybackControls": "再生コントロールを非表示",
|
||||
"seekBackwardButton": "${seconds}秒戻る",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Келесіні ойнату",
|
||||
"playButton": "Ойнату",
|
||||
"pauseButton": "Кідірту",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Басқару элементтерін көрсету",
|
||||
"hidePlaybackControls": "Басқару элементтерін жасыру",
|
||||
"seekBackwardButton": "${seconds} секунд артқа айналдыру",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "다음 재생",
|
||||
"playButton": "재생",
|
||||
"pauseButton": "일시정지",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "재생 컨트롤 표시",
|
||||
"hidePlaybackControls": "재생 컨트롤 숨기기",
|
||||
"seekBackwardButton": "${seconds}초 뒤로 이동",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Spill neste",
|
||||
"playButton": "Spill av",
|
||||
"pauseButton": "Pause",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Vis avspillingskontroller",
|
||||
"hidePlaybackControls": "Skjul avspillingskontroller",
|
||||
"seekBackwardButton": "Spol tilbake ${seconds} sekunder",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Volgende afspelen",
|
||||
"playButton": "Afspelen",
|
||||
"pauseButton": "Pauzeren",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Afspeelbediening tonen",
|
||||
"hidePlaybackControls": "Afspeelbediening verbergen",
|
||||
"seekBackwardButton": "${seconds} seconden terugspoelen",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Odtwórz następny",
|
||||
"playButton": "Odtwórz",
|
||||
"pauseButton": "Pauza",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Pokaż elementy sterujące odtwarzaniem",
|
||||
"hidePlaybackControls": "Ukryj elementy sterujące odtwarzaniem",
|
||||
"seekBackwardButton": "Przewiń do tyłu o ${seconds} sekund",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Reproduzir Próximo",
|
||||
"playButton": "Reproduzir",
|
||||
"pauseButton": "Pausar",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Mostrar controles de reprodução",
|
||||
"hidePlaybackControls": "Ocultar controles de reprodução",
|
||||
"seekBackwardButton": "Retroceder ${seconds} segundos",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Следующее",
|
||||
"playButton": "Воспроизвести",
|
||||
"pauseButton": "Пауза",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Показать элементы управления воспроизведением",
|
||||
"hidePlaybackControls": "Скрыть элементы управления воспроизведением",
|
||||
"seekBackwardButton": "Перемотать назад на ${seconds} с",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 22
|
||||
/// Strings: 32681 (1485 per locale)
|
||||
/// Strings: 32683 (1485 per locale)
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
||||
@@ -1541,6 +1541,12 @@ class Translations$videoControls$en {
|
||||
/// en: 'Pause'
|
||||
String get pauseButton => 'Pause';
|
||||
|
||||
/// en: 'Paused'
|
||||
String get playbackPaused => 'Paused';
|
||||
|
||||
/// en: 'Playing'
|
||||
String get playbackResumed => 'Playing';
|
||||
|
||||
/// en: 'Show playback controls'
|
||||
String get showPlaybackControls => 'Show playback controls';
|
||||
|
||||
@@ -5662,6 +5668,8 @@ extension on Translations {
|
||||
'videoControls.playNext' => 'Play Next',
|
||||
'videoControls.playButton' => 'Play',
|
||||
'videoControls.pauseButton' => 'Pause',
|
||||
'videoControls.playbackPaused' => 'Paused',
|
||||
'videoControls.playbackResumed' => 'Playing',
|
||||
'videoControls.showPlaybackControls' => 'Show playback controls',
|
||||
'videoControls.hidePlaybackControls' => 'Hide playback controls',
|
||||
'videoControls.seekBackwardButton' => ({required Object seconds}) => 'Seek backward ${seconds} seconds',
|
||||
@@ -5709,10 +5717,10 @@ extension on Translations {
|
||||
'videoControls.chapters' => 'Chapters',
|
||||
'videoControls.noChaptersAvailable' => 'No chapters available',
|
||||
'videoControls.queue' => 'Queue',
|
||||
'videoControls.noQueueItems' => 'No items in queue',
|
||||
'videoControls.searchSubtitles' => 'Search Subtitles',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'videoControls.noQueueItems' => 'No items in queue',
|
||||
'videoControls.searchSubtitles' => 'Search Subtitles',
|
||||
'videoControls.language' => 'Language',
|
||||
'videoControls.noSubtitlesFound' => 'No subtitles found',
|
||||
'videoControls.subtitleDownloaded' => 'Subtitle downloaded',
|
||||
@@ -6223,10 +6231,10 @@ extension on Translations {
|
||||
'watchTogether.joinWatchSession' => 'Join Watch Session',
|
||||
'watchTogether.enterCodeHint' => 'Enter 5-character code',
|
||||
'watchTogether.pasteFromClipboard' => 'Paste from clipboard',
|
||||
'watchTogether.pleaseEnterCode' => 'Please enter a session code',
|
||||
'watchTogether.codeMustBe5Chars' => 'Session code must be 5 characters',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.pleaseEnterCode' => 'Please enter a session code',
|
||||
'watchTogether.codeMustBe5Chars' => 'Session code must be 5 characters',
|
||||
'watchTogether.joinInstructions' => 'Enter the host\'s session code to join.',
|
||||
'watchTogether.failedToCreate' => 'Failed to create session',
|
||||
'watchTogether.failedToJoin' => 'Failed to join session',
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Spela nästa",
|
||||
"playButton": "Spela",
|
||||
"pauseButton": "Pausa",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Visa uppspelningskontroller",
|
||||
"hidePlaybackControls": "Dölj uppspelningskontroller",
|
||||
"seekBackwardButton": "Spola bakåt ${seconds} sekunder",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Sonrakini Oynat",
|
||||
"playButton": "Oynat",
|
||||
"pauseButton": "Duraklat",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Oynatma kontrollerini göster",
|
||||
"hidePlaybackControls": "Oynatma kontrollerini gizle",
|
||||
"seekBackwardButton": "${seconds} saniye geri sar",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "Keyingisini ijro etish",
|
||||
"playButton": "Ijro etish",
|
||||
"pauseButton": "Pauza",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "Boshqaruv tugmalarini koʻrsatish",
|
||||
"hidePlaybackControls": "Boshqaruv tugmalarini yashirish",
|
||||
"seekBackwardButton": "${seconds} soniya orqaga oʻtkazish",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "播放下一集",
|
||||
"playButton": "播放",
|
||||
"pauseButton": "暫停",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "顯示播放控制項",
|
||||
"hidePlaybackControls": "隱藏播放控制項",
|
||||
"seekBackwardButton": "後退 ${seconds} 秒",
|
||||
|
||||
@@ -493,6 +493,8 @@
|
||||
"playNext": "播放下一集",
|
||||
"playButton": "播放",
|
||||
"pauseButton": "暂停",
|
||||
"playbackPaused": "",
|
||||
"playbackResumed": "",
|
||||
"showPlaybackControls": "显示播放控制项",
|
||||
"hidePlaybackControls": "隐藏播放控制项",
|
||||
"seekBackwardButton": "快退 ${seconds} 秒",
|
||||
|
||||
Reference in New Issue
Block a user