From 32892bd4bd411f68002cbd1a3de013cf0085b81c Mon Sep 17 00:00:00 2001 From: zarzet Date: Thu, 9 Jul 2026 19:52:42 +0700 Subject: [PATCH] chore(i18n): localize folder-access download errors, drop em dashes The two folder-access failure messages are stored on items as fixed English sentinels so code can match on them; translate the known sentinels at display time (error dialog and failed-row message) via new downloadErrorSafPermissionLost / downloadErrorFolderAccessLost keys. Also replace em dashes in recently added comments. --- lib/l10n/app_localizations.dart | 12 ++++++++++++ lib/l10n/app_localizations_ar.dart | 8 ++++++++ lib/l10n/app_localizations_de.dart | 8 ++++++++ lib/l10n/app_localizations_en.dart | 8 ++++++++ lib/l10n/app_localizations_es.dart | 8 ++++++++ lib/l10n/app_localizations_fr.dart | 8 ++++++++ lib/l10n/app_localizations_hi.dart | 8 ++++++++ lib/l10n/app_localizations_id.dart | 8 ++++++++ lib/l10n/app_localizations_ja.dart | 8 ++++++++ lib/l10n/app_localizations_ko.dart | 8 ++++++++ lib/l10n/app_localizations_nl.dart | 8 ++++++++ lib/l10n/app_localizations_pt.dart | 8 ++++++++ lib/l10n/app_localizations_ru.dart | 8 ++++++++ lib/l10n/app_localizations_tr.dart | 8 ++++++++ lib/l10n/app_localizations_uk.dart | 8 ++++++++ lib/l10n/app_localizations_zh.dart | 8 ++++++++ lib/l10n/arb/app_en.arb | 8 ++++++++ lib/screens/queue_tab.dart | 18 +++++++++++++++--- lib/services/platform_bridge.dart | 2 +- 19 files changed, 156 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 1fcf6330..cf6c9e24 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -5353,6 +5353,18 @@ abstract class AppLocalizations { /// **'Re-select folder'** String get downloadFolderReselect; + /// Error shown on downloads that failed because the persisted Android SAF folder grant is no longer valid + /// + /// In en, this message translates to: + /// **'SAF permission invalid or revoked. Please reconfigure download location in Settings.'** + String get downloadErrorSafPermissionLost; + + /// Error shown on downloads that failed because the iOS download folder bookmark could not be opened + /// + /// In en, this message translates to: + /// **'Download folder access lost. Please re-select your download folder in Settings.'** + String get downloadErrorFolderAccessLost; + /// Description shown in filename format editor /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index e796fca3..6ed4a9c2 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -3139,6 +3139,14 @@ class AppLocalizationsAr extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 76b31491..9e8362e0 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -3179,6 +3179,14 @@ class AppLocalizationsDe extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 40304918..48cf7463 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -3139,6 +3139,14 @@ class AppLocalizationsEn extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 091449b8..353bb1aa 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -3139,6 +3139,14 @@ class AppLocalizationsEs extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 6fdd27dd..e6a8ad3b 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -3223,6 +3223,14 @@ class AppLocalizationsFr extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_hi.dart b/lib/l10n/app_localizations_hi.dart index d3b2735f..4200b1f8 100644 --- a/lib/l10n/app_localizations_hi.dart +++ b/lib/l10n/app_localizations_hi.dart @@ -3139,6 +3139,14 @@ class AppLocalizationsHi extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart index d2a96dd1..79039cff 100644 --- a/lib/l10n/app_localizations_id.dart +++ b/lib/l10n/app_localizations_id.dart @@ -3122,6 +3122,14 @@ class AppLocalizationsId extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index a5384fd4..39f1eab2 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -3126,6 +3126,14 @@ class AppLocalizationsJa extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index ae428296..6394315b 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -3124,6 +3124,14 @@ class AppLocalizationsKo extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 8570aeda..038d26f2 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -3139,6 +3139,14 @@ class AppLocalizationsNl extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index aaa10df5..0e2dcdfd 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -3139,6 +3139,14 @@ class AppLocalizationsPt extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 4bba75e0..b421bf75 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -3194,6 +3194,14 @@ class AppLocalizationsRu extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_tr.dart b/lib/l10n/app_localizations_tr.dart index d7897b8f..3614bee6 100644 --- a/lib/l10n/app_localizations_tr.dart +++ b/lib/l10n/app_localizations_tr.dart @@ -3170,6 +3170,14 @@ class AppLocalizationsTr extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index 867c11fb..15b78e16 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -3186,6 +3186,14 @@ class AppLocalizationsUk extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 13ea94c0..7aca1bda 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -3139,6 +3139,14 @@ class AppLocalizationsZh extends AppLocalizations { @override String get downloadFolderReselect => 'Re-select folder'; + @override + String get downloadErrorSafPermissionLost => + 'SAF permission invalid or revoked. Please reconfigure download location in Settings.'; + + @override + String get downloadErrorFolderAccessLost => + 'Download folder access lost. Please re-select your download folder in Settings.'; + @override String downloadFilenameDescription( Object album, diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index a7565f47..6f913b8a 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -4122,6 +4122,14 @@ "@downloadFolderReselect": { "description": "Button that reopens the folder picker to restore download folder access" }, + "downloadErrorSafPermissionLost": "SAF permission invalid or revoked. Please reconfigure download location in Settings.", + "@downloadErrorSafPermissionLost": { + "description": "Error shown on downloads that failed because the persisted Android SAF folder grant is no longer valid" + }, + "downloadErrorFolderAccessLost": "Download folder access lost. Please re-select your download folder in Settings.", + "@downloadErrorFolderAccessLost": { + "description": "Error shown on downloads that failed because the iOS download folder bookmark could not be opened" + }, "downloadFilenameDescription": "Use {artist}, {title}, {album}, {track}, {year}, {date}, {disc} as placeholders.", "@downloadFilenameDescription": { "description": "Description shown in filename format editor" diff --git a/lib/screens/queue_tab.dart b/lib/screens/queue_tab.dart index d8e83d0c..efd6deed 100644 --- a/lib/screens/queue_tab.dart +++ b/lib/screens/queue_tab.dart @@ -3421,7 +3421,7 @@ class _QueueTabState extends ConsumerState { final message = isRateLimit ? context.l10n.queueRateLimitMessage : (item.errorMessage.trim().isNotEmpty - ? item.errorMessage + ? _localizedDownloadError(context, item.errorMessage) : context.l10n.updateDownloadFailed); final action = await showDialog( context: context, @@ -4239,7 +4239,7 @@ class _QueueTabState extends ConsumerState { final expired = addedAt == null || now.difference(addedAt).inSeconds >= 6; if (activeDownloadIds.contains(id)) { - // Re-queued (retry) — the live row takes over from the bridge. + // Re-queued (retry): the live row takes over from the bridge. stale.add(id); } else if (hasActiveDownloads) { // Keep just-completed tracks pinned in the lead zone while the @@ -6603,6 +6603,18 @@ class _QueueTabState extends ConsumerState { ); } + /// Download error messages are stored as fixed English sentinels on the + /// item (so code can match on them); translate the known ones for display. + String _localizedDownloadError(BuildContext context, String raw) { + if (raw == safPermissionLostErrorMessage) { + return context.l10n.downloadErrorSafPermissionLost; + } + if (raw == downloadFolderAccessLostErrorMessage) { + return context.l10n.downloadErrorFolderAccessLost; + } + return raw; + } + Widget _buildDownloadFailureMessage( BuildContext context, DownloadItem item, @@ -6610,7 +6622,7 @@ class _QueueTabState extends ConsumerState { ) { if (item.errorType != DownloadErrorType.rateLimit) { return Text( - item.errorMessage, + _localizedDownloadError(context, item.errorMessage), maxLines: 1, overflow: TextOverflow.ellipsis, style: Theme.of( diff --git a/lib/services/platform_bridge.dart b/lib/services/platform_bridge.dart index c70037c3..9aff0482 100644 --- a/lib/services/platform_bridge.dart +++ b/lib/services/platform_bridge.dart @@ -2068,7 +2068,7 @@ class PlatformBridge { /// Present the native iOS folder picker. The security-scoped bookmark is /// created inside the picker callback while its access grant is still - /// active — creating it later from a bare path loses the grant. + /// active; creating it later from a bare path loses the grant. /// Returns null when the user cancels; throws on picker/bookmark failure. static Future pickIosDirectory() async { final result = await _channel.invokeMethod('pickIosDirectory');