From 771c431188897948f974998a697ef24569c2e8ee Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Tue, 14 Apr 2026 22:29:05 +0200 Subject: [PATCH] fix: treat 500 as permanent failure, show error in UI --- lib/i18n/da.i18n.json | 1 + lib/i18n/de.i18n.json | 1 + lib/i18n/en.i18n.json | 1 + lib/i18n/es.i18n.json | 1 + lib/i18n/fr.i18n.json | 1 + lib/i18n/it.i18n.json | 1 + lib/i18n/ja.i18n.json | 1 + lib/i18n/ko.i18n.json | 1 + lib/i18n/nb.i18n.json | 1 + lib/i18n/nl.i18n.json | 1 + lib/i18n/pl.i18n.json | 1 + lib/i18n/pt.i18n.json | 1 + lib/i18n/ru.i18n.json | 1 + lib/i18n/strings.g.dart | 4 ++-- lib/i18n/strings_da.g.dart | 2 ++ lib/i18n/strings_de.g.dart | 2 ++ lib/i18n/strings_en.g.dart | 4 ++++ lib/i18n/strings_es.g.dart | 2 ++ lib/i18n/strings_fr.g.dart | 2 ++ lib/i18n/strings_it.g.dart | 2 ++ lib/i18n/strings_ja.g.dart | 2 ++ lib/i18n/strings_ko.g.dart | 2 ++ lib/i18n/strings_nb.g.dart | 2 ++ lib/i18n/strings_nl.g.dart | 2 ++ lib/i18n/strings_pl.g.dart | 2 ++ lib/i18n/strings_pt.g.dart | 2 ++ lib/i18n/strings_ru.g.dart | 2 ++ lib/i18n/strings_sv.g.dart | 2 ++ lib/i18n/strings_zh.g.dart | 2 ++ lib/i18n/sv.i18n.json | 1 + lib/i18n/zh.i18n.json | 1 + lib/providers/download_provider.dart | 1 + lib/services/download_manager_service.dart | 9 +++++++-- lib/widgets/download_tree_view.dart | 12 ++++++++++++ 34 files changed, 69 insertions(+), 4 deletions(-) diff --git a/lib/i18n/da.i18n.json b/lib/i18n/da.i18n.json index d4a04999..4726d58c 100644 --- a/lib/i18n/da.i18n.json +++ b/lib/i18n/da.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "Slet download", "retryDownload": "Prøv download igen", "downloadQueued": "Download i kø", + "serverErrorBitrate": "Serverfejl — filen overskrider muligvis grænsen for fjernstreaming-bitrate", "episodesQueued": "${count} episoder i downloadkø", "downloadDeleted": "Download slettet", "deleteConfirm": "Er du sikker på, at du vil slette \"${title}\"? Den downloadede fil fjernes fra din enhed.", diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index 02d1530b..fc2f3a90 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -632,6 +632,7 @@ "deleteDownload": "Download löschen", "retryDownload": "Download wiederholen", "downloadQueued": "Download in Warteschlange", + "serverErrorBitrate": "Serverfehler — die Datei überschreitet möglicherweise das Remote-Streaming-Bitratenlimit", "episodesQueued": "${count} Episoden zum Download hinzugefügt", "downloadDeleted": "Download gelöscht", "deleteConfirm": "Möchtest du \"${title}\" wirklich löschen? Die heruntergeladene Datei wird von deinem Gerät entfernt.", diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index 46d52249..11861a0c 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "Delete download", "retryDownload": "Retry download", "downloadQueued": "Download queued", + "serverErrorBitrate": "Server error — the file may exceed the remote streaming bitrate limit", "episodesQueued": "${count} episodes queued for download", "downloadDeleted": "Download deleted", "deleteConfirm": "Are you sure you want to delete \"${title}\"? This will remove the downloaded file from your device.", diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index be67234b..12022aa9 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "Eliminar descarga", "retryDownload": "Reintentar descarga", "downloadQueued": "Descarga en cola", + "serverErrorBitrate": "Error del servidor — el archivo puede exceder el límite de bitrate de transmisión remota", "episodesQueued": "${count} episodios en cola para descargar", "downloadDeleted": "Descarga eliminada", "deleteConfirm": "¿Estás seguro de que quieres eliminar \"${title}\"? Esto borrará el archivo descargado de tu dispositivo.", diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index 36fb6995..d4a1a1d2 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "Supprimer le téléchargement", "retryDownload": "Réessayer le téléchargement", "downloadQueued": "Téléchargement en attente", + "serverErrorBitrate": "Erreur serveur — le fichier dépasse peut-être la limite de débit du streaming à distance", "episodesQueued": "${count} épisodes en attente de téléchargement", "downloadDeleted": "Télécharger supprimé", "deleteConfirm": "Êtes-vous sûr de vouloir supprimer \"${title}\" ? Cela supprimera le fichier téléchargé de votre appareil.", diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index 035b9776..2c041a0a 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -632,6 +632,7 @@ "deleteDownload": "Elimina download", "retryDownload": "Riprova download", "downloadQueued": "Download in coda", + "serverErrorBitrate": "Errore del server — il file potrebbe superare il limite di bitrate dello streaming remoto", "episodesQueued": "${count} episodi in coda per il download", "downloadDeleted": "Download eliminato", "deleteConfirm": "Sei sicuro di voler eliminare \"${title}\"? Il file scaricato verrà rimosso dal tuo dispositivo.", diff --git a/lib/i18n/ja.i18n.json b/lib/i18n/ja.i18n.json index c7c323ef..fc0ca2a5 100644 --- a/lib/i18n/ja.i18n.json +++ b/lib/i18n/ja.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "ダウンロードを削除", "retryDownload": "ダウンロードを再試行", "downloadQueued": "ダウンロードをキューに追加しました", + "serverErrorBitrate": "サーバーエラー — ファイルがリモートストリーミングのビットレート制限を超えている可能性があります", "episodesQueued": "${count}エピソードをダウンロードキューに追加しました", "downloadDeleted": "ダウンロードを削除しました", "deleteConfirm": "\"${title}\"を削除してもよろしいですか?ダウンロードしたファイルがデバイスから削除されます。", diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index e7f87cc6..c078ef69 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "다운로드 삭제", "retryDownload": "다운로드 재시도", "downloadQueued": "다운로드 대기 중", + "serverErrorBitrate": "서버 오류 — 파일이 원격 스트리밍 비트레이트 제한을 초과할 수 있습니다", "episodesQueued": "${count} 에피소드가 다운로드 대기열에 추가 되었습니다", "downloadDeleted": "다운로드 삭제됨", "deleteConfirm": "\"${title}\"를 삭제 하시겠습니까? 다운로드한 파일이 기기에서 삭제됩니다.", diff --git a/lib/i18n/nb.i18n.json b/lib/i18n/nb.i18n.json index 235bb971..66826a26 100644 --- a/lib/i18n/nb.i18n.json +++ b/lib/i18n/nb.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "Slett nedlasting", "retryDownload": "Prøv nedlasting på nytt", "downloadQueued": "Nedlasting i kø", + "serverErrorBitrate": "Serverfeil — filen overskrider muligens grensen for fjernstrømming-bitrate", "episodesQueued": "${count} episoder i nedlastingskø", "downloadDeleted": "Nedlasting slettet", "deleteConfirm": "Er du sikker på at du vil slette \"${title}\"? Dette vil fjerne den nedlastede filen fra enheten din.", diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index 7d4b9e1f..f10e2e51 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -632,6 +632,7 @@ "deleteDownload": "Download verwijderen", "retryDownload": "Download opnieuw proberen", "downloadQueued": "Download in wachtrij", + "serverErrorBitrate": "Serverfout — het bestand overschrijdt mogelijk de bitrate-limiet voor remote streaming", "episodesQueued": "${count} afleveringen in wachtrij voor download", "downloadDeleted": "Download verwijderd", "deleteConfirm": "Weet je zeker dat je \"${title}\" wilt verwijderen? Het gedownloade bestand wordt van je apparaat verwijderd.", diff --git a/lib/i18n/pl.i18n.json b/lib/i18n/pl.i18n.json index cf5a00c3..10781981 100644 --- a/lib/i18n/pl.i18n.json +++ b/lib/i18n/pl.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "Usuń pobranie", "retryDownload": "Ponów pobieranie", "downloadQueued": "Pobranie w kolejce", + "serverErrorBitrate": "Błąd serwera — plik może przekraczać limit bitrate zdalnego streamingu", "episodesQueued": "${count} odcinków w kolejce pobierania", "downloadDeleted": "Pobranie usunięte", "deleteConfirm": "Czy na pewno chcesz usunąć \"${title}\"? Spowoduje to usunięcie pobranego pliku z urządzenia.", diff --git a/lib/i18n/pt.i18n.json b/lib/i18n/pt.i18n.json index c10e6c81..30e5f7ab 100644 --- a/lib/i18n/pt.i18n.json +++ b/lib/i18n/pt.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "Excluir download", "retryDownload": "Tentar download novamente", "downloadQueued": "Download na fila", + "serverErrorBitrate": "Erro do servidor — o arquivo pode exceder o limite de bitrate de streaming remoto", "episodesQueued": "${count} episódios na fila de download", "downloadDeleted": "Download excluído", "deleteConfirm": "Tem certeza que deseja excluir \"${title}\"? Isso removerá o arquivo baixado do seu dispositivo.", diff --git a/lib/i18n/ru.i18n.json b/lib/i18n/ru.i18n.json index 2ecb4917..5c92a9ca 100644 --- a/lib/i18n/ru.i18n.json +++ b/lib/i18n/ru.i18n.json @@ -743,6 +743,7 @@ "deleteDownload": "Удалить загрузку", "retryDownload": "Повторить загрузку", "downloadQueued": "Загрузка поставлена в очередь", + "serverErrorBitrate": "Ошибка сервера — файл может превышать лимит битрейта удалённого стриминга", "episodesQueued": "${count} эпизодов поставлено в очередь загрузки", "downloadDeleted": "Загрузка удалена", "deleteConfirm": "Вы уверены, что хотите удалить \"${title}\"? Загруженный файл будет удалён с устройства.", diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 06c36fb1..a37207b3 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: 12990 (866 per locale) +/// Strings: 13005 (867 per locale) /// -/// Built on 2026-04-14 at 19:56 UTC +/// Built on 2026-04-14 at 20:28 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 b1cb190d..fcbed642 100644 --- a/lib/i18n/strings_da.g.dart +++ b/lib/i18n/strings_da.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsDa implements TranslationsDownloadsEn { @override String get deleteDownload => 'Slet download'; @override String get retryDownload => 'Prøv download igen'; @override String get downloadQueued => 'Download i kø'; + @override String get serverErrorBitrate => 'Serverfejl — filen overskrider muligvis grænsen for fjernstreaming-bitrate'; @override String episodesQueued({required Object count}) => '${count} episoder i downloadkø'; @override String get downloadDeleted => 'Download slettet'; @override String deleteConfirm({required Object title}) => 'Er du sikker på, at du vil slette "${title}"? Den downloadede fil fjernes fra din enhed.'; @@ -2038,6 +2039,7 @@ extension on TranslationsDa { 'downloads.deleteDownload' => 'Slet download', 'downloads.retryDownload' => 'Prøv download igen', 'downloads.downloadQueued' => 'Download i kø', + 'downloads.serverErrorBitrate' => 'Serverfejl — filen overskrider muligvis grænsen for fjernstreaming-bitrate', 'downloads.episodesQueued' => ({required Object count}) => '${count} episoder i downloadkø', 'downloads.downloadDeleted' => 'Download slettet', 'downloads.deleteConfirm' => ({required Object title}) => 'Er du sikker på, at du vil slette "${title}"? Den downloadede fil fjernes fra din enhed.', diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index 833b8ed9..3691c148 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -871,6 +871,7 @@ class _TranslationsDownloadsDe implements TranslationsDownloadsEn { @override String get deleteDownload => 'Download löschen'; @override String get retryDownload => 'Download wiederholen'; @override String get downloadQueued => 'Download in Warteschlange'; + @override String get serverErrorBitrate => 'Serverfehler — die Datei überschreitet möglicherweise das Remote-Streaming-Bitratenlimit'; @override String episodesQueued({required Object count}) => '${count} Episoden zum Download hinzugefügt'; @override String get downloadDeleted => 'Download gelöscht'; @override String deleteConfirm({required Object title}) => 'Möchtest du "${title}" wirklich löschen? Die heruntergeladene Datei wird von deinem Gerät entfernt.'; @@ -1933,6 +1934,7 @@ extension on TranslationsDe { 'downloads.deleteDownload' => 'Download löschen', 'downloads.retryDownload' => 'Download wiederholen', 'downloads.downloadQueued' => 'Download in Warteschlange', + 'downloads.serverErrorBitrate' => 'Serverfehler — die Datei überschreitet möglicherweise das Remote-Streaming-Bitratenlimit', 'downloads.episodesQueued' => ({required Object count}) => '${count} Episoden zum Download hinzugefügt', 'downloads.downloadDeleted' => 'Download gelöscht', 'downloads.deleteConfirm' => ({required Object title}) => 'Möchtest du "${title}" wirklich löschen? Die heruntergeladene Datei wird von deinem Gerät entfernt.', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index 9ac23bd7..a591d2f8 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -2282,6 +2282,9 @@ class TranslationsDownloadsEn { /// en: 'Download queued' String get downloadQueued => 'Download queued'; + /// en: 'Server error — the file may exceed the remote streaming bitrate limit' + String get serverErrorBitrate => 'Server error — the file may exceed the remote streaming bitrate limit'; + /// en: '${count} episodes queued for download' String episodesQueued({required Object count}) => '${count} episodes queued for download'; @@ -3777,6 +3780,7 @@ extension on Translations { 'downloads.deleteDownload' => 'Delete download', 'downloads.retryDownload' => 'Retry download', 'downloads.downloadQueued' => 'Download queued', + 'downloads.serverErrorBitrate' => 'Server error — the file may exceed the remote streaming bitrate limit', 'downloads.episodesQueued' => ({required Object count}) => '${count} episodes queued for download', 'downloads.downloadDeleted' => 'Download deleted', 'downloads.deleteConfirm' => ({required Object title}) => 'Are you sure you want to delete "${title}"? This will remove the downloaded file from your device.', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index 51e0c373..714195a1 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsEs implements TranslationsDownloadsEn { @override String get deleteDownload => 'Eliminar descarga'; @override String get retryDownload => 'Reintentar descarga'; @override String get downloadQueued => 'Descarga en cola'; + @override String get serverErrorBitrate => 'Error del servidor — el archivo puede exceder el límite de bitrate de transmisión remota'; @override String episodesQueued({required Object count}) => '${count} episodios en cola para descargar'; @override String get downloadDeleted => 'Descarga eliminada'; @override String deleteConfirm({required Object title}) => '¿Estás seguro de que quieres eliminar "${title}"? Esto borrará el archivo descargado de tu dispositivo.'; @@ -2038,6 +2039,7 @@ extension on TranslationsEs { 'downloads.deleteDownload' => 'Eliminar descarga', 'downloads.retryDownload' => 'Reintentar descarga', 'downloads.downloadQueued' => 'Descarga en cola', + 'downloads.serverErrorBitrate' => 'Error del servidor — el archivo puede exceder el límite de bitrate de transmisión remota', 'downloads.episodesQueued' => ({required Object count}) => '${count} episodios en cola para descargar', 'downloads.downloadDeleted' => 'Descarga eliminada', 'downloads.deleteConfirm' => ({required Object title}) => '¿Estás seguro de que quieres eliminar "${title}"? Esto borrará el archivo descargado de tu dispositivo.', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index 42f83e50..40ceb6ba 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsFr implements TranslationsDownloadsEn { @override String get deleteDownload => 'Supprimer le téléchargement'; @override String get retryDownload => 'Réessayer le téléchargement'; @override String get downloadQueued => 'Téléchargement en attente'; + @override String get serverErrorBitrate => 'Erreur serveur — le fichier dépasse peut-être la limite de débit du streaming à distance'; @override String episodesQueued({required Object count}) => '${count} épisodes en attente de téléchargement'; @override String get downloadDeleted => 'Télécharger supprimé'; @override String deleteConfirm({required Object title}) => 'Êtes-vous sûr de vouloir supprimer "${title}" ? Cela supprimera le fichier téléchargé de votre appareil.'; @@ -2038,6 +2039,7 @@ extension on TranslationsFr { 'downloads.deleteDownload' => 'Supprimer le téléchargement', 'downloads.retryDownload' => 'Réessayer le téléchargement', 'downloads.downloadQueued' => 'Téléchargement en attente', + 'downloads.serverErrorBitrate' => 'Erreur serveur — le fichier dépasse peut-être la limite de débit du streaming à distance', 'downloads.episodesQueued' => ({required Object count}) => '${count} épisodes en attente de téléchargement', 'downloads.downloadDeleted' => 'Télécharger supprimé', 'downloads.deleteConfirm' => ({required Object title}) => 'Êtes-vous sûr de vouloir supprimer "${title}" ? Cela supprimera le fichier téléchargé de votre appareil.', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index 2af9eec6..5ba6058e 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -871,6 +871,7 @@ class _TranslationsDownloadsIt implements TranslationsDownloadsEn { @override String get deleteDownload => 'Elimina download'; @override String get retryDownload => 'Riprova download'; @override String get downloadQueued => 'Download in coda'; + @override String get serverErrorBitrate => 'Errore del server — il file potrebbe superare il limite di bitrate dello streaming remoto'; @override String episodesQueued({required Object count}) => '${count} episodi in coda per il download'; @override String get downloadDeleted => 'Download eliminato'; @override String deleteConfirm({required Object title}) => 'Sei sicuro di voler eliminare "${title}"? Il file scaricato verrà rimosso dal tuo dispositivo.'; @@ -1933,6 +1934,7 @@ extension on TranslationsIt { 'downloads.deleteDownload' => 'Elimina download', 'downloads.retryDownload' => 'Riprova download', 'downloads.downloadQueued' => 'Download in coda', + 'downloads.serverErrorBitrate' => 'Errore del server — il file potrebbe superare il limite di bitrate dello streaming remoto', 'downloads.episodesQueued' => ({required Object count}) => '${count} episodi in coda per il download', 'downloads.downloadDeleted' => 'Download eliminato', 'downloads.deleteConfirm' => ({required Object title}) => 'Sei sicuro di voler eliminare "${title}"? Il file scaricato verrà rimosso dal tuo dispositivo.', diff --git a/lib/i18n/strings_ja.g.dart b/lib/i18n/strings_ja.g.dart index f5781aab..41e35870 100644 --- a/lib/i18n/strings_ja.g.dart +++ b/lib/i18n/strings_ja.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsJa implements TranslationsDownloadsEn { @override String get deleteDownload => 'ダウンロードを削除'; @override String get retryDownload => 'ダウンロードを再試行'; @override String get downloadQueued => 'ダウンロードをキューに追加しました'; + @override String get serverErrorBitrate => 'サーバーエラー — ファイルがリモートストリーミングのビットレート制限を超えている可能性があります'; @override String episodesQueued({required Object count}) => '${count}エピソードをダウンロードキューに追加しました'; @override String get downloadDeleted => 'ダウンロードを削除しました'; @override String deleteConfirm({required Object title}) => '"${title}"を削除してもよろしいですか?ダウンロードしたファイルがデバイスから削除されます。'; @@ -2038,6 +2039,7 @@ extension on TranslationsJa { 'downloads.deleteDownload' => 'ダウンロードを削除', 'downloads.retryDownload' => 'ダウンロードを再試行', 'downloads.downloadQueued' => 'ダウンロードをキューに追加しました', + 'downloads.serverErrorBitrate' => 'サーバーエラー — ファイルがリモートストリーミングのビットレート制限を超えている可能性があります', 'downloads.episodesQueued' => ({required Object count}) => '${count}エピソードをダウンロードキューに追加しました', 'downloads.downloadDeleted' => 'ダウンロードを削除しました', 'downloads.deleteConfirm' => ({required Object title}) => '"${title}"を削除してもよろしいですか?ダウンロードしたファイルがデバイスから削除されます。', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index c89f4abc..e9d93065 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsKo implements TranslationsDownloadsEn { @override String get deleteDownload => '다운로드 삭제'; @override String get retryDownload => '다운로드 재시도'; @override String get downloadQueued => '다운로드 대기 중'; + @override String get serverErrorBitrate => '서버 오류 — 파일이 원격 스트리밍 비트레이트 제한을 초과할 수 있습니다'; @override String episodesQueued({required Object count}) => '${count} 에피소드가 다운로드 대기열에 추가 되었습니다'; @override String get downloadDeleted => '다운로드 삭제됨'; @override String deleteConfirm({required Object title}) => '"${title}"를 삭제 하시겠습니까? 다운로드한 파일이 기기에서 삭제됩니다.'; @@ -2038,6 +2039,7 @@ extension on TranslationsKo { 'downloads.deleteDownload' => '다운로드 삭제', 'downloads.retryDownload' => '다운로드 재시도', 'downloads.downloadQueued' => '다운로드 대기 중', + 'downloads.serverErrorBitrate' => '서버 오류 — 파일이 원격 스트리밍 비트레이트 제한을 초과할 수 있습니다', 'downloads.episodesQueued' => ({required Object count}) => '${count} 에피소드가 다운로드 대기열에 추가 되었습니다', 'downloads.downloadDeleted' => '다운로드 삭제됨', 'downloads.deleteConfirm' => ({required Object title}) => '"${title}"를 삭제 하시겠습니까? 다운로드한 파일이 기기에서 삭제됩니다.', diff --git a/lib/i18n/strings_nb.g.dart b/lib/i18n/strings_nb.g.dart index ce6d494f..e94b5979 100644 --- a/lib/i18n/strings_nb.g.dart +++ b/lib/i18n/strings_nb.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsNb implements TranslationsDownloadsEn { @override String get deleteDownload => 'Slett nedlasting'; @override String get retryDownload => 'Prøv nedlasting på nytt'; @override String get downloadQueued => 'Nedlasting i kø'; + @override String get serverErrorBitrate => 'Serverfeil — filen overskrider muligens grensen for fjernstrømming-bitrate'; @override String episodesQueued({required Object count}) => '${count} episoder i nedlastingskø'; @override String get downloadDeleted => 'Nedlasting slettet'; @override String deleteConfirm({required Object title}) => 'Er du sikker på at du vil slette "${title}"? Dette vil fjerne den nedlastede filen fra enheten din.'; @@ -2038,6 +2039,7 @@ extension on TranslationsNb { 'downloads.deleteDownload' => 'Slett nedlasting', 'downloads.retryDownload' => 'Prøv nedlasting på nytt', 'downloads.downloadQueued' => 'Nedlasting i kø', + 'downloads.serverErrorBitrate' => 'Serverfeil — filen overskrider muligens grensen for fjernstrømming-bitrate', 'downloads.episodesQueued' => ({required Object count}) => '${count} episoder i nedlastingskø', 'downloads.downloadDeleted' => 'Nedlasting slettet', 'downloads.deleteConfirm' => ({required Object title}) => 'Er du sikker på at du vil slette "${title}"? Dette vil fjerne den nedlastede filen fra enheten din.', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index 4e250089..1e0ccb76 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -871,6 +871,7 @@ class _TranslationsDownloadsNl implements TranslationsDownloadsEn { @override String get deleteDownload => 'Download verwijderen'; @override String get retryDownload => 'Download opnieuw proberen'; @override String get downloadQueued => 'Download in wachtrij'; + @override String get serverErrorBitrate => 'Serverfout — het bestand overschrijdt mogelijk de bitrate-limiet voor remote streaming'; @override String episodesQueued({required Object count}) => '${count} afleveringen in wachtrij voor download'; @override String get downloadDeleted => 'Download verwijderd'; @override String deleteConfirm({required Object title}) => 'Weet je zeker dat je "${title}" wilt verwijderen? Het gedownloade bestand wordt van je apparaat verwijderd.'; @@ -1933,6 +1934,7 @@ extension on TranslationsNl { 'downloads.deleteDownload' => 'Download verwijderen', 'downloads.retryDownload' => 'Download opnieuw proberen', 'downloads.downloadQueued' => 'Download in wachtrij', + 'downloads.serverErrorBitrate' => 'Serverfout — het bestand overschrijdt mogelijk de bitrate-limiet voor remote streaming', 'downloads.episodesQueued' => ({required Object count}) => '${count} afleveringen in wachtrij voor download', 'downloads.downloadDeleted' => 'Download verwijderd', 'downloads.deleteConfirm' => ({required Object title}) => 'Weet je zeker dat je "${title}" wilt verwijderen? Het gedownloade bestand wordt van je apparaat verwijderd.', diff --git a/lib/i18n/strings_pl.g.dart b/lib/i18n/strings_pl.g.dart index bba22cc2..1a96ab63 100644 --- a/lib/i18n/strings_pl.g.dart +++ b/lib/i18n/strings_pl.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsPl implements TranslationsDownloadsEn { @override String get deleteDownload => 'Usuń pobranie'; @override String get retryDownload => 'Ponów pobieranie'; @override String get downloadQueued => 'Pobranie w kolejce'; + @override String get serverErrorBitrate => 'Błąd serwera — plik może przekraczać limit bitrate zdalnego streamingu'; @override String episodesQueued({required Object count}) => '${count} odcinków w kolejce pobierania'; @override String get downloadDeleted => 'Pobranie usunięte'; @override String deleteConfirm({required Object title}) => 'Czy na pewno chcesz usunąć "${title}"? Spowoduje to usunięcie pobranego pliku z urządzenia.'; @@ -2038,6 +2039,7 @@ extension on TranslationsPl { 'downloads.deleteDownload' => 'Usuń pobranie', 'downloads.retryDownload' => 'Ponów pobieranie', 'downloads.downloadQueued' => 'Pobranie w kolejce', + 'downloads.serverErrorBitrate' => 'Błąd serwera — plik może przekraczać limit bitrate zdalnego streamingu', 'downloads.episodesQueued' => ({required Object count}) => '${count} odcinków w kolejce pobierania', 'downloads.downloadDeleted' => 'Pobranie usunięte', 'downloads.deleteConfirm' => ({required Object title}) => 'Czy na pewno chcesz usunąć "${title}"? Spowoduje to usunięcie pobranego pliku z urządzenia.', diff --git a/lib/i18n/strings_pt.g.dart b/lib/i18n/strings_pt.g.dart index 574b7b60..7da7883d 100644 --- a/lib/i18n/strings_pt.g.dart +++ b/lib/i18n/strings_pt.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsPt implements TranslationsDownloadsEn { @override String get deleteDownload => 'Excluir download'; @override String get retryDownload => 'Tentar download novamente'; @override String get downloadQueued => 'Download na fila'; + @override String get serverErrorBitrate => 'Erro do servidor — o arquivo pode exceder o limite de bitrate de streaming remoto'; @override String episodesQueued({required Object count}) => '${count} episódios na fila de download'; @override String get downloadDeleted => 'Download excluído'; @override String deleteConfirm({required Object title}) => 'Tem certeza que deseja excluir "${title}"? Isso removerá o arquivo baixado do seu dispositivo.'; @@ -2038,6 +2039,7 @@ extension on TranslationsPt { 'downloads.deleteDownload' => 'Excluir download', 'downloads.retryDownload' => 'Tentar download novamente', 'downloads.downloadQueued' => 'Download na fila', + 'downloads.serverErrorBitrate' => 'Erro do servidor — o arquivo pode exceder o limite de bitrate de streaming remoto', 'downloads.episodesQueued' => ({required Object count}) => '${count} episódios na fila de download', 'downloads.downloadDeleted' => 'Download excluído', 'downloads.deleteConfirm' => ({required Object title}) => 'Tem certeza que deseja excluir "${title}"? Isso removerá o arquivo baixado do seu dispositivo.', diff --git a/lib/i18n/strings_ru.g.dart b/lib/i18n/strings_ru.g.dart index 837e0273..e8a6905e 100644 --- a/lib/i18n/strings_ru.g.dart +++ b/lib/i18n/strings_ru.g.dart @@ -1003,6 +1003,7 @@ class _TranslationsDownloadsRu implements TranslationsDownloadsEn { @override String get deleteDownload => 'Удалить загрузку'; @override String get retryDownload => 'Повторить загрузку'; @override String get downloadQueued => 'Загрузка поставлена в очередь'; + @override String get serverErrorBitrate => 'Ошибка сервера — файл может превышать лимит битрейта удалённого стриминга'; @override String episodesQueued({required Object count}) => '${count} эпизодов поставлено в очередь загрузки'; @override String get downloadDeleted => 'Загрузка удалена'; @override String deleteConfirm({required Object title}) => 'Вы уверены, что хотите удалить "${title}"? Загруженный файл будет удалён с устройства.'; @@ -2038,6 +2039,7 @@ extension on TranslationsRu { 'downloads.deleteDownload' => 'Удалить загрузку', 'downloads.retryDownload' => 'Повторить загрузку', 'downloads.downloadQueued' => 'Загрузка поставлена в очередь', + 'downloads.serverErrorBitrate' => 'Ошибка сервера — файл может превышать лимит битрейта удалённого стриминга', 'downloads.episodesQueued' => ({required Object count}) => '${count} эпизодов поставлено в очередь загрузки', 'downloads.downloadDeleted' => 'Загрузка удалена', 'downloads.deleteConfirm' => ({required Object title}) => 'Вы уверены, что хотите удалить "${title}"? Загруженный файл будет удалён с устройства.', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 81a62ed8..8831ef43 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -871,6 +871,7 @@ class _TranslationsDownloadsSv implements TranslationsDownloadsEn { @override String get deleteDownload => 'Ta bort nedladdning'; @override String get retryDownload => 'Försök igen'; @override String get downloadQueued => 'Nedladdning köad'; + @override String get serverErrorBitrate => 'Serverfel — filen överskrider möjligen gränsen för fjärrströmning-bitrate'; @override String episodesQueued({required Object count}) => '${count} avsnitt köade för nedladdning'; @override String get downloadDeleted => 'Nedladdning borttagen'; @override String deleteConfirm({required Object title}) => 'Är du säker på att du vill ta bort "${title}"? Den nedladdade filen kommer att tas bort från din enhet.'; @@ -1933,6 +1934,7 @@ extension on TranslationsSv { 'downloads.deleteDownload' => 'Ta bort nedladdning', 'downloads.retryDownload' => 'Försök igen', 'downloads.downloadQueued' => 'Nedladdning köad', + 'downloads.serverErrorBitrate' => 'Serverfel — filen överskrider möjligen gränsen för fjärrströmning-bitrate', 'downloads.episodesQueued' => ({required Object count}) => '${count} avsnitt köade för nedladdning', 'downloads.downloadDeleted' => 'Nedladdning borttagen', 'downloads.deleteConfirm' => ({required Object title}) => 'Är du säker på att du vill ta bort "${title}"? Den nedladdade filen kommer att tas bort från din enhet.', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index 2e308243..71cf4016 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -871,6 +871,7 @@ class _TranslationsDownloadsZh implements TranslationsDownloadsEn { @override String get deleteDownload => '删除下载'; @override String get retryDownload => '重试下载'; @override String get downloadQueued => '下载已排队'; + @override String get serverErrorBitrate => '服务器错误 — 文件可能超出远程流媒体比特率限制'; @override String episodesQueued({required Object count}) => '${count} 集已加入下载队列'; @override String get downloadDeleted => '下载已删除'; @override String deleteConfirm({required Object title}) => '确定要删除 "${title}" 吗?下载的文件将从您的设备中删除。'; @@ -1933,6 +1934,7 @@ extension on TranslationsZh { 'downloads.deleteDownload' => '删除下载', 'downloads.retryDownload' => '重试下载', 'downloads.downloadQueued' => '下载已排队', + 'downloads.serverErrorBitrate' => '服务器错误 — 文件可能超出远程流媒体比特率限制', 'downloads.episodesQueued' => ({required Object count}) => '${count} 集已加入下载队列', 'downloads.downloadDeleted' => '下载已删除', 'downloads.deleteConfirm' => ({required Object title}) => '确定要删除 "${title}" 吗?下载的文件将从您的设备中删除。', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index 4f1053b1..2b44f1cd 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -632,6 +632,7 @@ "deleteDownload": "Ta bort nedladdning", "retryDownload": "Försök igen", "downloadQueued": "Nedladdning köad", + "serverErrorBitrate": "Serverfel — filen överskrider möjligen gränsen för fjärrströmning-bitrate", "episodesQueued": "${count} avsnitt köade för nedladdning", "downloadDeleted": "Nedladdning borttagen", "deleteConfirm": "Är du säker på att du vill ta bort \"${title}\"? Den nedladdade filen kommer att tas bort från din enhet.", diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index 5e8c49c1..c4938e15 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -632,6 +632,7 @@ "deleteDownload": "删除下载", "retryDownload": "重试下载", "downloadQueued": "下载已排队", + "serverErrorBitrate": "服务器错误 — 文件可能超出远程流媒体比特率限制", "episodesQueued": "${count} 集已加入下载队列", "downloadDeleted": "下载已删除", "deleteConfirm": "确定要删除 \"${title}\" 吗?下载的文件将从您的设备中删除。", diff --git a/lib/providers/download_provider.dart b/lib/providers/download_provider.dart index 079fa3d7..e00dc861 100644 --- a/lib/providers/download_provider.dart +++ b/lib/providers/download_provider.dart @@ -106,6 +106,7 @@ class DownloadProvider extends ChangeNotifier { progress: item.progress, downloadedBytes: item.downloadedBytes, totalBytes: item.totalBytes ?? 0, + errorMessage: item.errorMessage, ); // Store Plex thumb path reference (file path computed from hash when needed) diff --git a/lib/services/download_manager_service.dart b/lib/services/download_manager_service.dart index 835827b4..c7307b88 100644 --- a/lib/services/download_manager_service.dart +++ b/lib/services/download_manager_service.dart @@ -15,6 +15,7 @@ import '../models/plex_media_info.dart'; import '../services/plex_client.dart'; import '../services/download_storage_service.dart'; import '../services/plex_api_cache.dart'; +import '../i18n/strings.g.dart'; import '../utils/app_logger.dart'; import '../utils/codec_utils.dart'; import '../utils/global_key_utils.dart'; @@ -742,11 +743,12 @@ class DownloadManagerService { errorMessage.contains('No address associated with hostname') || errorMessage.contains('Network is unreachable') || errorMessage.contains('Connection refused'); + final isServerError = errorMessage.contains('500 Internal Server Error'); final client = _getClient(parseGlobalKey(globalKey)?.serverId); final hadProgress = (existing?.downloadedBytes ?? 0) > 0; - if (!isNetworkError && retryCount < _maxAppRetries && client != null) { + if (!isNetworkError && !isServerError && retryCount < _maxAppRetries && client != null) { // App-level auto-retry: schedule a fresh download after a delay. // Each new task gets 5 native retries with Range-based resume. appLogger.w( @@ -768,7 +770,10 @@ class DownloadManagerService { if (isNetworkError) { appLogger.w('Network error for $globalKey, failing permanently (no auto-retry): $errorMessage'); } - await _onDownloadPermanentlyFailed(globalKey, errorMessage); + final userMessage = isServerError + ? t.downloads.serverErrorBitrate + : errorMessage; + await _onDownloadPermanentlyFailed(globalKey, userMessage); } } diff --git a/lib/widgets/download_tree_view.dart b/lib/widgets/download_tree_view.dart index fe1f3139..315e3ab1 100644 --- a/lib/widgets/download_tree_view.dart +++ b/lib/widgets/download_tree_view.dart @@ -689,6 +689,18 @@ class _DownloadTreeItemState extends State<_DownloadTreeItem> { style: theme.textTheme.bodySmall?.copyWith(color: theme.colorScheme.onSurface.withValues(alpha: 0.5)), ), ], + + // Error message for failed downloads + if (_effectiveStatus == DownloadStatus.failed && + widget.node.downloadProgress?.errorMessage != null) ...[ + const SizedBox(height: 4), + Text( + widget.node.downloadProgress!.errorMessage!, + style: theme.textTheme.bodySmall?.copyWith(color: Colors.red.withValues(alpha: 0.8)), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], ], ), ),