feat(i18n): replace all hardcoded strings with l10n keys across 13 screens

- Added 80+ new keys to app_en.arb covering lyrics, SAF, download settings,
  snackbars, dialogs, home, cache, and store screens
- Replaced hardcoded strings in main_shell, album_screen, playlist_screen,
  library_tracks_folder_screen, home_tab, settings_tab, download_settings_page,
  lyrics_provider_priority_page, track_metadata_screen, extension_detail_page,
  cache_management_page, local_album_screen, downloaded_album_screen, search_screen
- Fixed structural bug in track_metadata_screen (duplicate closing brace)
- Added missing l10n.dart import to search_screen.dart
- Regenerated all app_localizations*.dart files via flutter gen-l10n
This commit is contained in:
zarzet
2026-03-13 15:12:12 +07:00
parent 16669d8b7a
commit 48f614359e
29 changed files with 5831 additions and 161 deletions
+613 -1
View File
@@ -256,7 +256,7 @@ abstract class AppLocalizations {
/// **'Filename Format'**
String get downloadFilenameFormat;
/// Setting for folder structure
/// Title of the folder organization picker bottom sheet
///
/// In en, this message translates to:
/// **'Folder Organization'**
@@ -2236,6 +2236,84 @@ abstract class AppLocalizations {
/// **'Clear filters'**
String get storeClearFilters;
/// Store setup screen - heading when no repo is configured
///
/// In en, this message translates to:
/// **'Add Extension Repository'**
String get storeAddRepoTitle;
/// Store setup screen - explanatory text
///
/// In en, this message translates to:
/// **'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.'**
String get storeAddRepoDescription;
/// Label for the repository URL input field
///
/// In en, this message translates to:
/// **'Repository URL'**
String get storeRepoUrlLabel;
/// Hint/placeholder for the repository URL input field
///
/// In en, this message translates to:
/// **'https://github.com/user/repo'**
String get storeRepoUrlHint;
/// Helper text below the repository URL input field
///
/// In en, this message translates to:
/// **'e.g. https://github.com/user/extensions-repo'**
String get storeRepoUrlHelper;
/// Button to submit a new repository URL
///
/// In en, this message translates to:
/// **'Add Repository'**
String get storeAddRepoButton;
/// Tooltip for the change-repository icon button in the app bar
///
/// In en, this message translates to:
/// **'Change repository'**
String get storeChangeRepoTooltip;
/// Title of the change/remove repository dialog
///
/// In en, this message translates to:
/// **'Extension Repository'**
String get storeRepoDialogTitle;
/// Label shown above the current repository URL in the dialog
///
/// In en, this message translates to:
/// **'Current repository:'**
String get storeRepoDialogCurrent;
/// Label for the new repository URL field inside the dialog
///
/// In en, this message translates to:
/// **'New Repository URL'**
String get storeNewRepoUrlLabel;
/// Error heading when the store cannot be loaded
///
/// In en, this message translates to:
/// **'Failed to load store'**
String get storeLoadError;
/// Message when store has no extensions
///
/// In en, this message translates to:
/// **'No extensions available'**
String get storeEmptyNoExtensions;
/// Message when search/filter returns no results
///
/// In en, this message translates to:
/// **'No extensions found'**
String get storeEmptyNoResults;
/// Default search provider option
///
/// In en, this message translates to:
@@ -4205,6 +4283,540 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Artist folders use Track Artist only'**
String get downloadUseAlbumArtistForFoldersTrackSubtitle;
/// Title for the lyrics provider priority page
///
/// In en, this message translates to:
/// **'Lyrics Providers'**
String get lyricsProvidersTitle;
/// Description on the lyrics provider priority page
///
/// In en, this message translates to:
/// **'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.'**
String get lyricsProvidersDescription;
/// Info tip on lyrics provider priority page
///
/// In en, this message translates to:
/// **'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.'**
String get lyricsProvidersInfoText;
/// Section header for enabled providers
///
/// In en, this message translates to:
/// **'Enabled ({count})'**
String lyricsProvidersEnabledSection(int count);
/// Section header for disabled providers
///
/// In en, this message translates to:
/// **'Disabled ({count})'**
String lyricsProvidersDisabledSection(int count);
/// Snackbar when user tries to disable the last enabled provider
///
/// In en, this message translates to:
/// **'At least one provider must remain enabled'**
String get lyricsProvidersAtLeastOne;
/// Snackbar after saving lyrics provider priority
///
/// In en, this message translates to:
/// **'Lyrics provider priority saved'**
String get lyricsProvidersSaved;
/// Body text of the discard-changes dialog on lyrics provider page
///
/// In en, this message translates to:
/// **'You have unsaved changes that will be lost.'**
String get lyricsProvidersDiscardContent;
/// Description for Spotify Lyrics API provider
///
/// In en, this message translates to:
/// **'Spotify-sourced synced lyrics via community API'**
String get lyricsProviderSpotifyApiDesc;
/// Description for LRCLIB provider
///
/// In en, this message translates to:
/// **'Open-source synced lyrics database'**
String get lyricsProviderLrclibDesc;
/// Description for Netease provider
///
/// In en, this message translates to:
/// **'NetEase Cloud Music (good for Asian songs)'**
String get lyricsProviderNeteaseDesc;
/// Description for Musixmatch provider
///
/// In en, this message translates to:
/// **'Largest lyrics database (multi-language)'**
String get lyricsProviderMusixmatchDesc;
/// Description for Apple Music provider
///
/// In en, this message translates to:
/// **'Word-by-word synced lyrics (via proxy)'**
String get lyricsProviderAppleMusicDesc;
/// Description for QQ Music provider
///
/// In en, this message translates to:
/// **'QQ Music (good for Chinese songs, via proxy)'**
String get lyricsProviderQqMusicDesc;
/// Generic description for extension-based lyrics providers
///
/// In en, this message translates to:
/// **'Extension provider'**
String get lyricsProviderExtensionDesc;
/// Title of SAF migration dialog
///
/// In en, this message translates to:
/// **'Storage Update Required'**
String get safMigrationTitle;
/// First paragraph of SAF migration dialog
///
/// In en, this message translates to:
/// **'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.'**
String get safMigrationMessage1;
/// Second paragraph of SAF migration dialog
///
/// In en, this message translates to:
/// **'Please select your download folder again to switch to the new storage system.'**
String get safMigrationMessage2;
/// Snackbar after successfully migrating to SAF
///
/// In en, this message translates to:
/// **'Download folder updated to SAF mode'**
String get safMigrationSuccess;
/// Settings menu item - donate
///
/// In en, this message translates to:
/// **'Donate'**
String get settingsDonate;
/// Subtitle for donate menu item
///
/// In en, this message translates to:
/// **'Support SpotiFLAC-Mobile development'**
String get settingsDonateSubtitle;
/// Tooltip for the Love All button on album/playlist screens
///
/// In en, this message translates to:
/// **'Love All'**
String get tooltipLoveAll;
/// Tooltip for the Add to Playlist button
///
/// In en, this message translates to:
/// **'Add to Playlist'**
String get tooltipAddToPlaylist;
/// Snackbar after removing multiple tracks from Loved folder
///
/// In en, this message translates to:
/// **'Removed {count} tracks from Loved'**
String snackbarRemovedTracksFromLoved(int count);
/// Snackbar after adding multiple tracks to Loved folder
///
/// In en, this message translates to:
/// **'Added {count} tracks to Loved'**
String snackbarAddedTracksToLoved(int count);
/// Title of the Download All confirmation dialog
///
/// In en, this message translates to:
/// **'Download All'**
String get dialogDownloadAllTitle;
/// Body of the Download All confirmation dialog
///
/// In en, this message translates to:
/// **'Download {count} tracks?'**
String dialogDownloadAllMessage(int count);
/// Confirm button in Download All dialog
///
/// In en, this message translates to:
/// **'Download'**
String get dialogDownload;
/// Checkbox label in import dialog to skip already-downloaded songs
///
/// In en, this message translates to:
/// **'Skip already downloaded songs'**
String get homeSkipAlreadyDownloaded;
/// Context menu item to navigate to the album page
///
/// In en, this message translates to:
/// **'Go to Album'**
String get homeGoToAlbum;
/// Snackbar when album info cannot be loaded
///
/// In en, this message translates to:
/// **'Album info not available'**
String get homeAlbumInfoUnavailable;
/// Snackbar while loading a CUE sheet file
///
/// In en, this message translates to:
/// **'Loading CUE sheet...'**
String get snackbarLoadingCueSheet;
/// Snackbar after successfully saving track metadata
///
/// In en, this message translates to:
/// **'Metadata saved successfully'**
String get snackbarMetadataSaved;
/// Snackbar when lyrics embedding fails
///
/// In en, this message translates to:
/// **'Failed to embed lyrics'**
String get snackbarFailedToEmbedLyrics;
/// Snackbar when writing metadata back to file fails
///
/// In en, this message translates to:
/// **'Failed to write back to storage'**
String get snackbarFailedToWriteStorage;
/// Generic error snackbar with error detail
///
/// In en, this message translates to:
/// **'Error: {error}'**
String snackbarError(String error);
/// Snackbar when an extension button has no action configured
///
/// In en, this message translates to:
/// **'No action defined for this button'**
String get snackbarNoActionDefined;
/// Empty state message when an album has no tracks
///
/// In en, this message translates to:
/// **'No tracks found for this album'**
String get noTracksFoundForAlbum;
/// Subtitle text in Android download location bottom sheet
///
/// In en, this message translates to:
/// **'Choose storage mode for downloaded files.'**
String get downloadLocationSubtitle;
/// Storage mode option - use legacy app folder
///
/// In en, this message translates to:
/// **'App folder (non-SAF)'**
String get storageModeAppFolder;
/// Subtitle for app folder storage mode
///
/// In en, this message translates to:
/// **'Use default Music/SpotiFLAC path'**
String get storageModeAppFolderSubtitle;
/// Storage mode option - use Android SAF picker
///
/// In en, this message translates to:
/// **'SAF folder'**
String get storageModeSaf;
/// Subtitle for SAF storage mode
///
/// In en, this message translates to:
/// **'Pick folder via Android Storage Access Framework'**
String get storageModeSafSubtitle;
/// Description text in filename format bottom sheet
///
/// In en, this message translates to:
/// **'Customize how your files are named.'**
String get downloadFilenameDescription;
/// Label above filename tag chips
///
/// In en, this message translates to:
/// **'Tap to insert tag:'**
String get downloadFilenameInsertTag;
/// Subtitle when separate singles folder is enabled
///
/// In en, this message translates to:
/// **'Albums/ and Singles/ folders'**
String get downloadSeparateSinglesEnabled;
/// Subtitle when separate singles folder is disabled
///
/// In en, this message translates to:
/// **'All files in same structure'**
String get downloadSeparateSinglesDisabled;
/// Setting title for artist folder filter options
///
/// In en, this message translates to:
/// **'Artist Name Filters'**
String get downloadArtistNameFilters;
/// Setting title for SongLink country region
///
/// In en, this message translates to:
/// **'SongLink Region'**
String get downloadSongLinkRegion;
/// Setting title for network compatibility toggle
///
/// In en, this message translates to:
/// **'Network compatibility mode'**
String get downloadNetworkCompatibilityMode;
/// Subtitle when network compatibility mode is enabled
///
/// In en, this message translates to:
/// **'Enabled: try HTTP + accept invalid TLS certificates (unsafe)'**
String get downloadNetworkCompatibilityModeEnabled;
/// Subtitle when network compatibility mode is disabled
///
/// In en, this message translates to:
/// **'Off: strict HTTPS certificate validation (recommended)'**
String get downloadNetworkCompatibilityModeDisabled;
/// Hint shown instead of Ask-quality subtitle when no built-in service selected
///
/// In en, this message translates to:
/// **'Select a built-in service to enable'**
String get downloadSelectServiceToEnable;
/// Quality option label for Tidal lossy 320kbps
///
/// In en, this message translates to:
/// **'Lossy 320kbps'**
String get downloadLossy320;
/// Setting title to pick output format for Tidal lossy downloads
///
/// In en, this message translates to:
/// **'Lossy Format'**
String get downloadLossyFormat;
/// Info hint when non-Tidal/Qobuz service is selected
///
/// In en, this message translates to:
/// **'Select Tidal or Qobuz above to configure quality'**
String get downloadSelectTidalQobuz;
/// Subtitle for Embed Lyrics when Embed Metadata is disabled
///
/// In en, this message translates to:
/// **'Disabled while Embed Metadata is turned off'**
String get downloadEmbedLyricsDisabled;
/// Toggle title for including Netease translated lyrics
///
/// In en, this message translates to:
/// **'Netease: Include Translation'**
String get downloadNeteaseIncludeTranslation;
/// Subtitle when Netease translation is enabled
///
/// In en, this message translates to:
/// **'Append translated lyrics when available'**
String get downloadNeteaseIncludeTranslationEnabled;
/// Subtitle when Netease translation is disabled
///
/// In en, this message translates to:
/// **'Use original lyrics only'**
String get downloadNeteaseIncludeTranslationDisabled;
/// Toggle title for including Netease romanized lyrics
///
/// In en, this message translates to:
/// **'Netease: Include Romanization'**
String get downloadNeteaseIncludeRomanization;
/// Subtitle when Netease romanization is enabled
///
/// In en, this message translates to:
/// **'Append romanized lyrics when available'**
String get downloadNeteaseIncludeRomanizationEnabled;
/// Subtitle when Netease romanization is disabled
///
/// In en, this message translates to:
/// **'Disabled'**
String get downloadNeteaseIncludeRomanizationDisabled;
/// Toggle title for Apple/QQ multi-person word-by-word lyrics
///
/// In en, this message translates to:
/// **'Apple/QQ Multi-Person Word-by-Word'**
String get downloadAppleQqMultiPerson;
/// Subtitle when multi-person word-by-word is enabled
///
/// In en, this message translates to:
/// **'Enable v1/v2 speaker and [bg:] tags'**
String get downloadAppleQqMultiPersonEnabled;
/// Subtitle when multi-person word-by-word is disabled
///
/// In en, this message translates to:
/// **'Simplified word-by-word formatting'**
String get downloadAppleQqMultiPersonDisabled;
/// Setting title for Musixmatch language preference
///
/// In en, this message translates to:
/// **'Musixmatch Language'**
String get downloadMusixmatchLanguage;
/// Option label when Musixmatch uses original language
///
/// In en, this message translates to:
/// **'Auto (original)'**
String get downloadMusixmatchLanguageAuto;
/// Toggle title for filtering contributing artists in Album Artist metadata
///
/// In en, this message translates to:
/// **'Filter contributing artists in Album Artist'**
String get downloadFilterContributing;
/// Subtitle when contributing artist filter is enabled
///
/// In en, this message translates to:
/// **'Album Artist metadata uses primary artist only'**
String get downloadFilterContributingEnabled;
/// Subtitle when contributing artist filter is disabled
///
/// In en, this message translates to:
/// **'Keep full Album Artist metadata value'**
String get downloadFilterContributingDisabled;
/// Subtitle for lyrics providers setting when no providers are enabled
///
/// In en, this message translates to:
/// **'None enabled'**
String get downloadProvidersNoneEnabled;
/// Label for the Musixmatch language code text field
///
/// In en, this message translates to:
/// **'Language code'**
String get downloadMusixmatchLanguageCode;
/// Hint text for the Musixmatch language code field
///
/// In en, this message translates to:
/// **'auto / en / es / ja'**
String get downloadMusixmatchLanguageHint;
/// Description in the Musixmatch language picker
///
/// In en, this message translates to:
/// **'Set preferred language code (example: en, es, ja). Leave empty for auto.'**
String get downloadMusixmatchLanguageDesc;
/// Button to reset Musixmatch language to automatic
///
/// In en, this message translates to:
/// **'Auto'**
String get downloadMusixmatchAuto;
/// Title of the Tidal lossy format picker bottom sheet
///
/// In en, this message translates to:
/// **'Lossy 320kbps Format'**
String get downloadLossy320Format;
/// Description in the Tidal lossy format picker
///
/// In en, this message translates to:
/// **'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.'**
String get downloadLossy320FormatDesc;
/// Tidal lossy format option - MP3 320kbps
///
/// In en, this message translates to:
/// **'MP3 320kbps'**
String get downloadLossyMp3;
/// Subtitle for MP3 320kbps option
///
/// In en, this message translates to:
/// **'Best compatibility, ~10MB per track'**
String get downloadLossyMp3Subtitle;
/// Tidal lossy format option - Opus 256kbps
///
/// In en, this message translates to:
/// **'Opus 256kbps'**
String get downloadLossyOpus256;
/// Subtitle for Opus 256kbps option
///
/// In en, this message translates to:
/// **'Best quality Opus, ~8MB per track'**
String get downloadLossyOpus256Subtitle;
/// Tidal lossy format option - Opus 128kbps
///
/// In en, this message translates to:
/// **'Opus 128kbps'**
String get downloadLossyOpus128;
/// Subtitle for Opus 128kbps option
///
/// In en, this message translates to:
/// **'Smallest size, ~4MB per track'**
String get downloadLossyOpus128Subtitle;
/// Subtitle for 'Any' network mode option
///
/// In en, this message translates to:
/// **'WiFi + Mobile Data'**
String get downloadNetworkAnySubtitle;
/// Subtitle for 'WiFi only' network mode option
///
/// In en, this message translates to:
/// **'Pause downloads on mobile data'**
String get downloadNetworkWifiOnlySubtitle;
/// Description in the SongLink region picker
///
/// In en, this message translates to:
/// **'Used as userCountry for SongLink API lookup.'**
String get downloadSongLinkRegionDesc;
/// Snackbar when the audio format is not supported for the requested operation
///
/// In en, this message translates to:
/// **'Unsupported audio format'**
String get snackbarUnsupportedAudioFormat;
/// Tooltip for refresh button on cache management page
///
/// In en, this message translates to:
/// **'Refresh'**
String get cacheRefresh;
}
class _AppLocalizationsDelegate
+354
View File
@@ -1215,6 +1215,47 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get storeClearFilters => 'Filter entfernen';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Standard (Deezer/Spotify)';
@@ -2436,4 +2477,317 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1195,6 +1195,47 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get storeClearFilters => 'Clear filters';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2408,4 +2449,317 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1195,6 +1195,47 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String get storeClearFilters => 'Clear filters';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2408,6 +2449,319 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
/// The translations for Spanish Castilian, as used in Spain (`es_ES`).
+354
View File
@@ -1197,6 +1197,47 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get storeClearFilters => 'Clear filters';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2410,4 +2451,317 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1195,6 +1195,47 @@ class AppLocalizationsHi extends AppLocalizations {
@override
String get storeClearFilters => 'Clear filters';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2408,4 +2449,317 @@ class AppLocalizationsHi extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1200,6 +1200,47 @@ class AppLocalizationsId extends AppLocalizations {
@override
String get storeClearFilters => 'Hapus filter';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2415,4 +2456,317 @@ class AppLocalizationsId extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1189,6 +1189,47 @@ class AppLocalizationsJa extends AppLocalizations {
@override
String get storeClearFilters => 'フィルターを消去';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'デフォルト (Deezer/Spotify)';
@@ -2395,4 +2436,317 @@ class AppLocalizationsJa extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1175,6 +1175,47 @@ class AppLocalizationsKo extends AppLocalizations {
@override
String get storeClearFilters => 'Clear filters';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2388,4 +2429,317 @@ class AppLocalizationsKo extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1195,6 +1195,47 @@ class AppLocalizationsNl extends AppLocalizations {
@override
String get storeClearFilters => 'Clear filters';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2408,4 +2449,317 @@ class AppLocalizationsNl extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1195,6 +1195,47 @@ class AppLocalizationsPt extends AppLocalizations {
@override
String get storeClearFilters => 'Clear filters';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2408,6 +2449,319 @@ class AppLocalizationsPt extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
/// The translations for Portuguese, as used in Portugal (`pt_PT`).
+354
View File
@@ -1216,6 +1216,47 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get storeClearFilters => 'Очистить фильтры';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'По умолчанию (Deezer/Spotify)';
@@ -2467,4 +2508,317 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Папки исполнителя используют только трек исполнителя';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1206,6 +1206,47 @@ class AppLocalizationsTr extends AppLocalizations {
@override
String get storeClearFilters => 'Filtreleri temizle';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Varsayılan (Deezer/Spotify)';
@@ -2420,4 +2461,317 @@ class AppLocalizationsTr extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
+354
View File
@@ -1195,6 +1195,47 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get storeClearFilters => 'Clear filters';
@override
String get storeAddRepoTitle => 'Add Extension Repository';
@override
String get storeAddRepoDescription =>
'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.';
@override
String get storeRepoUrlLabel => 'Repository URL';
@override
String get storeRepoUrlHint => 'https://github.com/user/repo';
@override
String get storeRepoUrlHelper =>
'e.g. https://github.com/user/extensions-repo';
@override
String get storeAddRepoButton => 'Add Repository';
@override
String get storeChangeRepoTooltip => 'Change repository';
@override
String get storeRepoDialogTitle => 'Extension Repository';
@override
String get storeRepoDialogCurrent => 'Current repository:';
@override
String get storeNewRepoUrlLabel => 'New Repository URL';
@override
String get storeLoadError => 'Failed to load store';
@override
String get storeEmptyNoExtensions => 'No extensions available';
@override
String get storeEmptyNoResults => 'No extensions found';
@override
String get extensionDefaultProvider => 'Default (Deezer/Spotify)';
@@ -2408,6 +2449,319 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get downloadUseAlbumArtistForFoldersTrackSubtitle =>
'Artist folders use Track Artist only';
@override
String get lyricsProvidersTitle => 'Lyrics Providers';
@override
String get lyricsProvidersDescription =>
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.';
@override
String get lyricsProvidersInfoText =>
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.';
@override
String lyricsProvidersEnabledSection(int count) {
return 'Enabled ($count)';
}
@override
String lyricsProvidersDisabledSection(int count) {
return 'Disabled ($count)';
}
@override
String get lyricsProvidersAtLeastOne =>
'At least one provider must remain enabled';
@override
String get lyricsProvidersSaved => 'Lyrics provider priority saved';
@override
String get lyricsProvidersDiscardContent =>
'You have unsaved changes that will be lost.';
@override
String get lyricsProviderSpotifyApiDesc =>
'Spotify-sourced synced lyrics via community API';
@override
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
@override
String get lyricsProviderNeteaseDesc =>
'NetEase Cloud Music (good for Asian songs)';
@override
String get lyricsProviderMusixmatchDesc =>
'Largest lyrics database (multi-language)';
@override
String get lyricsProviderAppleMusicDesc =>
'Word-by-word synced lyrics (via proxy)';
@override
String get lyricsProviderQqMusicDesc =>
'QQ Music (good for Chinese songs, via proxy)';
@override
String get lyricsProviderExtensionDesc => 'Extension provider';
@override
String get safMigrationTitle => 'Storage Update Required';
@override
String get safMigrationMessage1 =>
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.';
@override
String get safMigrationMessage2 =>
'Please select your download folder again to switch to the new storage system.';
@override
String get safMigrationSuccess => 'Download folder updated to SAF mode';
@override
String get settingsDonate => 'Donate';
@override
String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development';
@override
String get tooltipLoveAll => 'Love All';
@override
String get tooltipAddToPlaylist => 'Add to Playlist';
@override
String snackbarRemovedTracksFromLoved(int count) {
return 'Removed $count tracks from Loved';
}
@override
String snackbarAddedTracksToLoved(int count) {
return 'Added $count tracks to Loved';
}
@override
String get dialogDownloadAllTitle => 'Download All';
@override
String dialogDownloadAllMessage(int count) {
return 'Download $count tracks?';
}
@override
String get dialogDownload => 'Download';
@override
String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs';
@override
String get homeGoToAlbum => 'Go to Album';
@override
String get homeAlbumInfoUnavailable => 'Album info not available';
@override
String get snackbarLoadingCueSheet => 'Loading CUE sheet...';
@override
String get snackbarMetadataSaved => 'Metadata saved successfully';
@override
String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics';
@override
String get snackbarFailedToWriteStorage => 'Failed to write back to storage';
@override
String snackbarError(String error) {
return 'Error: $error';
}
@override
String get snackbarNoActionDefined => 'No action defined for this button';
@override
String get noTracksFoundForAlbum => 'No tracks found for this album';
@override
String get downloadLocationSubtitle =>
'Choose storage mode for downloaded files.';
@override
String get storageModeAppFolder => 'App folder (non-SAF)';
@override
String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path';
@override
String get storageModeSaf => 'SAF folder';
@override
String get storageModeSafSubtitle =>
'Pick folder via Android Storage Access Framework';
@override
String get downloadFilenameDescription =>
'Customize how your files are named.';
@override
String get downloadFilenameInsertTag => 'Tap to insert tag:';
@override
String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders';
@override
String get downloadSeparateSinglesDisabled => 'All files in same structure';
@override
String get downloadArtistNameFilters => 'Artist Name Filters';
@override
String get downloadSongLinkRegion => 'SongLink Region';
@override
String get downloadNetworkCompatibilityMode => 'Network compatibility mode';
@override
String get downloadNetworkCompatibilityModeEnabled =>
'Enabled: try HTTP + accept invalid TLS certificates (unsafe)';
@override
String get downloadNetworkCompatibilityModeDisabled =>
'Off: strict HTTPS certificate validation (recommended)';
@override
String get downloadSelectServiceToEnable =>
'Select a built-in service to enable';
@override
String get downloadLossy320 => 'Lossy 320kbps';
@override
String get downloadLossyFormat => 'Lossy Format';
@override
String get downloadSelectTidalQobuz =>
'Select Tidal or Qobuz above to configure quality';
@override
String get downloadEmbedLyricsDisabled =>
'Disabled while Embed Metadata is turned off';
@override
String get downloadNeteaseIncludeTranslation =>
'Netease: Include Translation';
@override
String get downloadNeteaseIncludeTranslationEnabled =>
'Append translated lyrics when available';
@override
String get downloadNeteaseIncludeTranslationDisabled =>
'Use original lyrics only';
@override
String get downloadNeteaseIncludeRomanization =>
'Netease: Include Romanization';
@override
String get downloadNeteaseIncludeRomanizationEnabled =>
'Append romanized lyrics when available';
@override
String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled';
@override
String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word';
@override
String get downloadAppleQqMultiPersonEnabled =>
'Enable v1/v2 speaker and [bg:] tags';
@override
String get downloadAppleQqMultiPersonDisabled =>
'Simplified word-by-word formatting';
@override
String get downloadMusixmatchLanguage => 'Musixmatch Language';
@override
String get downloadMusixmatchLanguageAuto => 'Auto (original)';
@override
String get downloadFilterContributing =>
'Filter contributing artists in Album Artist';
@override
String get downloadFilterContributingEnabled =>
'Album Artist metadata uses primary artist only';
@override
String get downloadFilterContributingDisabled =>
'Keep full Album Artist metadata value';
@override
String get downloadProvidersNoneEnabled => 'None enabled';
@override
String get downloadMusixmatchLanguageCode => 'Language code';
@override
String get downloadMusixmatchLanguageHint => 'auto / en / es / ja';
@override
String get downloadMusixmatchLanguageDesc =>
'Set preferred language code (example: en, es, ja). Leave empty for auto.';
@override
String get downloadMusixmatchAuto => 'Auto';
@override
String get downloadLossy320Format => 'Lossy 320kbps Format';
@override
String get downloadLossy320FormatDesc =>
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.';
@override
String get downloadLossyMp3 => 'MP3 320kbps';
@override
String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track';
@override
String get downloadLossyOpus256 => 'Opus 256kbps';
@override
String get downloadLossyOpus256Subtitle =>
'Best quality Opus, ~8MB per track';
@override
String get downloadLossyOpus128 => 'Opus 128kbps';
@override
String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track';
@override
String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data';
@override
String get downloadNetworkWifiOnlySubtitle =>
'Pause downloads on mobile data';
@override
String get downloadSongLinkRegionDesc =>
'Used as userCountry for SongLink API lookup.';
@override
String get snackbarUnsupportedAudioFormat => 'Unsupported audio format';
@override
String get cacheRefresh => 'Refresh';
}
/// The translations for Chinese, as used in China (`zh_CN`).
+452
View File
@@ -1570,6 +1570,58 @@
"@storeClearFilters": {
"description": "Button to clear all filters"
},
"storeAddRepoTitle": "Add Extension Repository",
"@storeAddRepoTitle": {
"description": "Store setup screen - heading when no repo is configured"
},
"storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.",
"@storeAddRepoDescription": {
"description": "Store setup screen - explanatory text"
},
"storeRepoUrlLabel": "Repository URL",
"@storeRepoUrlLabel": {
"description": "Label for the repository URL input field"
},
"storeRepoUrlHint": "https://github.com/user/repo",
"@storeRepoUrlHint": {
"description": "Hint/placeholder for the repository URL input field"
},
"storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo",
"@storeRepoUrlHelper": {
"description": "Helper text below the repository URL input field"
},
"storeAddRepoButton": "Add Repository",
"@storeAddRepoButton": {
"description": "Button to submit a new repository URL"
},
"storeChangeRepoTooltip": "Change repository",
"@storeChangeRepoTooltip": {
"description": "Tooltip for the change-repository icon button in the app bar"
},
"storeRepoDialogTitle": "Extension Repository",
"@storeRepoDialogTitle": {
"description": "Title of the change/remove repository dialog"
},
"storeRepoDialogCurrent": "Current repository:",
"@storeRepoDialogCurrent": {
"description": "Label shown above the current repository URL in the dialog"
},
"storeNewRepoUrlLabel": "New Repository URL",
"@storeNewRepoUrlLabel": {
"description": "Label for the new repository URL field inside the dialog"
},
"storeLoadError": "Failed to load store",
"@storeLoadError": {
"description": "Error heading when the store cannot be loaded"
},
"storeEmptyNoExtensions": "No extensions available",
"@storeEmptyNoExtensions": {
"description": "Message when store has no extensions"
},
"storeEmptyNoResults": "No extensions found",
"@storeEmptyNoResults": {
"description": "Message when search/filter returns no results"
},
"extensionDefaultProvider": "Default (Deezer/Spotify)",
"@extensionDefaultProvider": {
"description": "Default search provider option"
@@ -3205,5 +3257,405 @@
"downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only",
"@downloadUseAlbumArtistForFoldersTrackSubtitle": {
"description": "Subtitle when Track Artist is used for folder naming"
},
"lyricsProvidersTitle": "Lyrics Providers",
"@lyricsProvidersTitle": {
"description": "Title for the lyrics provider priority page"
},
"lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.",
"@lyricsProvidersDescription": {
"description": "Description on the lyrics provider priority page"
},
"lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.",
"@lyricsProvidersInfoText": {
"description": "Info tip on lyrics provider priority page"
},
"lyricsProvidersEnabledSection": "Enabled ({count})",
"@lyricsProvidersEnabledSection": {
"description": "Section header for enabled providers",
"placeholders": {
"count": {
"type": "int"
}
}
},
"lyricsProvidersDisabledSection": "Disabled ({count})",
"@lyricsProvidersDisabledSection": {
"description": "Section header for disabled providers",
"placeholders": {
"count": {
"type": "int"
}
}
},
"lyricsProvidersAtLeastOne": "At least one provider must remain enabled",
"@lyricsProvidersAtLeastOne": {
"description": "Snackbar when user tries to disable the last enabled provider"
},
"lyricsProvidersSaved": "Lyrics provider priority saved",
"@lyricsProvidersSaved": {
"description": "Snackbar after saving lyrics provider priority"
},
"lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.",
"@lyricsProvidersDiscardContent": {
"description": "Body text of the discard-changes dialog on lyrics provider page"
},
"lyricsProviderSpotifyApiDesc": "Spotify-sourced synced lyrics via community API",
"@lyricsProviderSpotifyApiDesc": {
"description": "Description for Spotify Lyrics API provider"
},
"lyricsProviderLrclibDesc": "Open-source synced lyrics database",
"@lyricsProviderLrclibDesc": {
"description": "Description for LRCLIB provider"
},
"lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)",
"@lyricsProviderNeteaseDesc": {
"description": "Description for Netease provider"
},
"lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)",
"@lyricsProviderMusixmatchDesc": {
"description": "Description for Musixmatch provider"
},
"lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)",
"@lyricsProviderAppleMusicDesc": {
"description": "Description for Apple Music provider"
},
"lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)",
"@lyricsProviderQqMusicDesc": {
"description": "Description for QQ Music provider"
},
"lyricsProviderExtensionDesc": "Extension provider",
"@lyricsProviderExtensionDesc": {
"description": "Generic description for extension-based lyrics providers"
},
"safMigrationTitle": "Storage Update Required",
"@safMigrationTitle": {
"description": "Title of SAF migration dialog"
},
"safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.",
"@safMigrationMessage1": {
"description": "First paragraph of SAF migration dialog"
},
"safMigrationMessage2": "Please select your download folder again to switch to the new storage system.",
"@safMigrationMessage2": {
"description": "Second paragraph of SAF migration dialog"
},
"safMigrationSuccess": "Download folder updated to SAF mode",
"@safMigrationSuccess": {
"description": "Snackbar after successfully migrating to SAF"
},
"settingsDonate": "Donate",
"@settingsDonate": {
"description": "Settings menu item - donate"
},
"settingsDonateSubtitle": "Support SpotiFLAC-Mobile development",
"@settingsDonateSubtitle": {
"description": "Subtitle for donate menu item"
},
"tooltipLoveAll": "Love All",
"@tooltipLoveAll": {
"description": "Tooltip for the Love All button on album/playlist screens"
},
"tooltipAddToPlaylist": "Add to Playlist",
"@tooltipAddToPlaylist": {
"description": "Tooltip for the Add to Playlist button"
},
"snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved",
"@snackbarRemovedTracksFromLoved": {
"description": "Snackbar after removing multiple tracks from Loved folder",
"placeholders": {
"count": {
"type": "int"
}
}
},
"snackbarAddedTracksToLoved": "Added {count} tracks to Loved",
"@snackbarAddedTracksToLoved": {
"description": "Snackbar after adding multiple tracks to Loved folder",
"placeholders": {
"count": {
"type": "int"
}
}
},
"dialogDownloadAllTitle": "Download All",
"@dialogDownloadAllTitle": {
"description": "Title of the Download All confirmation dialog"
},
"dialogDownloadAllMessage": "Download {count} tracks?",
"@dialogDownloadAllMessage": {
"description": "Body of the Download All confirmation dialog",
"placeholders": {
"count": {
"type": "int"
}
}
},
"dialogDownload": "Download",
"@dialogDownload": {
"description": "Confirm button in Download All dialog"
},
"homeSkipAlreadyDownloaded": "Skip already downloaded songs",
"@homeSkipAlreadyDownloaded": {
"description": "Checkbox label in import dialog to skip already-downloaded songs"
},
"homeGoToAlbum": "Go to Album",
"@homeGoToAlbum": {
"description": "Context menu item to navigate to the album page"
},
"homeAlbumInfoUnavailable": "Album info not available",
"@homeAlbumInfoUnavailable": {
"description": "Snackbar when album info cannot be loaded"
},
"snackbarLoadingCueSheet": "Loading CUE sheet...",
"@snackbarLoadingCueSheet": {
"description": "Snackbar while loading a CUE sheet file"
},
"snackbarMetadataSaved": "Metadata saved successfully",
"@snackbarMetadataSaved": {
"description": "Snackbar after successfully saving track metadata"
},
"snackbarFailedToEmbedLyrics": "Failed to embed lyrics",
"@snackbarFailedToEmbedLyrics": {
"description": "Snackbar when lyrics embedding fails"
},
"snackbarFailedToWriteStorage": "Failed to write back to storage",
"@snackbarFailedToWriteStorage": {
"description": "Snackbar when writing metadata back to file fails"
},
"snackbarError": "Error: {error}",
"@snackbarError": {
"description": "Generic error snackbar with error detail",
"placeholders": {
"error": {
"type": "String"
}
}
},
"snackbarNoActionDefined": "No action defined for this button",
"@snackbarNoActionDefined": {
"description": "Snackbar when an extension button has no action configured"
},
"noTracksFoundForAlbum": "No tracks found for this album",
"@noTracksFoundForAlbum": {
"description": "Empty state message when an album has no tracks"
},
"downloadLocationSubtitle": "Choose storage mode for downloaded files.",
"@downloadLocationSubtitle": {
"description": "Subtitle text in Android download location bottom sheet"
},
"storageModeAppFolder": "App folder (non-SAF)",
"@storageModeAppFolder": {
"description": "Storage mode option - use legacy app folder"
},
"storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path",
"@storageModeAppFolderSubtitle": {
"description": "Subtitle for app folder storage mode"
},
"storageModeSaf": "SAF folder",
"@storageModeSaf": {
"description": "Storage mode option - use Android SAF picker"
},
"storageModeSafSubtitle": "Pick folder via Android Storage Access Framework",
"@storageModeSafSubtitle": {
"description": "Subtitle for SAF storage mode"
},
"downloadFilenameDescription": "Customize how your files are named.",
"@downloadFilenameDescription": {
"description": "Description text in filename format bottom sheet"
},
"downloadFilenameInsertTag": "Tap to insert tag:",
"@downloadFilenameInsertTag": {
"description": "Label above filename tag chips"
},
"downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders",
"@downloadSeparateSinglesEnabled": {
"description": "Subtitle when separate singles folder is enabled"
},
"downloadSeparateSinglesDisabled": "All files in same structure",
"@downloadSeparateSinglesDisabled": {
"description": "Subtitle when separate singles folder is disabled"
},
"downloadArtistNameFilters": "Artist Name Filters",
"@downloadArtistNameFilters": {
"description": "Setting title for artist folder filter options"
},
"downloadSongLinkRegion": "SongLink Region",
"@downloadSongLinkRegion": {
"description": "Setting title for SongLink country region"
},
"downloadNetworkCompatibilityMode": "Network compatibility mode",
"@downloadNetworkCompatibilityMode": {
"description": "Setting title for network compatibility toggle"
},
"downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)",
"@downloadNetworkCompatibilityModeEnabled": {
"description": "Subtitle when network compatibility mode is enabled"
},
"downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)",
"@downloadNetworkCompatibilityModeDisabled": {
"description": "Subtitle when network compatibility mode is disabled"
},
"downloadSelectServiceToEnable": "Select a built-in service to enable",
"@downloadSelectServiceToEnable": {
"description": "Hint shown instead of Ask-quality subtitle when no built-in service selected"
},
"downloadLossy320": "Lossy 320kbps",
"@downloadLossy320": {
"description": "Quality option label for Tidal lossy 320kbps"
},
"downloadLossyFormat": "Lossy Format",
"@downloadLossyFormat": {
"description": "Setting title to pick output format for Tidal lossy downloads"
},
"downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality",
"@downloadSelectTidalQobuz": {
"description": "Info hint when non-Tidal/Qobuz service is selected"
},
"downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off",
"@downloadEmbedLyricsDisabled": {
"description": "Subtitle for Embed Lyrics when Embed Metadata is disabled"
},
"downloadNeteaseIncludeTranslation": "Netease: Include Translation",
"@downloadNeteaseIncludeTranslation": {
"description": "Toggle title for including Netease translated lyrics"
},
"downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available",
"@downloadNeteaseIncludeTranslationEnabled": {
"description": "Subtitle when Netease translation is enabled"
},
"downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only",
"@downloadNeteaseIncludeTranslationDisabled": {
"description": "Subtitle when Netease translation is disabled"
},
"downloadNeteaseIncludeRomanization": "Netease: Include Romanization",
"@downloadNeteaseIncludeRomanization": {
"description": "Toggle title for including Netease romanized lyrics"
},
"downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available",
"@downloadNeteaseIncludeRomanizationEnabled": {
"description": "Subtitle when Netease romanization is enabled"
},
"downloadNeteaseIncludeRomanizationDisabled": "Disabled",
"@downloadNeteaseIncludeRomanizationDisabled": {
"description": "Subtitle when Netease romanization is disabled"
},
"downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word",
"@downloadAppleQqMultiPerson": {
"description": "Toggle title for Apple/QQ multi-person word-by-word lyrics"
},
"downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags",
"@downloadAppleQqMultiPersonEnabled": {
"description": "Subtitle when multi-person word-by-word is enabled"
},
"downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting",
"@downloadAppleQqMultiPersonDisabled": {
"description": "Subtitle when multi-person word-by-word is disabled"
},
"downloadMusixmatchLanguage": "Musixmatch Language",
"@downloadMusixmatchLanguage": {
"description": "Setting title for Musixmatch language preference"
},
"downloadMusixmatchLanguageAuto": "Auto (original)",
"@downloadMusixmatchLanguageAuto": {
"description": "Option label when Musixmatch uses original language"
},
"downloadFilterContributing": "Filter contributing artists in Album Artist",
"@downloadFilterContributing": {
"description": "Toggle title for filtering contributing artists in Album Artist metadata"
},
"downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only",
"@downloadFilterContributingEnabled": {
"description": "Subtitle when contributing artist filter is enabled"
},
"downloadFilterContributingDisabled": "Keep full Album Artist metadata value",
"@downloadFilterContributingDisabled": {
"description": "Subtitle when contributing artist filter is disabled"
},
"downloadProvidersNoneEnabled": "None enabled",
"@downloadProvidersNoneEnabled": {
"description": "Subtitle for lyrics providers setting when no providers are enabled"
},
"downloadMusixmatchLanguageCode": "Language code",
"@downloadMusixmatchLanguageCode": {
"description": "Label for the Musixmatch language code text field"
},
"downloadMusixmatchLanguageHint": "auto / en / es / ja",
"@downloadMusixmatchLanguageHint": {
"description": "Hint text for the Musixmatch language code field"
},
"downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.",
"@downloadMusixmatchLanguageDesc": {
"description": "Description in the Musixmatch language picker"
},
"downloadMusixmatchAuto": "Auto",
"@downloadMusixmatchAuto": {
"description": "Button to reset Musixmatch language to automatic"
},
"downloadLossy320Format": "Lossy 320kbps Format",
"@downloadLossy320Format": {
"description": "Title of the Tidal lossy format picker bottom sheet"
},
"downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.",
"@downloadLossy320FormatDesc": {
"description": "Description in the Tidal lossy format picker"
},
"downloadLossyMp3": "MP3 320kbps",
"@downloadLossyMp3": {
"description": "Tidal lossy format option - MP3 320kbps"
},
"downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track",
"@downloadLossyMp3Subtitle": {
"description": "Subtitle for MP3 320kbps option"
},
"downloadLossyOpus256": "Opus 256kbps",
"@downloadLossyOpus256": {
"description": "Tidal lossy format option - Opus 256kbps"
},
"downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track",
"@downloadLossyOpus256Subtitle": {
"description": "Subtitle for Opus 256kbps option"
},
"downloadLossyOpus128": "Opus 128kbps",
"@downloadLossyOpus128": {
"description": "Tidal lossy format option - Opus 128kbps"
},
"downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track",
"@downloadLossyOpus128Subtitle": {
"description": "Subtitle for Opus 128kbps option"
},
"downloadNetworkAnySubtitle": "WiFi + Mobile Data",
"@downloadNetworkAnySubtitle": {
"description": "Subtitle for 'Any' network mode option"
},
"downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data",
"@downloadNetworkWifiOnlySubtitle": {
"description": "Subtitle for 'WiFi only' network mode option"
},
"downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.",
"@downloadSongLinkRegionDesc": {
"description": "Description in the SongLink region picker"
},
"downloadFolderOrganization": "Folder Organization",
"@downloadFolderOrganization": {
"description": "Title of the folder organization picker bottom sheet"
},
"snackbarUnsupportedAudioFormat": "Unsupported audio format",
"@snackbarUnsupportedAudioFormat": {
"description": "Snackbar when the audio format is not supported for the requested operation"
},
"cacheRefresh": "Refresh",
"@cacheRefresh": {
"description": "Tooltip for refresh button on cache management page"
}
}
+12 -4
View File
@@ -619,7 +619,7 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
size: 22,
color: allLoved ? Colors.redAccent : Colors.white,
),
tooltip: allLoved ? 'Remove from Loved' : 'Love All',
tooltip: allLoved ? context.l10n.trackOptionRemoveFromLoved : context.l10n.tooltipLoveAll,
padding: EdgeInsets.zero,
),
);
@@ -642,7 +642,7 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
? null
: () => showAddTracksToPlaylistSheet(context, ref, _tracks!),
icon: const Icon(Icons.add, size: 22, color: Colors.white),
tooltip: 'Add to Playlist',
tooltip: context.l10n.tooltipAddToPlaylist,
padding: EdgeInsets.zero,
),
);
@@ -660,7 +660,11 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
}
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Removed ${tracks.length} tracks from Loved')),
SnackBar(
content: Text(
context.l10n.snackbarRemovedTracksFromLoved(tracks.length),
),
),
);
}
} else {
@@ -673,7 +677,11 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen> {
}
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Added $addedCount tracks to Loved')),
SnackBar(
content: Text(
context.l10n.snackbarAddedTracksToLoved(addedCount),
),
),
);
}
}
+1 -1
View File
@@ -363,7 +363,7 @@ class _DownloadedAlbumScreenState extends ConsumerState<DownloadedAlbumScreen> {
if (tracks.isEmpty) {
return Scaffold(
appBar: AppBar(title: Text(widget.albumName)),
body: Center(child: Text('No tracks found for this album')),
body: Center(child: Text(context.l10n.noTracksFoundForAlbum)),
);
}
+3 -3
View File
@@ -816,7 +816,7 @@ class _HomeTabState extends ConsumerState<HomeTab>
const SizedBox(height: 12),
CheckboxListTile(
contentPadding: EdgeInsets.zero,
title: const Text('Skip already downloaded songs'),
title: Text(l10n.homeSkipAlreadyDownloaded),
value: skipDownloaded,
onChanged: (value) {
setDialogState(() {
@@ -1750,7 +1750,7 @@ class _HomeTabState extends ConsumerState<HomeTab>
),
ListTile(
leading: Icon(Icons.album, color: colorScheme.onSurfaceVariant),
title: const Text('Go to Album'),
title: Text(context.l10n.homeGoToAlbum),
onTap: () {
Navigator.pop(context);
_navigateToTrackAlbum(item);
@@ -1824,7 +1824,7 @@ class _HomeTabState extends ConsumerState<HomeTab>
} else {
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('Album info not available')));
).showSnackBar(SnackBar(content: Text(context.l10n.homeAlbumInfoUnavailable)));
}
}
@@ -850,8 +850,8 @@ class _LibraryTracksFolderScreenState
final colorScheme = Theme.of(dialogContext).colorScheme;
return AlertDialog(
backgroundColor: colorScheme.surfaceContainerHigh,
title: const Text('Download All'),
content: Text('Download ${tracks.length} tracks?'),
title: Text(context.l10n.dialogDownloadAllTitle),
content: Text(context.l10n.dialogDownloadAllMessage(tracks.length)),
actions: [
TextButton(
onPressed: () => Navigator.pop(dialogContext),
@@ -862,7 +862,7 @@ class _LibraryTracksFolderScreenState
Navigator.pop(dialogContext);
_downloadAll(tracks);
},
child: const Text('Download'),
child: Text(context.l10n.dialogDownload),
),
],
);
+1 -1
View File
@@ -247,7 +247,7 @@ class _LocalAlbumScreenState extends ConsumerState<LocalAlbumScreen> {
if (tracks.isEmpty) {
return Scaffold(
appBar: AppBar(title: Text(widget.albumName)),
body: const Center(child: Text('No tracks found for this album')),
body: Center(child: Text(context.l10n.noTracksFoundForAlbum)),
);
}
+9 -14
View File
@@ -181,25 +181,20 @@ class _MainShellState extends ConsumerState<MainShell> {
size: 32,
color: colorScheme.primary,
),
title: const Text('Storage Update Required'),
content: const Column(
title: Text(context.l10n.safMigrationTitle),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. '
'This fixes "permission denied" errors on Android 10+.',
),
SizedBox(height: 12),
Text(
'Please select your download folder again to switch to the new storage system.',
),
Text(context.l10n.safMigrationMessage1),
const SizedBox(height: 12),
Text(context.l10n.safMigrationMessage2),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx),
child: const Text('Later'),
child: Text(context.l10n.updateLater),
),
FilledButton(
onPressed: () async {
@@ -219,15 +214,15 @@ class _MainShellState extends ConsumerState<MainShell> {
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Download folder updated to SAF mode'),
SnackBar(
content: Text(context.l10n.safMigrationSuccess),
),
);
}
}
}
},
child: const Text('Select Folder'),
child: Text(context.l10n.setupSelectFolder),
),
],
),
+15 -7
View File
@@ -482,7 +482,7 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen> {
size: 22,
color: allLoved ? Colors.redAccent : Colors.white,
),
tooltip: allLoved ? 'Remove from Loved' : 'Love All',
tooltip: allLoved ? context.l10n.trackOptionRemoveFromLoved : context.l10n.tooltipLoveAll,
padding: EdgeInsets.zero,
),
);
@@ -505,7 +505,7 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen> {
Widget _buildAddToPlaylistButton(BuildContext context) {
return _buildCircleButton(
icon: Icons.playlist_add,
tooltip: 'Add to Playlist',
tooltip: context.l10n.tooltipAddToPlaylist,
onPressed: _tracks.isEmpty
? null
: () => showAddTracksToPlaylistSheet(context, ref, _tracks),
@@ -520,8 +520,8 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen> {
final colorScheme = Theme.of(dialogContext).colorScheme;
return AlertDialog(
backgroundColor: colorScheme.surfaceContainerHigh,
title: const Text('Download All'),
content: Text('Download ${_tracks.length} tracks?'),
title: Text(context.l10n.dialogDownloadAllTitle),
content: Text(context.l10n.dialogDownloadAllMessage(_tracks.length)),
actions: [
TextButton(
onPressed: () => Navigator.pop(dialogContext),
@@ -532,7 +532,7 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen> {
Navigator.pop(dialogContext);
_downloadAll(context);
},
child: const Text('Download'),
child: Text(context.l10n.dialogDownload),
),
],
);
@@ -552,7 +552,11 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen> {
}
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Removed ${tracks.length} tracks from Loved')),
SnackBar(
content: Text(
context.l10n.snackbarRemovedTracksFromLoved(tracks.length),
),
),
);
}
} else {
@@ -565,7 +569,11 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen> {
}
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Added $addedCount tracks to Loved')),
SnackBar(
content: Text(
context.l10n.snackbarAddedTracksToLoved(addedCount),
),
),
);
}
}
+2 -1
View File
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/services/cover_cache_manager.dart';
import 'package:spotiflac_android/models/track.dart';
import 'package:spotiflac_android/providers/track_provider.dart';
@@ -52,7 +53,7 @@ class _SearchScreenState extends ConsumerState<SearchScreen> {
.addToQueue(track, settings.defaultService);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Added "${track.name}" to queue')));
).showSnackBar(SnackBar(content: Text(context.l10n.snackbarAddedToQueue(track.name))));
}
@override
@@ -56,7 +56,7 @@ class _CacheManagementPageState extends ConsumerState<CacheManagementPage> {
setState(() => _isLoading = false);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Error: $e')));
).showSnackBar(SnackBar(content: Text(context.l10n.snackbarError(e.toString()))));
}
}
@@ -282,7 +282,7 @@ class _CacheManagementPageState extends ConsumerState<CacheManagementPage> {
if (!mounted) return;
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Error: $e')));
).showSnackBar(SnackBar(content: Text(context.l10n.snackbarError(e.toString()))));
} finally {
if (mounted) {
setState(() => _busyAction = null);
@@ -394,7 +394,7 @@ class _CacheManagementPageState extends ConsumerState<CacheManagementPage> {
),
actions: [
IconButton(
tooltip: 'Refresh',
tooltip: context.l10n.cacheRefresh,
onPressed: _isBusy ? null : _refreshOverview,
icon: const Icon(Icons.refresh),
),
@@ -376,7 +376,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
title: context.l10n.downloadAskBeforeDownload,
subtitle: isBuiltInService
? context.l10n.downloadAskQualitySubtitle
: 'Select a built-in service to enable',
: context.l10n.downloadSelectServiceToEnable,
value: settings.askQualityBeforeDownload,
enabled: isBuiltInService,
onChanged: (value) => ref
@@ -413,7 +413,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
// Lossy 320kbps option (Tidal only) - downloads M4A, converts to MP3/Opus
if (isTidalService)
_QualityOption(
title: 'Lossy 320kbps',
title: context.l10n.downloadLossy320,
subtitle: _getTidalHighFormatLabel(
settings.tidalHighFormat,
),
@@ -426,7 +426,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
if (isTidalService && settings.audioQuality == 'HIGH')
SettingsItem(
icon: Icons.tune,
title: 'Lossy Format',
title: context.l10n.downloadLossyFormat,
subtitle: _getTidalHighFormatLabel(
settings.tidalHighFormat,
),
@@ -451,7 +451,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
const SizedBox(width: 8),
Expanded(
child: Text(
'Select Tidal or Qobuz above to configure quality',
context.l10n.downloadSelectTidalQobuz,
style: Theme.of(context).textTheme.bodySmall
?.copyWith(
color: colorScheme.onSurfaceVariant,
@@ -504,7 +504,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
title: context.l10n.optionsEmbedLyrics,
subtitle: settings.embedMetadata
? context.l10n.optionsEmbedLyricsSubtitle
: 'Disabled while Embed Metadata is turned off',
: context.l10n.downloadEmbedLyricsDisabled,
value: settings.embedLyrics,
enabled: settings.embedMetadata,
onChanged: (value) => ref
@@ -528,7 +528,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
SettingsItem(
icon: Icons.source_outlined,
title: 'Lyrics Providers',
title: context.l10n.lyricsProvidersTitle,
subtitle: _getLyricsProvidersSubtitle(
settings.lyricsProviders,
),
@@ -541,10 +541,10 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
SettingsSwitchItem(
icon: Icons.translate_outlined,
title: 'Netease: Include Translation',
title: context.l10n.downloadNeteaseIncludeTranslation,
subtitle: settings.lyricsIncludeTranslationNetease
? 'Append translated lyrics when available'
: 'Use original lyrics only',
? context.l10n.downloadNeteaseIncludeTranslationEnabled
: context.l10n.downloadNeteaseIncludeTranslationDisabled,
value: settings.lyricsIncludeTranslationNetease,
onChanged: (value) => ref
.read(settingsProvider.notifier)
@@ -552,10 +552,10 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
SettingsSwitchItem(
icon: Icons.text_fields_outlined,
title: 'Netease: Include Romanization',
title: context.l10n.downloadNeteaseIncludeRomanization,
subtitle: settings.lyricsIncludeRomanizationNetease
? 'Append romanized lyrics when available'
: 'Disabled',
? context.l10n.downloadNeteaseIncludeRomanizationEnabled
: context.l10n.downloadNeteaseIncludeRomanizationDisabled,
value: settings.lyricsIncludeRomanizationNetease,
onChanged: (value) => ref
.read(settingsProvider.notifier)
@@ -563,10 +563,10 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
SettingsSwitchItem(
icon: Icons.record_voice_over_outlined,
title: 'Apple/QQ Multi-Person Word-by-Word',
title: context.l10n.downloadAppleQqMultiPerson,
subtitle: settings.lyricsMultiPersonWordByWord
? 'Enable v1/v2 speaker and [bg:] tags'
: 'Simplified word-by-word formatting',
? context.l10n.downloadAppleQqMultiPersonEnabled
: context.l10n.downloadAppleQqMultiPersonDisabled,
value: settings.lyricsMultiPersonWordByWord,
onChanged: (value) => ref
.read(settingsProvider.notifier)
@@ -574,9 +574,9 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
SettingsItem(
icon: Icons.language_outlined,
title: 'Musixmatch Language',
title: context.l10n.downloadMusixmatchLanguage,
subtitle: settings.musixmatchLanguage.isEmpty
? 'Auto (original)'
? context.l10n.downloadMusixmatchLanguageAuto
: settings.musixmatchLanguage.toUpperCase(),
onTap: () => _showMusixmatchLanguagePicker(
context,
@@ -622,8 +622,8 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
icon: Icons.library_music_outlined,
title: context.l10n.downloadSeparateSinglesFolder,
subtitle: settings.separateSingles
? 'Albums/ and Singles/ folders'
: 'All files in same structure',
? context.l10n.downloadSeparateSinglesEnabled
: context.l10n.downloadSeparateSinglesDisabled,
value: settings.separateSingles,
onChanged: (value) => ref
.read(settingsProvider.notifier)
@@ -670,9 +670,9 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
.read(settingsProvider.notifier)
.setUseAlbumArtistForFolders(value),
),
SettingsItem(
SettingsItem(
icon: Icons.filter_alt_outlined,
title: 'Artist Name Filters',
title: context.l10n.downloadArtistNameFilters,
subtitle: _getArtistFolderFilterSubtitle(
context,
usePrimaryArtistOnly: settings.usePrimaryArtistOnly,
@@ -707,28 +707,16 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
if (_artistFolderFiltersExpanded)
SettingsSwitchItem(
icon: Icons.group_remove_outlined,
title: 'Filter contributing artists in Album Artist',
title: context.l10n.downloadFilterContributing,
subtitle: settings.filterContributingArtistsInAlbumArtist
? 'Album Artist metadata uses primary artist only'
: 'Keep full Album Artist metadata value',
? context.l10n.downloadFilterContributingEnabled
: context.l10n.downloadFilterContributingDisabled,
value: settings.filterContributingArtistsInAlbumArtist,
onChanged: (value) => ref
.read(settingsProvider.notifier)
.setFilterContributingArtistsInAlbumArtist(value),
showDivider: false,
),
SettingsSwitchItem(
icon: Icons.person_outline,
title: context.l10n.downloadUsePrimaryArtistOnly,
subtitle: settings.usePrimaryArtistOnly
? context.l10n.downloadUsePrimaryArtistOnlyEnabled
: context.l10n.downloadUsePrimaryArtistOnlyDisabled,
value: settings.usePrimaryArtistOnly,
onChanged: (value) => ref
.read(settingsProvider.notifier)
.setUsePrimaryArtistOnly(value),
showDivider: false,
),
],
),
),
@@ -753,7 +741,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
SettingsItem(
icon: Icons.public,
title: 'SongLink Region',
title: context.l10n.downloadSongLinkRegion,
subtitle: _getSongLinkRegionLabel(settings.songLinkRegion),
onTap: () => _showSongLinkRegionPicker(
context,
@@ -763,10 +751,10 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
SettingsSwitchItem(
icon: Icons.security_outlined,
title: 'Network compatibility mode',
title: context.l10n.downloadNetworkCompatibilityMode,
subtitle: settings.networkCompatibilityMode
? 'Enabled: try HTTP + accept invalid TLS certificates (unsafe)'
: 'Off: strict HTTPS certificate validation (recommended)',
? context.l10n.downloadNetworkCompatibilityModeEnabled
: context.l10n.downloadNetworkCompatibilityModeDisabled,
value: settings.networkCompatibilityMode,
onChanged: (value) {
ref
@@ -1045,7 +1033,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
const SizedBox(height: 8),
Text(
'Customize how your files are named.',
context.l10n.downloadFilenameDescription,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
@@ -1070,7 +1058,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
const SizedBox(height: 24),
Text(
'Tap to insert tag:',
context.l10n.downloadFilenameInsertTag,
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold,
),
@@ -1238,7 +1226,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
Padding(
padding: const EdgeInsets.fromLTRB(24, 24, 24, 8),
child: Text(
'Download Location',
context.l10n.setupDownloadLocationTitle,
style: Theme.of(
ctx,
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
@@ -1247,7 +1235,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
child: Text(
'Choose storage mode for downloaded files.',
context.l10n.downloadLocationSubtitle,
style: Theme.of(ctx).textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
@@ -1255,8 +1243,8 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
ListTile(
leading: Icon(Icons.folder_special, color: colorScheme.primary),
title: const Text('App folder (non-SAF)'),
subtitle: const Text('Use default Music/SpotiFLAC path'),
title: Text(context.l10n.storageModeAppFolder),
subtitle: Text(context.l10n.storageModeAppFolderSubtitle),
trailing: !isSafMode ? const Icon(Icons.check) : null,
onTap: () async {
Navigator.pop(ctx);
@@ -1269,10 +1257,8 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
ListTile(
leading: Icon(Icons.folder_open, color: colorScheme.primary),
title: const Text('SAF folder'),
subtitle: const Text(
'Pick folder via Android Storage Access Framework',
),
title: Text(context.l10n.storageModeSaf),
subtitle: Text(context.l10n.storageModeSafSubtitle),
trailing: isSafMode ? const Icon(Icons.check) : null,
onTap: () async {
Navigator.pop(ctx);
@@ -1546,7 +1532,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
};
String _getLyricsProvidersSubtitle(List<String> providers) {
if (providers.isEmpty) return 'None enabled';
if (providers.isEmpty) return context.l10n.downloadProvidersNoneEnabled;
return providers.map((p) => _providerDisplayNames[p] ?? p).join(' > ');
}
@@ -1645,14 +1631,14 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Musixmatch Language',
context.l10n.downloadMusixmatchLanguage,
style: Theme.of(
context,
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
'Set preferred language code (example: en, es, ja). Leave empty for auto.',
context.l10n.downloadMusixmatchLanguageDesc,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
@@ -1661,9 +1647,9 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
TextField(
controller: controller,
textInputAction: TextInputAction.done,
decoration: const InputDecoration(
labelText: 'Language code',
hintText: 'auto / en / es / ja',
decoration: InputDecoration(
labelText: context.l10n.downloadMusixmatchLanguageCode,
hintText: context.l10n.downloadMusixmatchLanguageHint,
),
),
const SizedBox(height: 16),
@@ -1682,7 +1668,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
.setMusixmatchLanguage('');
Navigator.pop(context);
},
child: const Text('Auto'),
child: Text(context.l10n.downloadMusixmatchAuto),
),
const SizedBox(width: 8),
FilledButton(
@@ -1739,7 +1725,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
Padding(
padding: const EdgeInsets.fromLTRB(24, 24, 24, 8),
child: Text(
'Lossy 320kbps Format',
context.l10n.downloadLossy320Format,
style: Theme.of(
context,
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
@@ -1748,7 +1734,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
child: Text(
'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.',
context.l10n.downloadLossy320FormatDesc,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
@@ -1756,8 +1742,8 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
ListTile(
leading: const Icon(Icons.audiotrack),
title: const Text('MP3 320kbps'),
subtitle: const Text('Best compatibility, ~10MB per track'),
title: Text(context.l10n.downloadLossyMp3),
subtitle: Text(context.l10n.downloadLossyMp3Subtitle),
trailing: current == 'mp3_320'
? Icon(Icons.check, color: colorScheme.primary)
: null,
@@ -1770,8 +1756,8 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
ListTile(
leading: const Icon(Icons.graphic_eq),
title: const Text('Opus 256kbps'),
subtitle: const Text('Best quality Opus, ~8MB per track'),
title: Text(context.l10n.downloadLossyOpus256),
subtitle: Text(context.l10n.downloadLossyOpus256Subtitle),
trailing: current == 'opus_256'
? Icon(Icons.check, color: colorScheme.primary)
: null,
@@ -1784,8 +1770,8 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
),
ListTile(
leading: const Icon(Icons.graphic_eq),
title: const Text('Opus 128kbps'),
subtitle: const Text('Smallest size, ~4MB per track'),
title: Text(context.l10n.downloadLossyOpus128),
subtitle: Text(context.l10n.downloadLossyOpus128Subtitle),
trailing: current == 'opus_128'
? Icon(Icons.check, color: colorScheme.primary)
: null,
@@ -1842,7 +1828,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
ListTile(
leading: const Icon(Icons.signal_cellular_alt),
title: Text(context.l10n.settingsDownloadNetworkAny),
subtitle: const Text('WiFi + Mobile Data'),
subtitle: Text(context.l10n.downloadNetworkAnySubtitle),
trailing: current == 'any'
? Icon(Icons.check, color: colorScheme.primary)
: null,
@@ -1856,7 +1842,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
ListTile(
leading: const Icon(Icons.wifi),
title: Text(context.l10n.settingsDownloadNetworkWifiOnly),
subtitle: const Text('Pause downloads on mobile data'),
subtitle: Text(context.l10n.downloadNetworkWifiOnlySubtitle),
trailing: current == 'wifi_only'
? Icon(Icons.check, color: colorScheme.primary)
: null,
@@ -1897,17 +1883,17 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
children: [
Padding(
padding: const EdgeInsets.fromLTRB(24, 24, 24, 8),
child: Text(
'SongLink Region',
style: Theme.of(
context,
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
),
child: Text(
context.l10n.downloadSongLinkRegion,
style: Theme.of(
context,
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
child: Text(
'Used as userCountry for SongLink API lookup.',
),
Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
child: Text(
context.l10n.downloadSongLinkRegionDesc,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
@@ -1968,12 +1954,12 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
children: [
Padding(
padding: const EdgeInsets.fromLTRB(24, 24, 24, 8),
child: Text(
'Folder Organization',
style: Theme.of(
context,
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
),
child: Text(
context.l10n.downloadFolderOrganization,
style: Theme.of(
context,
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
@@ -801,7 +801,7 @@ class _SettingItemState extends State<_SettingItem> {
Future<void> _invokeAction(BuildContext context) async {
if (widget.setting.action == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No action defined for this button')),
SnackBar(content: Text(context.l10n.snackbarNoActionDefined)),
);
return;
}
@@ -834,7 +834,7 @@ class _SettingItemState extends State<_SettingItem> {
if (context.mounted) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Error: $e')));
).showSnackBar(SnackBar(content: Text(context.l10n.snackbarError(e.toString()))));
}
} finally {
if (mounted) {
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/providers/settings_provider.dart';
import 'package:spotiflac_android/widgets/priority_settings_scaffold.dart';
import 'package:spotiflac_android/widgets/settings_group.dart';
@@ -55,18 +56,18 @@ class _LyricsProviderPriorityPageState
return PrioritySettingsScaffold(
hasChanges: _hasChanges,
title: 'Lyrics Providers',
description:
'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.',
infoText:
'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.',
title: context.l10n.lyricsProvidersTitle,
description: context.l10n.lyricsProvidersDescription,
infoText: context.l10n.lyricsProvidersInfoText,
onSave: _saveChanges,
onConfirmDiscard: _confirmDiscard,
slivers: [
if (_enabledProviders.isNotEmpty)
SliverToBoxAdapter(
child: SettingsSectionHeader(
title: 'Enabled (${_enabledProviders.length})',
title: context.l10n.lyricsProvidersEnabledSection(
_enabledProviders.length,
),
),
),
if (_enabledProviders.isNotEmpty)
@@ -76,7 +77,7 @@ class _LyricsProviderPriorityPageState
itemCount: _enabledProviders.length,
itemBuilder: (context, index) {
final id = _enabledProviders[index];
final info = _getLyricsProviderInfo(id);
final info = _getLyricsProviderInfo(id, context);
return _EnabledProviderItem(
key: ValueKey(id),
providerId: id,
@@ -99,7 +100,9 @@ class _LyricsProviderPriorityPageState
if (disabled.isNotEmpty)
SliverToBoxAdapter(
child: SettingsSectionHeader(
title: 'Disabled (${disabled.length})',
title: context.l10n.lyricsProvidersDisabledSection(
disabled.length,
),
),
),
if (disabled.isNotEmpty)
@@ -108,7 +111,7 @@ class _LyricsProviderPriorityPageState
sliver: SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
final id = disabled[index];
final info = _getLyricsProviderInfo(id);
final info = _getLyricsProviderInfo(id, context);
return _DisabledProviderItem(
key: ValueKey(id),
providerId: id,
@@ -130,8 +133,8 @@ class _LyricsProviderPriorityPageState
void _disableProvider(String id) {
if (_enabledProviders.length <= 1) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('At least one provider must remain enabled'),
SnackBar(
content: Text(context.l10n.lyricsProvidersAtLeastOne),
),
);
return;
@@ -150,7 +153,7 @@ class _LyricsProviderPriorityPageState
});
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Lyrics provider priority saved')),
SnackBar(content: Text(context.l10n.lyricsProvidersSaved)),
);
}
}
@@ -159,16 +162,16 @@ class _LyricsProviderPriorityPageState
final result = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Discard changes?'),
content: const Text('You have unsaved changes that will be lost.'),
title: Text(context.l10n.dialogDiscardChanges),
content: Text(context.l10n.lyricsProvidersDiscardContent),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('Cancel'),
child: Text(context.l10n.dialogCancel),
),
FilledButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('Discard'),
child: Text(context.l10n.dialogDiscard),
),
],
),
@@ -176,48 +179,51 @@ class _LyricsProviderPriorityPageState
return result ?? false;
}
static _LyricsProviderInfo _getLyricsProviderInfo(String id) {
static _LyricsProviderInfo _getLyricsProviderInfo(
String id,
BuildContext context,
) {
switch (id) {
case 'spotify_api':
return _LyricsProviderInfo(
name: 'Spotify Lyrics API',
description: 'Spotify-sourced synced lyrics via community API',
description: context.l10n.lyricsProviderSpotifyApiDesc,
icon: Icons.music_note_outlined,
);
case 'lrclib':
return _LyricsProviderInfo(
name: 'LRCLIB',
description: 'Open-source synced lyrics database',
description: context.l10n.lyricsProviderLrclibDesc,
icon: Icons.subtitles_outlined,
);
case 'netease':
return _LyricsProviderInfo(
name: 'Netease',
description: 'NetEase Cloud Music (good for Asian songs)',
description: context.l10n.lyricsProviderNeteaseDesc,
icon: Icons.cloud_outlined,
);
case 'musixmatch':
return _LyricsProviderInfo(
name: 'Musixmatch',
description: 'Largest lyrics database (multi-language)',
description: context.l10n.lyricsProviderMusixmatchDesc,
icon: Icons.translate,
);
case 'apple_music':
return _LyricsProviderInfo(
name: 'Apple Music',
description: 'Word-by-word synced lyrics (via proxy)',
description: context.l10n.lyricsProviderAppleMusicDesc,
icon: Icons.music_note,
);
case 'qqmusic':
return _LyricsProviderInfo(
name: 'QQ Music',
description: 'QQ Music (good for Chinese songs, via proxy)',
description: context.l10n.lyricsProviderQqMusicDesc,
icon: Icons.queue_music,
);
default:
return _LyricsProviderInfo(
name: id,
description: 'Extension provider',
description: context.l10n.lyricsProviderExtensionDesc,
icon: Icons.extension,
);
}
+2 -2
View File
@@ -107,8 +107,8 @@ class SettingsTab extends ConsumerWidget {
),
SettingsItem(
icon: Icons.favorite_outline,
title: 'Donate',
subtitle: 'Support SpotiFLAC-Mobile development',
title: l10n.settingsDonate,
subtitle: l10n.settingsDonateSubtitle,
onTap: () => _navigateTo(context, const DonatePage()),
showDivider: false,
),
+12 -12
View File
@@ -1731,13 +1731,13 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
);
success = ok;
if (!ok) {
error = 'Failed to write back to storage';
error = context.l10n.snackbarFailedToWriteStorage;
}
} else {
success = true;
}
} else {
error = result['error']?.toString() ?? 'Failed to embed lyrics';
error = result['error']?.toString() ?? context.l10n.snackbarFailedToEmbedLyrics;
}
} else if (isMp3 || isOpus) {
final metadata = _buildFallbackMetadata();
@@ -1783,7 +1783,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
}
if (ffmpegResult == null) {
error = 'Failed to embed lyrics';
error = context.l10n.snackbarFailedToEmbedLyrics;
} else if (_isSafFile) {
final ok = await PlatformBridge.writeTempToSaf(
ffmpegResult,
@@ -1791,13 +1791,13 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
);
success = ok;
if (!ok) {
error = 'Failed to write back to storage';
error = context.l10n.snackbarFailedToWriteStorage;
}
} else {
success = true;
}
} else {
error = 'Unsupported audio format';
error = context.l10n.snackbarUnsupportedAudioFormat;
}
if (mounted) {
@@ -1812,7 +1812,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
} else {
setState(() => _isEmbedding = false);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(error ?? 'Failed to embed lyrics')),
SnackBar(content: Text(error ?? context.l10n.snackbarFailedToEmbedLyrics)),
);
}
}
@@ -1821,7 +1821,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
setState(() => _isEmbedding = false);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Error: $e')));
).showSnackBar(SnackBar(content: Text(context.l10n.snackbarError(e.toString()))));
}
} finally {
if (coverPath != null) {
@@ -2271,7 +2271,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
SnackBar(
content: Text(
context.l10n.trackSaveFailed(
'Failed to write back to storage',
context.l10n.snackbarFailedToWriteStorage,
),
),
),
@@ -2873,7 +2873,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
// Show loading indicator
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Loading CUE sheet...')),
SnackBar(content: Text(context.l10n.snackbarLoadingCueSheet)),
);
try {
@@ -3644,7 +3644,7 @@ class _TrackMetadataScreenState extends ConsumerState<TrackMetadataScreen> {
if (saved == true && mounted) {
ScaffoldMessenger.of(this.context).showSnackBar(
const SnackBar(content: Text('Metadata saved successfully')),
SnackBar(content: Text(this.context.l10n.snackbarMetadataSaved)),
);
// Re-read metadata from file to refresh the display
try {
@@ -4066,7 +4066,7 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> {
if (!mounted) return;
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Failed to pick cover: $e')));
).showSnackBar(SnackBar(content: Text(context.l10n.snackbarError(e.toString()))));
}
}
@@ -4290,7 +4290,7 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> {
if (mounted) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Failed to save metadata: $e')));
).showSnackBar(SnackBar(content: Text(context.l10n.snackbarError(e.toString()))));
}
} finally {
if (mounted) setState(() => _saving = false);