diff --git a/lib/i18n/da.i18n.json b/lib/i18n/da.i18n.json index e7b86b5b..d4a04999 100644 --- a/lib/i18n/da.i18n.json +++ b/lib/i18n/da.i18n.json @@ -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" diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index 8f5ec045..02d1530b 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -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" diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index 41cc356a..46d52249 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -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" diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index 25e8339a..be67234b 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -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" diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index bbaedcce..36fb6995 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -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" diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index f7afc53e..035b9776 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -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" diff --git a/lib/i18n/ja.i18n.json b/lib/i18n/ja.i18n.json index 209ea956..c7c323ef 100644 --- a/lib/i18n/ja.i18n.json +++ b/lib/i18n/ja.i18n.json @@ -726,6 +726,8 @@ "participantPaused": "${name}が一時停止しました", "participantResumed": "${name}が再開しました", "participantSeeked": "${name}がシークしました", + "participantBuffering": "${name}がバッファリング中", + "waitingForParticipants": "他の参加者の読み込みを待っています...", "recentRooms": "最近のルーム", "renameRoom": "ルーム名を変更", "removeRoom": "削除" diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index e9772b55..e7f87cc6 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -726,6 +726,8 @@ "participantPaused": "${name}님이 일시정지했습니다", "participantResumed": "${name}님이 재생했습니다", "participantSeeked": "${name}님이 탐색했습니다", + "participantBuffering": "${name}님이 버퍼링 중입니다", + "waitingForParticipants": "다른 참가자의 로딩을 기다리는 중...", "recentRooms": "최근 방", "renameRoom": "방 이름 변경", "removeRoom": "제거" diff --git a/lib/i18n/nb.i18n.json b/lib/i18n/nb.i18n.json index 9f17cae6..235bb971 100644 --- a/lib/i18n/nb.i18n.json +++ b/lib/i18n/nb.i18n.json @@ -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" diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index 36b9c4ef..7d4b9e1f 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -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" diff --git a/lib/i18n/pl.i18n.json b/lib/i18n/pl.i18n.json index 04fb3eb7..cf5a00c3 100644 --- a/lib/i18n/pl.i18n.json +++ b/lib/i18n/pl.i18n.json @@ -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ń" diff --git a/lib/i18n/pt.i18n.json b/lib/i18n/pt.i18n.json index 96cac004..c10e6c81 100644 --- a/lib/i18n/pt.i18n.json +++ b/lib/i18n/pt.i18n.json @@ -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" diff --git a/lib/i18n/ru.i18n.json b/lib/i18n/ru.i18n.json index 3fecdba9..2ecb4917 100644 --- a/lib/i18n/ru.i18n.json +++ b/lib/i18n/ru.i18n.json @@ -726,6 +726,8 @@ "participantPaused": "${name} поставил на паузу", "participantResumed": "${name} возобновил", "participantSeeked": "${name} перемотал", + "participantBuffering": "${name} буферизует", + "waitingForParticipants": "Ожидание загрузки у других...", "recentRooms": "Недавние комнаты", "renameRoom": "Переименовать комнату", "removeRoom": "Удалить" diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 67459307..06c36fb1 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -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 diff --git a/lib/i18n/strings_da.g.dart b/lib/i18n/strings_da.g.dart index a476d0b4..b1cb190d 100644 --- a/lib/i18n/strings_da.g.dart +++ b/lib/i18n/strings_da.g.dart @@ -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', diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index ca370f3a..833b8ed9 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -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', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index 735b0ee9..9ac23bd7 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -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', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index 050360b0..51e0c373 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -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', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index 12405ccd..42f83e50 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -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', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index 05f450da..2af9eec6 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -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', diff --git a/lib/i18n/strings_ja.g.dart b/lib/i18n/strings_ja.g.dart index 662036aa..f5781aab 100644 --- a/lib/i18n/strings_ja.g.dart +++ b/lib/i18n/strings_ja.g.dart @@ -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' => '削除', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index 3d7ff58c..c89f4abc 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -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' => '제거', diff --git a/lib/i18n/strings_nb.g.dart b/lib/i18n/strings_nb.g.dart index 40c07eec..ce6d494f 100644 --- a/lib/i18n/strings_nb.g.dart +++ b/lib/i18n/strings_nb.g.dart @@ -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', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index 44ea6adf..4e250089 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -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', diff --git a/lib/i18n/strings_pl.g.dart b/lib/i18n/strings_pl.g.dart index 240cc549..bba22cc2 100644 --- a/lib/i18n/strings_pl.g.dart +++ b/lib/i18n/strings_pl.g.dart @@ -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ń', diff --git a/lib/i18n/strings_pt.g.dart b/lib/i18n/strings_pt.g.dart index bdd406e9..574b7b60 100644 --- a/lib/i18n/strings_pt.g.dart +++ b/lib/i18n/strings_pt.g.dart @@ -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', diff --git a/lib/i18n/strings_ru.g.dart b/lib/i18n/strings_ru.g.dart index 60154420..837e0273 100644 --- a/lib/i18n/strings_ru.g.dart +++ b/lib/i18n/strings_ru.g.dart @@ -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' => 'Удалить', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 170318f7..81a62ed8 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -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', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index 8ec486ea..2e308243 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -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' => '移除', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index 7197cad2..4f1053b1 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -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" diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index 2f860034..5e8c49c1 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -753,6 +753,8 @@ "participantPaused": "${name} 暂停了", "participantResumed": "${name} 继续播放了", "participantSeeked": "${name} 跳转了", + "participantBuffering": "${name} 正在缓冲", + "waitingForParticipants": "等待其他人加载...", "recentRooms": "最近的房间", "renameRoom": "重命名房间", "removeRoom": "移除" diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index 0abb23e8..1137300c 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -3413,8 +3413,12 @@ class VideoPlayerScreenState extends State 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(), ], ), ), diff --git a/lib/watch_together/providers/watch_together_provider.dart b/lib/watch_together/providers/watch_together_provider.dart index 8751d170..09c96470 100644 --- a/lib/watch_together/providers/watch_together_provider.dart +++ b/lib/watch_together/providers/watch_together_provider.dart @@ -28,6 +28,7 @@ class WatchTogetherProvider with ChangeNotifier { WatchTogetherSyncManager? _syncManager; final List _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 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 { diff --git a/lib/watch_together/services/watch_together_sync_manager.dart b/lib/watch_together/services/watch_together_sync_manager.dart index 23d5f4f9..b04a3b44 100644 --- a/lib/watch_together/services/watch_together_sync_manager.dart +++ b/lib/watch_together/services/watch_together_sync_manager.dart @@ -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( diff --git a/lib/watch_together/widgets/watch_together_overlay.dart b/lib/watch_together/widgets/watch_together_overlay.dart index 4f37a29c..7b62be9f 100644 --- a/lib/watch_together/widgets/watch_together_overlay.dart +++ b/lib/watch_together/widgets/watch_together_overlay.dart @@ -352,6 +352,7 @@ class _ParticipantNotificationOverlayState extends State 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( - 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( + 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( + 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)), + ], + ), + ), + ), + ); + } +}