feat: watch together buffering indicators
This commit is contained in:
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name} satte på pause",
|
||||
"participantResumed": "${name} genoptog",
|
||||
"participantSeeked": "${name} spoled",
|
||||
"participantBuffering": "${name} bufferer",
|
||||
"waitingForParticipants": "Venter på at andre indlæser...",
|
||||
"recentRooms": "Seneste rum",
|
||||
"renameRoom": "Omdøb rum",
|
||||
"removeRoom": "Fjern"
|
||||
|
||||
@@ -753,6 +753,8 @@
|
||||
"participantPaused": "${name} hat pausiert",
|
||||
"participantResumed": "${name} hat fortgesetzt",
|
||||
"participantSeeked": "${name} hat gespult",
|
||||
"participantBuffering": "${name} puffert",
|
||||
"waitingForParticipants": "Warte auf andere zum Laden...",
|
||||
"recentRooms": "Letzte Räume",
|
||||
"renameRoom": "Raum umbenennen",
|
||||
"removeRoom": "Entfernen"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name} paused",
|
||||
"participantResumed": "${name} resumed",
|
||||
"participantSeeked": "${name} seeked",
|
||||
"participantBuffering": "${name} is buffering",
|
||||
"waitingForParticipants": "Waiting for others to load...",
|
||||
"recentRooms": "Recent Rooms",
|
||||
"renameRoom": "Rename Room",
|
||||
"removeRoom": "Remove"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name} pausó",
|
||||
"participantResumed": "${name} reanudó",
|
||||
"participantSeeked": "${name} avanzó",
|
||||
"participantBuffering": "${name} está cargando",
|
||||
"waitingForParticipants": "Esperando a que otros carguen...",
|
||||
"recentRooms": "Salas recientes",
|
||||
"renameRoom": "Renombrar sala",
|
||||
"removeRoom": "Eliminar"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name} a mis en pause",
|
||||
"participantResumed": "${name} a repris",
|
||||
"participantSeeked": "${name} a avancé",
|
||||
"participantBuffering": "${name} met en mémoire tampon",
|
||||
"waitingForParticipants": "En attente du chargement des autres...",
|
||||
"recentRooms": "Salons récents",
|
||||
"renameRoom": "Renommer le salon",
|
||||
"removeRoom": "Supprimer"
|
||||
|
||||
@@ -753,6 +753,8 @@
|
||||
"participantPaused": "${name} ha messo in pausa",
|
||||
"participantResumed": "${name} ha ripreso",
|
||||
"participantSeeked": "${name} ha cercato",
|
||||
"participantBuffering": "${name} sta caricando",
|
||||
"waitingForParticipants": "In attesa che gli altri carichino...",
|
||||
"recentRooms": "Stanze recenti",
|
||||
"renameRoom": "Rinomina stanza",
|
||||
"removeRoom": "Rimuovi"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name}が一時停止しました",
|
||||
"participantResumed": "${name}が再開しました",
|
||||
"participantSeeked": "${name}がシークしました",
|
||||
"participantBuffering": "${name}がバッファリング中",
|
||||
"waitingForParticipants": "他の参加者の読み込みを待っています...",
|
||||
"recentRooms": "最近のルーム",
|
||||
"renameRoom": "ルーム名を変更",
|
||||
"removeRoom": "削除"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name}님이 일시정지했습니다",
|
||||
"participantResumed": "${name}님이 재생했습니다",
|
||||
"participantSeeked": "${name}님이 탐색했습니다",
|
||||
"participantBuffering": "${name}님이 버퍼링 중입니다",
|
||||
"waitingForParticipants": "다른 참가자의 로딩을 기다리는 중...",
|
||||
"recentRooms": "최근 방",
|
||||
"renameRoom": "방 이름 변경",
|
||||
"removeRoom": "제거"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name} pauset",
|
||||
"participantResumed": "${name} gjenopptok",
|
||||
"participantSeeked": "${name} spolet",
|
||||
"participantBuffering": "${name} buffrer",
|
||||
"waitingForParticipants": "Venter på at andre laster inn...",
|
||||
"recentRooms": "Nylige rom",
|
||||
"renameRoom": "Gi nytt navn til rom",
|
||||
"removeRoom": "Fjern"
|
||||
|
||||
@@ -753,6 +753,8 @@
|
||||
"participantPaused": "${name} heeft gepauzeerd",
|
||||
"participantResumed": "${name} heeft hervat",
|
||||
"participantSeeked": "${name} heeft gespoeld",
|
||||
"participantBuffering": "${name} is aan het bufferen",
|
||||
"waitingForParticipants": "Wachten tot anderen geladen zijn...",
|
||||
"recentRooms": "Recente kamers",
|
||||
"renameRoom": "Kamer hernoemen",
|
||||
"removeRoom": "Verwijderen"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name} wstrzymał",
|
||||
"participantResumed": "${name} wznowił",
|
||||
"participantSeeked": "${name} przewinął",
|
||||
"participantBuffering": "${name} buforuje",
|
||||
"waitingForParticipants": "Oczekiwanie na załadowanie u innych...",
|
||||
"recentRooms": "Ostatnie pokoje",
|
||||
"renameRoom": "Zmień nazwę pokoju",
|
||||
"removeRoom": "Usuń"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name} pausou",
|
||||
"participantResumed": "${name} retomou",
|
||||
"participantSeeked": "${name} avançou",
|
||||
"participantBuffering": "${name} está carregando",
|
||||
"waitingForParticipants": "Aguardando outros carregarem...",
|
||||
"recentRooms": "Salas recentes",
|
||||
"renameRoom": "Renomear sala",
|
||||
"removeRoom": "Remover"
|
||||
|
||||
@@ -726,6 +726,8 @@
|
||||
"participantPaused": "${name} поставил на паузу",
|
||||
"participantResumed": "${name} возобновил",
|
||||
"participantSeeked": "${name} перемотал",
|
||||
"participantBuffering": "${name} буферизует",
|
||||
"waitingForParticipants": "Ожидание загрузки у других...",
|
||||
"recentRooms": "Недавние комнаты",
|
||||
"renameRoom": "Переименовать комнату",
|
||||
"removeRoom": "Удалить"
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 15
|
||||
/// Strings: 12960 (864 per locale)
|
||||
/// Strings: 12990 (866 per locale)
|
||||
///
|
||||
/// Built on 2026-04-14 at 10:29 UTC
|
||||
/// Built on 2026-04-14 at 19:56 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherDa implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} satte på pause';
|
||||
@override String participantResumed({required Object name}) => '${name} genoptog';
|
||||
@override String participantSeeked({required Object name}) => '${name} spoled';
|
||||
@override String participantBuffering({required Object name}) => '${name} bufferer';
|
||||
@override String get waitingForParticipants => 'Venter på at andre indlæser...';
|
||||
@override String get recentRooms => 'Seneste rum';
|
||||
@override String get renameRoom => 'Omdøb rum';
|
||||
@override String get removeRoom => 'Fjern';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsDa {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} satte på pause',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} genoptog',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} spoled',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} bufferer',
|
||||
'watchTogether.waitingForParticipants' => 'Venter på at andre indlæser...',
|
||||
'watchTogether.recentRooms' => 'Seneste rum',
|
||||
'watchTogether.renameRoom' => 'Omdøb rum',
|
||||
'watchTogether.removeRoom' => 'Fjern',
|
||||
|
||||
@@ -1013,6 +1013,8 @@ class _TranslationsWatchTogetherDe implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} hat pausiert';
|
||||
@override String participantResumed({required Object name}) => '${name} hat fortgesetzt';
|
||||
@override String participantSeeked({required Object name}) => '${name} hat gespult';
|
||||
@override String participantBuffering({required Object name}) => '${name} puffert';
|
||||
@override String get waitingForParticipants => 'Warte auf andere zum Laden...';
|
||||
@override String get recentRooms => 'Letzte Räume';
|
||||
@override String get renameRoom => 'Raum umbenennen';
|
||||
@override String get removeRoom => 'Entfernen';
|
||||
@@ -2046,6 +2048,8 @@ extension on TranslationsDe {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} hat pausiert',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} hat fortgesetzt',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} hat gespult',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} puffert',
|
||||
'watchTogether.waitingForParticipants' => 'Warte auf andere zum Laden...',
|
||||
'watchTogether.recentRooms' => 'Letzte Räume',
|
||||
'watchTogether.renameRoom' => 'Raum umbenennen',
|
||||
'watchTogether.removeRoom' => 'Entfernen',
|
||||
|
||||
@@ -2228,6 +2228,12 @@ class TranslationsWatchTogetherEn {
|
||||
/// en: '${name} seeked'
|
||||
String participantSeeked({required Object name}) => '${name} seeked';
|
||||
|
||||
/// en: '${name} is buffering'
|
||||
String participantBuffering({required Object name}) => '${name} is buffering';
|
||||
|
||||
/// en: 'Waiting for others to load...'
|
||||
String get waitingForParticipants => 'Waiting for others to load...';
|
||||
|
||||
/// en: 'Recent Rooms'
|
||||
String get recentRooms => 'Recent Rooms';
|
||||
|
||||
@@ -3756,6 +3762,8 @@ extension on Translations {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} paused',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} resumed',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} seeked',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} is buffering',
|
||||
'watchTogether.waitingForParticipants' => 'Waiting for others to load...',
|
||||
'watchTogether.recentRooms' => 'Recent Rooms',
|
||||
'watchTogether.renameRoom' => 'Rename Room',
|
||||
'watchTogether.removeRoom' => 'Remove',
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherEs implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} pausó';
|
||||
@override String participantResumed({required Object name}) => '${name} reanudó';
|
||||
@override String participantSeeked({required Object name}) => '${name} avanzó';
|
||||
@override String participantBuffering({required Object name}) => '${name} está cargando';
|
||||
@override String get waitingForParticipants => 'Esperando a que otros carguen...';
|
||||
@override String get recentRooms => 'Salas recientes';
|
||||
@override String get renameRoom => 'Renombrar sala';
|
||||
@override String get removeRoom => 'Eliminar';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsEs {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} pausó',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} reanudó',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} avanzó',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} está cargando',
|
||||
'watchTogether.waitingForParticipants' => 'Esperando a que otros carguen...',
|
||||
'watchTogether.recentRooms' => 'Salas recientes',
|
||||
'watchTogether.renameRoom' => 'Renombrar sala',
|
||||
'watchTogether.removeRoom' => 'Eliminar',
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherFr implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} a mis en pause';
|
||||
@override String participantResumed({required Object name}) => '${name} a repris';
|
||||
@override String participantSeeked({required Object name}) => '${name} a avancé';
|
||||
@override String participantBuffering({required Object name}) => '${name} met en mémoire tampon';
|
||||
@override String get waitingForParticipants => 'En attente du chargement des autres...';
|
||||
@override String get recentRooms => 'Salons récents';
|
||||
@override String get renameRoom => 'Renommer le salon';
|
||||
@override String get removeRoom => 'Supprimer';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsFr {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} a mis en pause',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} a repris',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} a avancé',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} met en mémoire tampon',
|
||||
'watchTogether.waitingForParticipants' => 'En attente du chargement des autres...',
|
||||
'watchTogether.recentRooms' => 'Salons récents',
|
||||
'watchTogether.renameRoom' => 'Renommer le salon',
|
||||
'watchTogether.removeRoom' => 'Supprimer',
|
||||
|
||||
@@ -1013,6 +1013,8 @@ class _TranslationsWatchTogetherIt implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} ha messo in pausa';
|
||||
@override String participantResumed({required Object name}) => '${name} ha ripreso';
|
||||
@override String participantSeeked({required Object name}) => '${name} ha cercato';
|
||||
@override String participantBuffering({required Object name}) => '${name} sta caricando';
|
||||
@override String get waitingForParticipants => 'In attesa che gli altri carichino...';
|
||||
@override String get recentRooms => 'Stanze recenti';
|
||||
@override String get renameRoom => 'Rinomina stanza';
|
||||
@override String get removeRoom => 'Rimuovi';
|
||||
@@ -2046,6 +2048,8 @@ extension on TranslationsIt {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} ha messo in pausa',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} ha ripreso',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} ha cercato',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} sta caricando',
|
||||
'watchTogether.waitingForParticipants' => 'In attesa che gli altri carichino...',
|
||||
'watchTogether.recentRooms' => 'Stanze recenti',
|
||||
'watchTogether.renameRoom' => 'Rinomina stanza',
|
||||
'watchTogether.removeRoom' => 'Rimuovi',
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherJa implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name}が一時停止しました';
|
||||
@override String participantResumed({required Object name}) => '${name}が再開しました';
|
||||
@override String participantSeeked({required Object name}) => '${name}がシークしました';
|
||||
@override String participantBuffering({required Object name}) => '${name}がバッファリング中';
|
||||
@override String get waitingForParticipants => '他の参加者の読み込みを待っています...';
|
||||
@override String get recentRooms => '最近のルーム';
|
||||
@override String get renameRoom => 'ルーム名を変更';
|
||||
@override String get removeRoom => '削除';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsJa {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name}が一時停止しました',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name}が再開しました',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name}がシークしました',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name}がバッファリング中',
|
||||
'watchTogether.waitingForParticipants' => '他の参加者の読み込みを待っています...',
|
||||
'watchTogether.recentRooms' => '最近のルーム',
|
||||
'watchTogether.renameRoom' => 'ルーム名を変更',
|
||||
'watchTogether.removeRoom' => '削除',
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherKo implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name}님이 일시정지했습니다';
|
||||
@override String participantResumed({required Object name}) => '${name}님이 재생했습니다';
|
||||
@override String participantSeeked({required Object name}) => '${name}님이 탐색했습니다';
|
||||
@override String participantBuffering({required Object name}) => '${name}님이 버퍼링 중입니다';
|
||||
@override String get waitingForParticipants => '다른 참가자의 로딩을 기다리는 중...';
|
||||
@override String get recentRooms => '최근 방';
|
||||
@override String get renameRoom => '방 이름 변경';
|
||||
@override String get removeRoom => '제거';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsKo {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name}님이 일시정지했습니다',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name}님이 재생했습니다',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name}님이 탐색했습니다',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name}님이 버퍼링 중입니다',
|
||||
'watchTogether.waitingForParticipants' => '다른 참가자의 로딩을 기다리는 중...',
|
||||
'watchTogether.recentRooms' => '최근 방',
|
||||
'watchTogether.renameRoom' => '방 이름 변경',
|
||||
'watchTogether.removeRoom' => '제거',
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherNb implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} pauset';
|
||||
@override String participantResumed({required Object name}) => '${name} gjenopptok';
|
||||
@override String participantSeeked({required Object name}) => '${name} spolet';
|
||||
@override String participantBuffering({required Object name}) => '${name} buffrer';
|
||||
@override String get waitingForParticipants => 'Venter på at andre laster inn...';
|
||||
@override String get recentRooms => 'Nylige rom';
|
||||
@override String get renameRoom => 'Gi nytt navn til rom';
|
||||
@override String get removeRoom => 'Fjern';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsNb {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} pauset',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} gjenopptok',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} spolet',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} buffrer',
|
||||
'watchTogether.waitingForParticipants' => 'Venter på at andre laster inn...',
|
||||
'watchTogether.recentRooms' => 'Nylige rom',
|
||||
'watchTogether.renameRoom' => 'Gi nytt navn til rom',
|
||||
'watchTogether.removeRoom' => 'Fjern',
|
||||
|
||||
@@ -1013,6 +1013,8 @@ class _TranslationsWatchTogetherNl implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} heeft gepauzeerd';
|
||||
@override String participantResumed({required Object name}) => '${name} heeft hervat';
|
||||
@override String participantSeeked({required Object name}) => '${name} heeft gespoeld';
|
||||
@override String participantBuffering({required Object name}) => '${name} is aan het bufferen';
|
||||
@override String get waitingForParticipants => 'Wachten tot anderen geladen zijn...';
|
||||
@override String get recentRooms => 'Recente kamers';
|
||||
@override String get renameRoom => 'Kamer hernoemen';
|
||||
@override String get removeRoom => 'Verwijderen';
|
||||
@@ -2046,6 +2048,8 @@ extension on TranslationsNl {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} heeft gepauzeerd',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} heeft hervat',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} heeft gespoeld',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} is aan het bufferen',
|
||||
'watchTogether.waitingForParticipants' => 'Wachten tot anderen geladen zijn...',
|
||||
'watchTogether.recentRooms' => 'Recente kamers',
|
||||
'watchTogether.renameRoom' => 'Kamer hernoemen',
|
||||
'watchTogether.removeRoom' => 'Verwijderen',
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherPl implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} wstrzymał';
|
||||
@override String participantResumed({required Object name}) => '${name} wznowił';
|
||||
@override String participantSeeked({required Object name}) => '${name} przewinął';
|
||||
@override String participantBuffering({required Object name}) => '${name} buforuje';
|
||||
@override String get waitingForParticipants => 'Oczekiwanie na załadowanie u innych...';
|
||||
@override String get recentRooms => 'Ostatnie pokoje';
|
||||
@override String get renameRoom => 'Zmień nazwę pokoju';
|
||||
@override String get removeRoom => 'Usuń';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsPl {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} wstrzymał',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} wznowił',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} przewinął',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} buforuje',
|
||||
'watchTogether.waitingForParticipants' => 'Oczekiwanie na załadowanie u innych...',
|
||||
'watchTogether.recentRooms' => 'Ostatnie pokoje',
|
||||
'watchTogether.renameRoom' => 'Zmień nazwę pokoju',
|
||||
'watchTogether.removeRoom' => 'Usuń',
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherPt implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} pausou';
|
||||
@override String participantResumed({required Object name}) => '${name} retomou';
|
||||
@override String participantSeeked({required Object name}) => '${name} avançou';
|
||||
@override String participantBuffering({required Object name}) => '${name} está carregando';
|
||||
@override String get waitingForParticipants => 'Aguardando outros carregarem...';
|
||||
@override String get recentRooms => 'Salas recentes';
|
||||
@override String get renameRoom => 'Renomear sala';
|
||||
@override String get removeRoom => 'Remover';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsPt {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} pausou',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} retomou',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} avançou',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} está carregando',
|
||||
'watchTogether.waitingForParticipants' => 'Aguardando outros carregarem...',
|
||||
'watchTogether.recentRooms' => 'Salas recentes',
|
||||
'watchTogether.renameRoom' => 'Renomear sala',
|
||||
'watchTogether.removeRoom' => 'Remover',
|
||||
|
||||
@@ -979,6 +979,8 @@ class _TranslationsWatchTogetherRu implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} поставил на паузу';
|
||||
@override String participantResumed({required Object name}) => '${name} возобновил';
|
||||
@override String participantSeeked({required Object name}) => '${name} перемотал';
|
||||
@override String participantBuffering({required Object name}) => '${name} буферизует';
|
||||
@override String get waitingForParticipants => 'Ожидание загрузки у других...';
|
||||
@override String get recentRooms => 'Недавние комнаты';
|
||||
@override String get renameRoom => 'Переименовать комнату';
|
||||
@override String get removeRoom => 'Удалить';
|
||||
@@ -2021,6 +2023,8 @@ extension on TranslationsRu {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} поставил на паузу',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} возобновил',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} перемотал',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} буферизует',
|
||||
'watchTogether.waitingForParticipants' => 'Ожидание загрузки у других...',
|
||||
'watchTogether.recentRooms' => 'Недавние комнаты',
|
||||
'watchTogether.renameRoom' => 'Переименовать комнату',
|
||||
'watchTogether.removeRoom' => 'Удалить',
|
||||
|
||||
@@ -1013,6 +1013,8 @@ class _TranslationsWatchTogetherSv implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} pausade';
|
||||
@override String participantResumed({required Object name}) => '${name} återupptog';
|
||||
@override String participantSeeked({required Object name}) => '${name} spolade';
|
||||
@override String participantBuffering({required Object name}) => '${name} buffrar';
|
||||
@override String get waitingForParticipants => 'Väntar på att andra laddar...';
|
||||
@override String get recentRooms => 'Senaste rum';
|
||||
@override String get renameRoom => 'Byt namn på rum';
|
||||
@override String get removeRoom => 'Ta bort';
|
||||
@@ -2046,6 +2048,8 @@ extension on TranslationsSv {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} pausade',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} återupptog',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} spolade',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} buffrar',
|
||||
'watchTogether.waitingForParticipants' => 'Väntar på att andra laddar...',
|
||||
'watchTogether.recentRooms' => 'Senaste rum',
|
||||
'watchTogether.renameRoom' => 'Byt namn på rum',
|
||||
'watchTogether.removeRoom' => 'Ta bort',
|
||||
|
||||
@@ -1013,6 +1013,8 @@ class _TranslationsWatchTogetherZh implements TranslationsWatchTogetherEn {
|
||||
@override String participantPaused({required Object name}) => '${name} 暂停了';
|
||||
@override String participantResumed({required Object name}) => '${name} 继续播放了';
|
||||
@override String participantSeeked({required Object name}) => '${name} 跳转了';
|
||||
@override String participantBuffering({required Object name}) => '${name} 正在缓冲';
|
||||
@override String get waitingForParticipants => '等待其他人加载...';
|
||||
@override String get recentRooms => '最近的房间';
|
||||
@override String get renameRoom => '重命名房间';
|
||||
@override String get removeRoom => '移除';
|
||||
@@ -2046,6 +2048,8 @@ extension on TranslationsZh {
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} 暂停了',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} 继续播放了',
|
||||
'watchTogether.participantSeeked' => ({required Object name}) => '${name} 跳转了',
|
||||
'watchTogether.participantBuffering' => ({required Object name}) => '${name} 正在缓冲',
|
||||
'watchTogether.waitingForParticipants' => '等待其他人加载...',
|
||||
'watchTogether.recentRooms' => '最近的房间',
|
||||
'watchTogether.renameRoom' => '重命名房间',
|
||||
'watchTogether.removeRoom' => '移除',
|
||||
|
||||
@@ -753,6 +753,8 @@
|
||||
"participantPaused": "${name} pausade",
|
||||
"participantResumed": "${name} återupptog",
|
||||
"participantSeeked": "${name} spolade",
|
||||
"participantBuffering": "${name} buffrar",
|
||||
"waitingForParticipants": "Väntar på att andra laddar...",
|
||||
"recentRooms": "Senaste rum",
|
||||
"renameRoom": "Byt namn på rum",
|
||||
"removeRoom": "Ta bort"
|
||||
|
||||
@@ -753,6 +753,8 @@
|
||||
"participantPaused": "${name} 暂停了",
|
||||
"participantResumed": "${name} 继续播放了",
|
||||
"participantSeeked": "${name} 跳转了",
|
||||
"participantBuffering": "${name} 正在缓冲",
|
||||
"waitingForParticipants": "等待其他人加载...",
|
||||
"recentRooms": "最近的房间",
|
||||
"renameRoom": "重命名房间",
|
||||
"removeRoom": "移除"
|
||||
|
||||
@@ -3413,8 +3413,12 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
);
|
||||
},
|
||||
),
|
||||
// Watch Together: participant join/leave notifications
|
||||
// Watch Together: participant join/leave/buffering notifications
|
||||
const ParticipantNotificationOverlay(),
|
||||
// Watch Together: waiting for participants to load
|
||||
const WaitingForParticipantsIndicator(),
|
||||
// Watch Together: syncing indicator during drift correction
|
||||
const SyncingIndicator(),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -28,6 +28,7 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
WatchTogetherSyncManager? _syncManager;
|
||||
final List<Participant> _participants = [];
|
||||
bool _isSyncing = false;
|
||||
bool _isDeferredPlay = false;
|
||||
String _displayName = 'User';
|
||||
String? _lastHandledCurrentPlaybackKey;
|
||||
|
||||
@@ -83,6 +84,7 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
bool get isHost => _session?.isHost ?? false;
|
||||
bool get isConnected => _session?.isConnected ?? false;
|
||||
bool get isSyncing => _isSyncing;
|
||||
bool get isDeferredPlay => _isDeferredPlay;
|
||||
WatchSession? get session => _session;
|
||||
List<Participant> get participants => List.unmodifiable(_participants);
|
||||
int get participantCount => _participants.length;
|
||||
@@ -178,6 +180,10 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
_isSyncing = isSyncing;
|
||||
notifyListeners();
|
||||
};
|
||||
_syncManager!.onDeferredPlayChanged = (isDeferredPlay) {
|
||||
_isDeferredPlay = isDeferredPlay;
|
||||
notifyListeners();
|
||||
};
|
||||
}
|
||||
|
||||
/// Create a new watch together session as host
|
||||
@@ -348,6 +354,7 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
_session = null;
|
||||
_participants.clear();
|
||||
_isSyncing = false;
|
||||
_isDeferredPlay = false;
|
||||
_lastHandledCurrentPlaybackKey = null;
|
||||
_lastActionEventMs.clear();
|
||||
|
||||
@@ -491,6 +498,9 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
final newState = message.bufferingState ?? false;
|
||||
if (_participants[index].isBuffering != newState) {
|
||||
_participants[index] = _participants[index].copyWith(isBuffering: newState);
|
||||
if (newState) {
|
||||
_emitActionEvent(message.peerId, ParticipantEventType.buffering);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
@@ -737,7 +747,7 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
/// Type of participant event
|
||||
enum ParticipantEventType { joined, left, paused, resumed, seeked }
|
||||
enum ParticipantEventType { joined, left, paused, resumed, seeked, buffering }
|
||||
|
||||
/// Event emitted when a participant joins or leaves
|
||||
class ParticipantEvent {
|
||||
|
||||
@@ -14,6 +14,9 @@ typedef SessionConfigCallback = void Function(ControlMode controlMode);
|
||||
/// Callback type for when sync state changes
|
||||
typedef SyncStateCallback = void Function(bool isSyncing);
|
||||
|
||||
/// Callback type for when deferred play state changes
|
||||
typedef DeferredPlayCallback = void Function(bool isDeferredPlay);
|
||||
|
||||
/// Manages playback synchronization between peers
|
||||
///
|
||||
/// This class:
|
||||
@@ -79,6 +82,7 @@ class WatchTogetherSyncManager {
|
||||
// Callbacks
|
||||
SessionConfigCallback? onSessionConfigReceived;
|
||||
SyncStateCallback? onSyncStateChanged;
|
||||
DeferredPlayCallback? onDeferredPlayChanged;
|
||||
|
||||
WatchTogetherSyncManager({
|
||||
required WatchTogetherPeerService peerService,
|
||||
@@ -169,7 +173,7 @@ class WatchTogetherSyncManager {
|
||||
_peerReady[_peerService.myPeerId!] = false;
|
||||
}
|
||||
_hasAnnouncedReady = false;
|
||||
_deferredPlay = false;
|
||||
_setDeferredPlay(false);
|
||||
_deferredPlayPosition = null;
|
||||
_firstPlayCompleted = false;
|
||||
_syncingTimer?.cancel();
|
||||
@@ -208,7 +212,7 @@ class WatchTogetherSyncManager {
|
||||
|
||||
if (isPlaying && !isAllReady && !_firstPlayCompleted) {
|
||||
// Defer until all peers have loaded video (initial sync only)
|
||||
_deferredPlay = true;
|
||||
_setDeferredPlay(true);
|
||||
_deferredPlayPosition = player.state.position;
|
||||
_isRemoteAction = true;
|
||||
try {
|
||||
@@ -228,7 +232,7 @@ class WatchTogetherSyncManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isPlaying) _deferredPlay = false;
|
||||
if (!isPlaying) _setDeferredPlay(false);
|
||||
_broadcastPlayPause(isPlaying);
|
||||
}),
|
||||
);
|
||||
@@ -572,7 +576,7 @@ class WatchTogetherSyncManager {
|
||||
|
||||
case SyncMessageType.pause:
|
||||
if (!_shouldApplyRemoteControl(message)) break;
|
||||
_deferredPlay = false;
|
||||
_setDeferredPlay(false);
|
||||
await _applyRemotePause(expectedAttachmentGeneration: queuedAttachmentGeneration);
|
||||
break;
|
||||
|
||||
@@ -663,7 +667,7 @@ class WatchTogetherSyncManager {
|
||||
appLogger.d('WatchTogether: Peer ${message.peerId} player ready: ${message.bufferingState}');
|
||||
|
||||
if (_deferredPlay && isAllReady) {
|
||||
_deferredPlay = false;
|
||||
_setDeferredPlay(false);
|
||||
_firstPlayCompleted = true;
|
||||
await _applyRemotePlay(
|
||||
position: _deferredPlayPosition,
|
||||
@@ -903,10 +907,10 @@ class WatchTogetherSyncManager {
|
||||
final hostIsPlaying = message.isPlaying ?? (message.bufferingState == false);
|
||||
if (hostIsPlaying) {
|
||||
// Host was playing — defer until our video is loaded
|
||||
_deferredPlay = true;
|
||||
_setDeferredPlay(true);
|
||||
_deferredPlayPosition = message.position;
|
||||
if (_hasAnnouncedReady) {
|
||||
_deferredPlay = false;
|
||||
_setDeferredPlay(false);
|
||||
_firstPlayCompleted = true;
|
||||
final didPlay = await _runGuardedPlayerCommand(
|
||||
actionName: 'session config play',
|
||||
@@ -943,6 +947,14 @@ class WatchTogetherSyncManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set deferred play state and notify listeners
|
||||
void _setDeferredPlay(bool value) {
|
||||
if (_deferredPlay != value) {
|
||||
_deferredPlay = value;
|
||||
onDeferredPlayChanged?.call(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Send join announcement to all peers
|
||||
void announceJoin(String displayName) {
|
||||
_peerService.broadcast(
|
||||
|
||||
@@ -352,6 +352,7 @@ class _ParticipantNotificationOverlayState extends State<ParticipantNotification
|
||||
ParticipantEventType.paused => t.watchTogether.participantPaused(name: n.event.displayName),
|
||||
ParticipantEventType.resumed => t.watchTogether.participantResumed(name: n.event.displayName),
|
||||
ParticipantEventType.seeked => t.watchTogether.participantSeeked(name: n.event.displayName),
|
||||
ParticipantEventType.buffering => t.watchTogether.participantBuffering(name: n.event.displayName),
|
||||
};
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
@@ -381,41 +382,67 @@ class SyncingIndicator extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<WatchTogetherProvider>(
|
||||
builder: (context, provider, child) {
|
||||
if (!provider.isSyncing) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Positioned(
|
||||
bottom: 80,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.black54,
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 14,
|
||||
height: 14,
|
||||
child: PlatformDetector.isTV()
|
||||
? const Icon(Symbols.sync_rounded, size: 14, color: Colors.white)
|
||||
: const CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(t.watchTogether.syncing, style: const TextStyle(color: Colors.white, fontSize: 12)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return Selector<WatchTogetherProvider, bool>(
|
||||
selector: (_, provider) => provider.isSyncing,
|
||||
builder: (context, isSyncing, child) {
|
||||
if (!isSyncing) return const SizedBox.shrink();
|
||||
return _StatusPill(tvIcon: Symbols.sync_rounded, label: t.watchTogether.syncing);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicator shown when playback is deferred waiting for participants to load
|
||||
class WaitingForParticipantsIndicator extends StatelessWidget {
|
||||
const WaitingForParticipantsIndicator({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Selector<WatchTogetherProvider, bool>(
|
||||
selector: (_, provider) => provider.isDeferredPlay,
|
||||
builder: (context, isDeferredPlay, child) {
|
||||
if (!isDeferredPlay) return const SizedBox.shrink();
|
||||
return _StatusPill(tvIcon: Symbols.hourglass_empty_rounded, label: t.watchTogether.waitingForParticipants);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _StatusPill extends StatelessWidget {
|
||||
final IconData tvIcon;
|
||||
final String label;
|
||||
|
||||
const _StatusPill({required this.tvIcon, required this.label});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
bottom: 80,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.black54,
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 14,
|
||||
height: 14,
|
||||
child: PlatformDetector.isTV()
|
||||
? Icon(tvIcon, size: 14, color: Colors.white)
|
||||
: const CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(label, style: const TextStyle(color: Colors.white, fontSize: 12)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user