diff --git a/.gitignore b/.gitignore index 72bdf220..a4b6e829 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,11 @@ AGENTS.md # Temp/misc nul + +# Log files +*.log +hs_err_*.log +flutter_*.log + +# Development tools +tool/ diff --git a/crowdin.yml b/crowdin.yml index b7a02fe3..0c089bad 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,3 +1,3 @@ files: - source: /lib/l10n/arb/app_en.arb - translation: /lib/l10n/arb/app_%two_letters_code%.arb + translation: /lib/l10n/arb/app_%locale_with_underscore%.arb diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 2fafa4b0..c3781e32 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -116,6 +116,7 @@ abstract class AppLocalizations { Locale('pt'), Locale('ru'), Locale('zh'), + Locale('zh', 'CN'), Locale('zh', 'TW'), ]; @@ -2621,42 +2622,24 @@ abstract class AppLocalizations { /// **'Layout'** String get sectionLayout; - /// Settings section header for language selection + /// Settings section header for language /// /// In en, this message translates to: /// **'Language'** String get sectionLanguage; - /// Setting title for language selection + /// Language setting title /// /// In en, this message translates to: /// **'App Language'** String get appearanceLanguage; - /// Subtitle for language setting + /// Language setting subtitle /// /// In en, this message translates to: /// **'Choose your preferred language'** String get appearanceLanguageSubtitle; - /// Use device system language - /// - /// In en, this message translates to: - /// **'System Default'** - String get languageSystem; - - /// English language option - /// - /// In en, this message translates to: - /// **'English'** - String get languageEnglish; - - /// Indonesian language option - /// - /// In en, this message translates to: - /// **'Bahasa Indonesia'** - String get languageIndonesian; - /// Appearance settings description /// /// In en, this message translates to: @@ -3683,6 +3666,8 @@ AppLocalizations lookupAppLocalizations(Locale locale) { case 'zh': { switch (locale.countryCode) { + case 'CN': + return AppLocalizationsZhCn(); case 'TW': return AppLocalizationsZhTw(); } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 06e66f17..cb3b2481 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsDe extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 48220eb7..3076e225 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsEn extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 2ca999d0..a5adb890 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsEs extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 3139492a..44995932 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsFr extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_hi.dart b/lib/l10n/app_localizations_hi.dart index affa7609..7ada4ec3 100644 --- a/lib/l10n/app_localizations_hi.dart +++ b/lib/l10n/app_localizations_hi.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsHi extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart index 5f13f1ab..85249455 100644 --- a/lib/l10n/app_localizations_id.dart +++ b/lib/l10n/app_localizations_id.dart @@ -1455,15 +1455,6 @@ class AppLocalizationsId extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Pilih bahasa yang kamu inginkan'; - @override - String get languageSystem => 'Bawaan Sistem'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Tema, warna, tampilan'; diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index aaa2cc21..dc159b26 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsJa extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index 9e8d4d22..372a765f 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsKo extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 6dea9681..f3fb6361 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsNl extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 8b423485..8e985b89 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsPt extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index dee18edc..0e96f465 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsRu extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index f8d7d4a4..a5ab5a63 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -1445,15 +1445,6 @@ class AppLocalizationsZh extends AppLocalizations { @override String get appearanceLanguageSubtitle => 'Choose your preferred language'; - @override - String get languageSystem => 'System Default'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageIndonesian => 'Bahasa Indonesia'; - @override String get settingsAppearanceSubtitle => 'Theme, colors, display'; @@ -2008,6 +1999,1971 @@ class AppLocalizationsZh extends AppLocalizations { } } +/// The translations for Chinese, as used in China (`zh_CN`). +class AppLocalizationsZhCn extends AppLocalizationsZh { + AppLocalizationsZhCn() : super('zh_CN'); + + @override + String get appName => 'SpotiFLAC'; + + @override + String get appDescription => + 'Download Spotify tracks in lossless quality from Tidal, Qobuz, and Amazon Music.'; + + @override + String get navHome => 'Home'; + + @override + String get navHistory => 'History'; + + @override + String get navSettings => 'Settings'; + + @override + String get navStore => 'Store'; + + @override + String get homeTitle => 'Home'; + + @override + String get homeSearchHint => 'Paste Spotify URL or search...'; + + @override + String homeSearchHintExtension(String extensionName) { + return 'Search with $extensionName...'; + } + + @override + String get homeSubtitle => 'Paste a Spotify link or search by name'; + + @override + String get homeSupports => 'Supports: Track, Album, Playlist, Artist URLs'; + + @override + String get homeRecent => 'Recent'; + + @override + String get historyTitle => 'History'; + + @override + String historyDownloading(int count) { + return 'Downloading ($count)'; + } + + @override + String get historyDownloaded => 'Downloaded'; + + @override + String get historyFilterAll => 'All'; + + @override + String get historyFilterAlbums => 'Albums'; + + @override + String get historyFilterSingles => 'Singles'; + + @override + String historyTracksCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count tracks', + one: '1 track', + ); + return '$_temp0'; + } + + @override + String historyAlbumsCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count albums', + one: '1 album', + ); + return '$_temp0'; + } + + @override + String get historyNoDownloads => 'No download history'; + + @override + String get historyNoDownloadsSubtitle => 'Downloaded tracks will appear here'; + + @override + String get historyNoAlbums => 'No album downloads'; + + @override + String get historyNoAlbumsSubtitle => + 'Download multiple tracks from an album to see them here'; + + @override + String get historyNoSingles => 'No single downloads'; + + @override + String get historyNoSinglesSubtitle => + 'Single track downloads will appear here'; + + @override + String get settingsTitle => 'Settings'; + + @override + String get settingsDownload => 'Download'; + + @override + String get settingsAppearance => 'Appearance'; + + @override + String get settingsOptions => 'Options'; + + @override + String get settingsExtensions => 'Extensions'; + + @override + String get settingsAbout => 'About'; + + @override + String get downloadTitle => 'Download'; + + @override + String get downloadLocation => 'Download Location'; + + @override + String get downloadLocationSubtitle => 'Choose where to save files'; + + @override + String get downloadLocationDefault => 'Default location'; + + @override + String get downloadDefaultService => 'Default Service'; + + @override + String get downloadDefaultServiceSubtitle => 'Service used for downloads'; + + @override + String get downloadDefaultQuality => 'Default Quality'; + + @override + String get downloadAskQuality => 'Ask Quality Before Download'; + + @override + String get downloadAskQualitySubtitle => + 'Show quality picker for each download'; + + @override + String get downloadFilenameFormat => 'Filename Format'; + + @override + String get downloadFolderOrganization => 'Folder Organization'; + + @override + String get downloadSeparateSingles => 'Separate Singles'; + + @override + String get downloadSeparateSinglesSubtitle => + 'Put single tracks in a separate folder'; + + @override + String get qualityBest => 'Best Available'; + + @override + String get qualityFlac => 'FLAC'; + + @override + String get quality320 => '320 kbps'; + + @override + String get quality128 => '128 kbps'; + + @override + String get appearanceTitle => 'Appearance'; + + @override + String get appearanceTheme => 'Theme'; + + @override + String get appearanceThemeSystem => 'System'; + + @override + String get appearanceThemeLight => 'Light'; + + @override + String get appearanceThemeDark => 'Dark'; + + @override + String get appearanceDynamicColor => 'Dynamic Color'; + + @override + String get appearanceDynamicColorSubtitle => 'Use colors from your wallpaper'; + + @override + String get appearanceAccentColor => 'Accent Color'; + + @override + String get appearanceHistoryView => 'History View'; + + @override + String get appearanceHistoryViewList => 'List'; + + @override + String get appearanceHistoryViewGrid => 'Grid'; + + @override + String get optionsTitle => 'Options'; + + @override + String get optionsSearchSource => 'Search Source'; + + @override + String get optionsPrimaryProvider => 'Primary Provider'; + + @override + String get optionsPrimaryProviderSubtitle => + 'Service used when searching by track name.'; + + @override + String optionsUsingExtension(String extensionName) { + return 'Using extension: $extensionName'; + } + + @override + String get optionsSwitchBack => + 'Tap Deezer or Spotify to switch back from extension'; + + @override + String get optionsAutoFallback => 'Auto Fallback'; + + @override + String get optionsAutoFallbackSubtitle => + 'Try other services if download fails'; + + @override + String get optionsUseExtensionProviders => 'Use Extension Providers'; + + @override + String get optionsUseExtensionProvidersOn => 'Extensions will be tried first'; + + @override + String get optionsUseExtensionProvidersOff => 'Using built-in providers only'; + + @override + String get optionsEmbedLyrics => 'Embed Lyrics'; + + @override + String get optionsEmbedLyricsSubtitle => + 'Embed synced lyrics into FLAC files'; + + @override + String get optionsMaxQualityCover => 'Max Quality Cover'; + + @override + String get optionsMaxQualityCoverSubtitle => + 'Download highest resolution cover art'; + + @override + String get optionsConcurrentDownloads => 'Concurrent Downloads'; + + @override + String get optionsConcurrentSequential => 'Sequential (1 at a time)'; + + @override + String optionsConcurrentParallel(int count) { + return '$count parallel downloads'; + } + + @override + String get optionsConcurrentWarning => + 'Parallel downloads may trigger rate limiting'; + + @override + String get optionsExtensionStore => 'Extension Store'; + + @override + String get optionsExtensionStoreSubtitle => 'Show Store tab in navigation'; + + @override + String get optionsCheckUpdates => 'Check for Updates'; + + @override + String get optionsCheckUpdatesSubtitle => + 'Notify when new version is available'; + + @override + String get optionsUpdateChannel => 'Update Channel'; + + @override + String get optionsUpdateChannelStable => 'Stable releases only'; + + @override + String get optionsUpdateChannelPreview => 'Get preview releases'; + + @override + String get optionsUpdateChannelWarning => + 'Preview may contain bugs or incomplete features'; + + @override + String get optionsClearHistory => 'Clear Download History'; + + @override + String get optionsClearHistorySubtitle => + 'Remove all downloaded tracks from history'; + + @override + String get optionsDetailedLogging => 'Detailed Logging'; + + @override + String get optionsDetailedLoggingOn => 'Detailed logs are being recorded'; + + @override + String get optionsDetailedLoggingOff => 'Enable for bug reports'; + + @override + String get optionsSpotifyCredentials => 'Spotify Credentials'; + + @override + String optionsSpotifyCredentialsConfigured(String clientId) { + return 'Client ID: $clientId...'; + } + + @override + String get optionsSpotifyCredentialsRequired => 'Required - tap to configure'; + + @override + String get optionsSpotifyWarning => + 'Spotify requires your own API credentials. Get them free from developer.spotify.com'; + + @override + String get extensionsTitle => 'Extensions'; + + @override + String get extensionsInstalled => 'Installed Extensions'; + + @override + String get extensionsNone => 'No extensions installed'; + + @override + String get extensionsNoneSubtitle => 'Install extensions from the Store tab'; + + @override + String get extensionsEnabled => 'Enabled'; + + @override + String get extensionsDisabled => 'Disabled'; + + @override + String extensionsVersion(String version) { + return 'Version $version'; + } + + @override + String extensionsAuthor(String author) { + return 'by $author'; + } + + @override + String get extensionsUninstall => 'Uninstall'; + + @override + String get extensionsSetAsSearch => 'Set as Search Provider'; + + @override + String get storeTitle => 'Extension Store'; + + @override + String get storeSearch => 'Search extensions...'; + + @override + String get storeInstall => 'Install'; + + @override + String get storeInstalled => 'Installed'; + + @override + String get storeUpdate => 'Update'; + + @override + String get aboutTitle => 'About'; + + @override + String get aboutContributors => 'Contributors'; + + @override + String get aboutMobileDeveloper => 'Mobile version developer'; + + @override + String get aboutOriginalCreator => 'Creator of the original SpotiFLAC'; + + @override + String get aboutLogoArtist => + 'The talented artist who created our beautiful app logo!'; + + @override + String get aboutSpecialThanks => 'Special Thanks'; + + @override + String get aboutLinks => 'Links'; + + @override + String get aboutMobileSource => 'Mobile source code'; + + @override + String get aboutPCSource => 'PC source code'; + + @override + String get aboutReportIssue => 'Report an issue'; + + @override + String get aboutReportIssueSubtitle => 'Report any problems you encounter'; + + @override + String get aboutFeatureRequest => 'Feature request'; + + @override + String get aboutFeatureRequestSubtitle => 'Suggest new features for the app'; + + @override + String get aboutSupport => 'Support'; + + @override + String get aboutBuyMeCoffee => 'Buy me a coffee'; + + @override + String get aboutBuyMeCoffeeSubtitle => 'Support development on Ko-fi'; + + @override + String get aboutApp => 'App'; + + @override + String get aboutVersion => 'Version'; + + @override + String get aboutBinimumDesc => + 'The creator of QQDL & HiFi API. Without this API, Tidal downloads wouldn\'t exist!'; + + @override + String get aboutSachinsenalDesc => + 'The original HiFi project creator. The foundation of Tidal integration!'; + + @override + String get aboutDoubleDouble => 'DoubleDouble'; + + @override + String get aboutDoubleDoubleDesc => + 'Amazing API for Amazon Music downloads. Thank you for making it free!'; + + @override + String get aboutDabMusic => 'DAB Music'; + + @override + String get aboutDabMusicDesc => + 'The best Qobuz streaming API. Hi-Res downloads wouldn\'t be possible without this!'; + + @override + String get aboutAppDescription => + 'Download Spotify tracks in lossless quality from Tidal, Qobuz, and Amazon Music.'; + + @override + String get albumTitle => 'Album'; + + @override + String albumTracks(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count tracks', + one: '1 track', + ); + return '$_temp0'; + } + + @override + String get albumDownloadAll => 'Download All'; + + @override + String get albumDownloadRemaining => 'Download Remaining'; + + @override + String get playlistTitle => 'Playlist'; + + @override + String get artistTitle => 'Artist'; + + @override + String get artistAlbums => 'Albums'; + + @override + String get artistSingles => 'Singles & EPs'; + + @override + String get artistCompilations => 'Compilations'; + + @override + String artistReleases(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count releases', + one: '1 release', + ); + return '$_temp0'; + } + + @override + String get trackMetadataTitle => 'Track Info'; + + @override + String get trackMetadataArtist => 'Artist'; + + @override + String get trackMetadataAlbum => 'Album'; + + @override + String get trackMetadataDuration => 'Duration'; + + @override + String get trackMetadataQuality => 'Quality'; + + @override + String get trackMetadataPath => 'File Path'; + + @override + String get trackMetadataDownloadedAt => 'Downloaded'; + + @override + String get trackMetadataService => 'Service'; + + @override + String get trackMetadataPlay => 'Play'; + + @override + String get trackMetadataShare => 'Share'; + + @override + String get trackMetadataDelete => 'Delete'; + + @override + String get trackMetadataRedownload => 'Re-download'; + + @override + String get trackMetadataOpenFolder => 'Open Folder'; + + @override + String get setupTitle => 'Welcome to SpotiFLAC'; + + @override + String get setupSubtitle => 'Let\'s get you started'; + + @override + String get setupStoragePermission => 'Storage Permission'; + + @override + String get setupStoragePermissionSubtitle => + 'Required to save downloaded files'; + + @override + String get setupStoragePermissionGranted => 'Permission granted'; + + @override + String get setupStoragePermissionDenied => 'Permission denied'; + + @override + String get setupGrantPermission => 'Grant Permission'; + + @override + String get setupDownloadLocation => 'Download Location'; + + @override + String get setupChooseFolder => 'Choose Folder'; + + @override + String get setupContinue => 'Continue'; + + @override + String get setupSkip => 'Skip for now'; + + @override + String get setupStorageAccessRequired => 'Storage Access Required'; + + @override + String get setupStorageAccessMessage => + 'SpotiFLAC needs \"All files access\" permission to save music files to your chosen folder.'; + + @override + String get setupStorageAccessMessageAndroid11 => + 'Android 11+ requires \"All files access\" permission to save files to your chosen download folder.'; + + @override + String get setupOpenSettings => 'Open Settings'; + + @override + String get setupPermissionDeniedMessage => + 'Permission denied. Please grant all permissions to continue.'; + + @override + String setupPermissionRequired(String permissionType) { + return '$permissionType Permission Required'; + } + + @override + String setupPermissionRequiredMessage(String permissionType) { + return '$permissionType permission is required for the best experience. You can change this later in Settings.'; + } + + @override + String get setupSelectDownloadFolder => 'Select Download Folder'; + + @override + String get setupUseDefaultFolder => 'Use Default Folder?'; + + @override + String get setupNoFolderSelected => + 'No folder selected. Would you like to use the default Music folder?'; + + @override + String get setupUseDefault => 'Use Default'; + + @override + String get setupDownloadLocationTitle => 'Download Location'; + + @override + String get setupDownloadLocationIosMessage => + 'On iOS, downloads are saved to the app\'s Documents folder. You can access them via the Files app.'; + + @override + String get setupAppDocumentsFolder => 'App Documents Folder'; + + @override + String get setupAppDocumentsFolderSubtitle => + 'Recommended - accessible via Files app'; + + @override + String get setupChooseFromFiles => 'Choose from Files'; + + @override + String get setupChooseFromFilesSubtitle => 'Select iCloud or other location'; + + @override + String get setupIosEmptyFolderWarning => + 'iOS limitation: Empty folders cannot be selected. Choose a folder with at least one file.'; + + @override + String get setupDownloadInFlac => 'Download Spotify tracks in FLAC'; + + @override + String get setupStepStorage => 'Storage'; + + @override + String get setupStepNotification => 'Notification'; + + @override + String get setupStepFolder => 'Folder'; + + @override + String get setupStepSpotify => 'Spotify'; + + @override + String get setupStepPermission => 'Permission'; + + @override + String get setupStorageGranted => 'Storage Permission Granted!'; + + @override + String get setupStorageRequired => 'Storage Permission Required'; + + @override + String get setupStorageDescription => + 'SpotiFLAC needs storage permission to save your downloaded music files.'; + + @override + String get setupNotificationGranted => 'Notification Permission Granted!'; + + @override + String get setupNotificationEnable => 'Enable Notifications'; + + @override + String get setupNotificationDescription => + 'Get notified when downloads complete or require attention.'; + + @override + String get setupFolderSelected => 'Download Folder Selected!'; + + @override + String get setupFolderChoose => 'Choose Download Folder'; + + @override + String get setupFolderDescription => + 'Select a folder where your downloaded music will be saved.'; + + @override + String get setupChangeFolder => 'Change Folder'; + + @override + String get setupSelectFolder => 'Select Folder'; + + @override + String get setupSpotifyApiOptional => 'Spotify API (Optional)'; + + @override + String get setupSpotifyApiDescription => + 'Add your Spotify API credentials for better search results and access to Spotify-exclusive content.'; + + @override + String get setupUseSpotifyApi => 'Use Spotify API'; + + @override + String get setupEnterCredentialsBelow => 'Enter your credentials below'; + + @override + String get setupUsingDeezer => 'Using Deezer (no account needed)'; + + @override + String get setupEnterClientId => 'Enter Spotify Client ID'; + + @override + String get setupEnterClientSecret => 'Enter Spotify Client Secret'; + + @override + String get setupGetFreeCredentials => + 'Get your free API credentials from the Spotify Developer Dashboard.'; + + @override + String get setupEnableNotifications => 'Enable Notifications'; + + @override + String get setupProceedToNextStep => 'You can now proceed to the next step.'; + + @override + String get setupNotificationProgressDescription => + 'You will receive download progress notifications.'; + + @override + String get setupNotificationBackgroundDescription => + 'Get notified about download progress and completion. This helps you track downloads when the app is in background.'; + + @override + String get setupSkipForNow => 'Skip for now'; + + @override + String get setupBack => 'Back'; + + @override + String get setupNext => 'Next'; + + @override + String get setupGetStarted => 'Get Started'; + + @override + String get setupSkipAndStart => 'Skip & Start'; + + @override + String get setupAllowAccessToManageFiles => + 'Please enable \"Allow access to manage all files\" in the next screen.'; + + @override + String get setupGetCredentialsFromSpotify => + 'Get credentials from developer.spotify.com'; + + @override + String get dialogCancel => 'Cancel'; + + @override + String get dialogOk => 'OK'; + + @override + String get dialogSave => 'Save'; + + @override + String get dialogDelete => 'Delete'; + + @override + String get dialogRetry => 'Retry'; + + @override + String get dialogClose => 'Close'; + + @override + String get dialogYes => 'Yes'; + + @override + String get dialogNo => 'No'; + + @override + String get dialogClear => 'Clear'; + + @override + String get dialogConfirm => 'Confirm'; + + @override + String get dialogDone => 'Done'; + + @override + String get dialogImport => 'Import'; + + @override + String get dialogDiscard => 'Discard'; + + @override + String get dialogRemove => 'Remove'; + + @override + String get dialogUninstall => 'Uninstall'; + + @override + String get dialogDiscardChanges => 'Discard Changes?'; + + @override + String get dialogUnsavedChanges => + 'You have unsaved changes. Do you want to discard them?'; + + @override + String get dialogDownloadFailed => 'Download Failed'; + + @override + String get dialogTrackLabel => 'Track:'; + + @override + String get dialogArtistLabel => 'Artist:'; + + @override + String get dialogErrorLabel => 'Error:'; + + @override + String get dialogClearAll => 'Clear All'; + + @override + String get dialogClearAllDownloads => + 'Are you sure you want to clear all downloads?'; + + @override + String get dialogRemoveFromDevice => 'Remove from device?'; + + @override + String get dialogRemoveExtension => 'Remove Extension'; + + @override + String get dialogRemoveExtensionMessage => + 'Are you sure you want to remove this extension? This cannot be undone.'; + + @override + String get dialogUninstallExtension => 'Uninstall Extension?'; + + @override + String dialogUninstallExtensionMessage(String extensionName) { + return 'Are you sure you want to remove $extensionName?'; + } + + @override + String get dialogClearHistoryTitle => 'Clear History'; + + @override + String get dialogClearHistoryMessage => + 'Are you sure you want to clear all download history? This cannot be undone.'; + + @override + String get dialogDeleteSelectedTitle => 'Delete Selected'; + + @override + String dialogDeleteSelectedMessage(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Delete $count $_temp0 from history?\n\nThis will also delete the files from storage.'; + } + + @override + String get dialogImportPlaylistTitle => 'Import Playlist'; + + @override + String dialogImportPlaylistMessage(int count) { + return 'Found $count tracks in CSV. Add them to download queue?'; + } + + @override + String snackbarAddedToQueue(String trackName) { + return 'Added \"$trackName\" to queue'; + } + + @override + String snackbarAddedTracksToQueue(int count) { + return 'Added $count tracks to queue'; + } + + @override + String snackbarAlreadyDownloaded(String trackName) { + return '\"$trackName\" already downloaded'; + } + + @override + String get snackbarHistoryCleared => 'History cleared'; + + @override + String get snackbarCredentialsSaved => 'Credentials saved'; + + @override + String get snackbarCredentialsCleared => 'Credentials cleared'; + + @override + String snackbarDeletedTracks(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Deleted $count $_temp0'; + } + + @override + String snackbarCannotOpenFile(String error) { + return 'Cannot open file: $error'; + } + + @override + String get snackbarFillAllFields => 'Please fill all fields'; + + @override + String get snackbarViewQueue => 'View Queue'; + + @override + String snackbarFailedToLoad(String error) { + return 'Failed to load: $error'; + } + + @override + String snackbarUrlCopied(String platform) { + return '$platform URL copied to clipboard'; + } + + @override + String get snackbarFileNotFound => 'File not found'; + + @override + String get snackbarSelectExtFile => 'Please select a .spotiflac-ext file'; + + @override + String get snackbarProviderPrioritySaved => 'Provider priority saved'; + + @override + String get snackbarMetadataProviderSaved => + 'Metadata provider priority saved'; + + @override + String snackbarExtensionInstalled(String extensionName) { + return '$extensionName installed.'; + } + + @override + String snackbarExtensionUpdated(String extensionName) { + return '$extensionName updated.'; + } + + @override + String get snackbarFailedToInstall => 'Failed to install extension'; + + @override + String get snackbarFailedToUpdate => 'Failed to update extension'; + + @override + String get errorRateLimited => 'Rate Limited'; + + @override + String get errorRateLimitedMessage => + 'Too many requests. Please wait a moment before searching again.'; + + @override + String errorFailedToLoad(String item) { + return 'Failed to load $item'; + } + + @override + String get errorNoTracksFound => 'No tracks found'; + + @override + String errorMissingExtensionSource(String item) { + return 'Cannot load $item: missing extension source'; + } + + @override + String get statusQueued => 'Queued'; + + @override + String get statusDownloading => 'Downloading'; + + @override + String get statusFinalizing => 'Finalizing'; + + @override + String get statusCompleted => 'Completed'; + + @override + String get statusFailed => 'Failed'; + + @override + String get statusSkipped => 'Skipped'; + + @override + String get statusPaused => 'Paused'; + + @override + String get actionPause => 'Pause'; + + @override + String get actionResume => 'Resume'; + + @override + String get actionCancel => 'Cancel'; + + @override + String get actionStop => 'Stop'; + + @override + String get actionSelect => 'Select'; + + @override + String get actionSelectAll => 'Select All'; + + @override + String get actionDeselect => 'Deselect'; + + @override + String get actionPaste => 'Paste'; + + @override + String get actionImportCsv => 'Import CSV'; + + @override + String get actionRemoveCredentials => 'Remove Credentials'; + + @override + String get actionSaveCredentials => 'Save Credentials'; + + @override + String selectionSelected(int count) { + return '$count selected'; + } + + @override + String get selectionAllSelected => 'All tracks selected'; + + @override + String get selectionTapToSelect => 'Tap tracks to select'; + + @override + String selectionDeleteTracks(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Delete $count $_temp0'; + } + + @override + String get selectionSelectToDelete => 'Select tracks to delete'; + + @override + String progressFetchingMetadata(int current, int total) { + return 'Fetching metadata... $current/$total'; + } + + @override + String get progressReadingCsv => 'Reading CSV...'; + + @override + String get searchSongs => 'Songs'; + + @override + String get searchArtists => 'Artists'; + + @override + String get searchAlbums => 'Albums'; + + @override + String get searchPlaylists => 'Playlists'; + + @override + String get tooltipPlay => 'Play'; + + @override + String get tooltipCancel => 'Cancel'; + + @override + String get tooltipStop => 'Stop'; + + @override + String get tooltipRetry => 'Retry'; + + @override + String get tooltipRemove => 'Remove'; + + @override + String get tooltipClear => 'Clear'; + + @override + String get tooltipPaste => 'Paste'; + + @override + String get filenameFormat => 'Filename Format'; + + @override + String filenameFormatPreview(String preview) { + return 'Preview: $preview'; + } + + @override + String get filenameAvailablePlaceholders => 'Available placeholders:'; + + @override + String filenameHint(Object artist, Object title) { + return '$artist - $title'; + } + + @override + String get folderOrganization => 'Folder Organization'; + + @override + String get folderOrganizationNone => 'No organization'; + + @override + String get folderOrganizationByArtist => 'By Artist'; + + @override + String get folderOrganizationByAlbum => 'By Album'; + + @override + String get folderOrganizationByArtistAlbum => 'Artist/Album'; + + @override + String get folderOrganizationDescription => + 'Organize downloaded files into folders'; + + @override + String get folderOrganizationNoneSubtitle => 'All files in download folder'; + + @override + String get folderOrganizationByArtistSubtitle => + 'Separate folder for each artist'; + + @override + String get folderOrganizationByAlbumSubtitle => + 'Separate folder for each album'; + + @override + String get folderOrganizationByArtistAlbumSubtitle => + 'Nested folders for artist and album'; + + @override + String get updateAvailable => 'Update Available'; + + @override + String updateNewVersion(String version) { + return 'Version $version is available'; + } + + @override + String get updateDownload => 'Download'; + + @override + String get updateLater => 'Later'; + + @override + String get updateChangelog => 'Changelog'; + + @override + String get updateStartingDownload => 'Starting download...'; + + @override + String get updateDownloadFailed => 'Download failed'; + + @override + String get updateFailedMessage => 'Failed to download update'; + + @override + String get updateNewVersionReady => 'A new version is ready'; + + @override + String get updateCurrent => 'Current'; + + @override + String get updateNew => 'New'; + + @override + String get updateDownloading => 'Downloading...'; + + @override + String get updateWhatsNew => 'What\'s New'; + + @override + String get updateDownloadInstall => 'Download & Install'; + + @override + String get updateDontRemind => 'Don\'t remind'; + + @override + String get providerPriority => 'Provider Priority'; + + @override + String get providerPrioritySubtitle => 'Drag to reorder download providers'; + + @override + String get providerPriorityTitle => 'Provider Priority'; + + @override + String get providerPriorityDescription => + 'Drag to reorder download providers. The app will try providers from top to bottom when downloading tracks.'; + + @override + String get providerPriorityInfo => + 'If a track is not available on the first provider, the app will automatically try the next one.'; + + @override + String get providerBuiltIn => 'Built-in'; + + @override + String get providerExtension => 'Extension'; + + @override + String get metadataProviderPriority => 'Metadata Provider Priority'; + + @override + String get metadataProviderPrioritySubtitle => + 'Order used when fetching track metadata'; + + @override + String get metadataProviderPriorityTitle => 'Metadata Priority'; + + @override + String get metadataProviderPriorityDescription => + 'Drag to reorder metadata providers. The app will try providers from top to bottom when searching for tracks and fetching metadata.'; + + @override + String get metadataProviderPriorityInfo => + 'Deezer has no rate limits and is recommended as primary. Spotify may rate limit after many requests.'; + + @override + String get metadataNoRateLimits => 'No rate limits'; + + @override + String get metadataMayRateLimit => 'May rate limit'; + + @override + String get logTitle => 'Logs'; + + @override + String get logCopy => 'Copy Logs'; + + @override + String get logClear => 'Clear Logs'; + + @override + String get logShare => 'Share Logs'; + + @override + String get logEmpty => 'No logs yet'; + + @override + String get logCopied => 'Logs copied to clipboard'; + + @override + String get logSearchHint => 'Search logs...'; + + @override + String get logFilterLevel => 'Level'; + + @override + String get logFilterSection => 'Filter'; + + @override + String get logShareLogs => 'Share logs'; + + @override + String get logClearLogs => 'Clear logs'; + + @override + String get logClearLogsTitle => 'Clear Logs'; + + @override + String get logClearLogsMessage => 'Are you sure you want to clear all logs?'; + + @override + String get logIspBlocking => 'ISP BLOCKING DETECTED'; + + @override + String get logRateLimited => 'RATE LIMITED'; + + @override + String get logNetworkError => 'NETWORK ERROR'; + + @override + String get logTrackNotFound => 'TRACK NOT FOUND'; + + @override + String get logFilterBySeverity => 'Filter logs by severity'; + + @override + String get logNoLogsYet => 'No logs yet'; + + @override + String get logNoLogsYetSubtitle => 'Logs will appear here as you use the app'; + + @override + String get logIssueSummary => 'Issue Summary'; + + @override + String get logIspBlockingDescription => + 'Your ISP may be blocking access to download services'; + + @override + String get logIspBlockingSuggestion => + 'Try using a VPN or change DNS to 1.1.1.1 or 8.8.8.8'; + + @override + String get logRateLimitedDescription => 'Too many requests to the service'; + + @override + String get logRateLimitedSuggestion => + 'Wait a few minutes before trying again'; + + @override + String get logNetworkErrorDescription => 'Connection issues detected'; + + @override + String get logNetworkErrorSuggestion => 'Check your internet connection'; + + @override + String get logTrackNotFoundDescription => + 'Some tracks could not be found on download services'; + + @override + String get logTrackNotFoundSuggestion => + 'The track may not be available in lossless quality'; + + @override + String logTotalErrors(int count) { + return 'Total errors: $count'; + } + + @override + String logAffected(String domains) { + return 'Affected: $domains'; + } + + @override + String logEntriesFiltered(int count) { + return 'Entries ($count filtered)'; + } + + @override + String logEntries(int count) { + return 'Entries ($count)'; + } + + @override + String get credentialsTitle => 'Spotify Credentials'; + + @override + String get credentialsDescription => + 'Enter your Client ID and Secret to use your own Spotify application quota.'; + + @override + String get credentialsClientId => 'Client ID'; + + @override + String get credentialsClientIdHint => 'Paste Client ID'; + + @override + String get credentialsClientSecret => 'Client Secret'; + + @override + String get credentialsClientSecretHint => 'Paste Client Secret'; + + @override + String get channelStable => 'Stable'; + + @override + String get channelPreview => 'Preview'; + + @override + String get sectionSearchSource => 'Search Source'; + + @override + String get sectionDownload => 'Download'; + + @override + String get sectionPerformance => 'Performance'; + + @override + String get sectionApp => 'App'; + + @override + String get sectionData => 'Data'; + + @override + String get sectionDebug => 'Debug'; + + @override + String get sectionService => 'Service'; + + @override + String get sectionAudioQuality => 'Audio Quality'; + + @override + String get sectionFileSettings => 'File Settings'; + + @override + String get sectionColor => 'Color'; + + @override + String get sectionTheme => 'Theme'; + + @override + String get sectionLayout => 'Layout'; + + @override + String get sectionLanguage => 'Language'; + + @override + String get appearanceLanguage => 'App Language'; + + @override + String get appearanceLanguageSubtitle => 'Choose your preferred language'; + + @override + String get settingsAppearanceSubtitle => 'Theme, colors, display'; + + @override + String get settingsDownloadSubtitle => 'Service, quality, filename format'; + + @override + String get settingsOptionsSubtitle => 'Fallback, lyrics, cover art, updates'; + + @override + String get settingsExtensionsSubtitle => 'Manage download providers'; + + @override + String get settingsLogsSubtitle => 'View app logs for debugging'; + + @override + String get loadingSharedLink => 'Loading shared link...'; + + @override + String get pressBackAgainToExit => 'Press back again to exit'; + + @override + String get tracksHeader => 'Tracks'; + + @override + String downloadAllCount(int count) { + return 'Download All ($count)'; + } + + @override + String tracksCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count tracks', + one: '1 track', + ); + return '$_temp0'; + } + + @override + String get trackCopyFilePath => 'Copy file path'; + + @override + String get trackRemoveFromDevice => 'Remove from device'; + + @override + String get trackLoadLyrics => 'Load Lyrics'; + + @override + String get trackMetadata => 'Metadata'; + + @override + String get trackFileInfo => 'File Info'; + + @override + String get trackLyrics => 'Lyrics'; + + @override + String get trackFileNotFound => 'File not found'; + + @override + String get trackOpenInDeezer => 'Open in Deezer'; + + @override + String get trackOpenInSpotify => 'Open in Spotify'; + + @override + String get trackTrackName => 'Track name'; + + @override + String get trackArtist => 'Artist'; + + @override + String get trackAlbumArtist => 'Album artist'; + + @override + String get trackAlbum => 'Album'; + + @override + String get trackTrackNumber => 'Track number'; + + @override + String get trackDiscNumber => 'Disc number'; + + @override + String get trackDuration => 'Duration'; + + @override + String get trackAudioQuality => 'Audio quality'; + + @override + String get trackReleaseDate => 'Release date'; + + @override + String get trackDownloaded => 'Downloaded'; + + @override + String get trackCopyLyrics => 'Copy lyrics'; + + @override + String get trackLyricsNotAvailable => 'Lyrics not available for this track'; + + @override + String get trackLyricsTimeout => 'Request timed out. Try again later.'; + + @override + String get trackLyricsLoadFailed => 'Failed to load lyrics'; + + @override + String get trackCopiedToClipboard => 'Copied to clipboard'; + + @override + String get trackDeleteConfirmTitle => 'Remove from device?'; + + @override + String get trackDeleteConfirmMessage => + 'This will permanently delete the downloaded file and remove it from your history.'; + + @override + String trackCannotOpen(String message) { + return 'Cannot open: $message'; + } + + @override + String get dateToday => 'Today'; + + @override + String get dateYesterday => 'Yesterday'; + + @override + String dateDaysAgo(int count) { + return '$count days ago'; + } + + @override + String dateWeeksAgo(int count) { + return '$count weeks ago'; + } + + @override + String dateMonthsAgo(int count) { + return '$count months ago'; + } + + @override + String get concurrentSequential => 'Sequential'; + + @override + String get concurrentParallel2 => '2 Parallel'; + + @override + String get concurrentParallel3 => '3 Parallel'; + + @override + String get tapToSeeError => 'Tap to see error details'; + + @override + String get storeFilterAll => 'All'; + + @override + String get storeFilterMetadata => 'Metadata'; + + @override + String get storeFilterDownload => 'Download'; + + @override + String get storeFilterUtility => 'Utility'; + + @override + String get storeFilterLyrics => 'Lyrics'; + + @override + String get storeFilterIntegration => 'Integration'; + + @override + String get storeClearFilters => 'Clear filters'; + + @override + String get storeNoResults => 'No extensions found'; + + @override + String get extensionProviderPriority => 'Provider Priority'; + + @override + String get extensionInstallButton => 'Install Extension'; + + @override + String get extensionDefaultProvider => 'Default (Deezer/Spotify)'; + + @override + String get extensionDefaultProviderSubtitle => 'Use built-in search'; + + @override + String get extensionAuthor => 'Author'; + + @override + String get extensionId => 'ID'; + + @override + String get extensionError => 'Error'; + + @override + String get extensionCapabilities => 'Capabilities'; + + @override + String get extensionMetadataProvider => 'Metadata Provider'; + + @override + String get extensionDownloadProvider => 'Download Provider'; + + @override + String get extensionLyricsProvider => 'Lyrics Provider'; + + @override + String get extensionUrlHandler => 'URL Handler'; + + @override + String get extensionQualityOptions => 'Quality Options'; + + @override + String get extensionPostProcessingHooks => 'Post-Processing Hooks'; + + @override + String get extensionPermissions => 'Permissions'; + + @override + String get extensionSettings => 'Settings'; + + @override + String get extensionRemoveButton => 'Remove Extension'; + + @override + String get extensionUpdated => 'Updated'; + + @override + String get extensionMinAppVersion => 'Min App Version'; + + @override + String get extensionCustomTrackMatching => 'Custom Track Matching'; + + @override + String get extensionPostProcessing => 'Post-Processing'; + + @override + String extensionHooksAvailable(int count) { + return '$count hook(s) available'; + } + + @override + String extensionPatternsCount(int count) { + return '$count pattern(s)'; + } + + @override + String extensionStrategy(String strategy) { + return 'Strategy: $strategy'; + } + + @override + String get extensionsProviderPrioritySection => 'Provider Priority'; + + @override + String get extensionsInstalledSection => 'Installed Extensions'; + + @override + String get extensionsNoExtensions => 'No extensions installed'; + + @override + String get extensionsNoExtensionsSubtitle => + 'Install .spotiflac-ext files to add new providers'; + + @override + String get extensionsInstallButton => 'Install Extension'; + + @override + String get extensionsInfoTip => + 'Extensions can add new metadata and download providers. Only install extensions from trusted sources.'; + + @override + String get extensionsInstalledSuccess => 'Extension installed successfully'; + + @override + String get extensionsDownloadPriority => 'Download Priority'; + + @override + String get extensionsDownloadPrioritySubtitle => 'Set download service order'; + + @override + String get extensionsNoDownloadProvider => + 'No extensions with download provider'; + + @override + String get extensionsMetadataPriority => 'Metadata Priority'; + + @override + String get extensionsMetadataPrioritySubtitle => + 'Set search & metadata source order'; + + @override + String get extensionsNoMetadataProvider => + 'No extensions with metadata provider'; + + @override + String get extensionsSearchProvider => 'Search Provider'; + + @override + String get extensionsNoCustomSearch => 'No extensions with custom search'; + + @override + String get extensionsSearchProviderDescription => + 'Choose which service to use for searching tracks'; + + @override + String get extensionsCustomSearch => 'Custom search'; + + @override + String get extensionsErrorLoading => 'Error loading extension'; + + @override + String get qualityFlacLossless => 'FLAC Lossless'; + + @override + String get qualityFlacLosslessSubtitle => '16-bit / 44.1kHz'; + + @override + String get qualityHiResFlac => 'Hi-Res FLAC'; + + @override + String get qualityHiResFlacSubtitle => '24-bit / up to 96kHz'; + + @override + String get qualityHiResFlacMax => 'Hi-Res FLAC Max'; + + @override + String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; + + @override + String get qualityNote => + 'Actual quality depends on track availability from the service'; + + @override + String get downloadAskBeforeDownload => 'Ask Before Download'; + + @override + String get downloadDirectory => 'Download Directory'; + + @override + String get downloadSeparateSinglesFolder => 'Separate Singles Folder'; + + @override + String get downloadAlbumFolderStructure => 'Album Folder Structure'; + + @override + String get downloadSaveFormat => 'Save Format'; + + @override + String get downloadSelectService => 'Select Service'; + + @override + String get downloadSelectQuality => 'Select Quality'; + + @override + String get downloadFrom => 'Download From'; + + @override + String get downloadDefaultQualityLabel => 'Default Quality'; + + @override + String get downloadBestAvailable => 'Best available'; + + @override + String get folderNone => 'None'; + + @override + String get folderNoneSubtitle => 'Save all files directly to download folder'; + + @override + String get folderArtist => 'Artist'; + + @override + String get folderArtistSubtitle => 'Artist Name/filename'; + + @override + String get folderAlbum => 'Album'; + + @override + String get folderAlbumSubtitle => 'Album Name/filename'; + + @override + String get folderArtistAlbum => 'Artist/Album'; + + @override + String get folderArtistAlbumSubtitle => 'Artist Name/Album Name/filename'; + + @override + String get serviceTidal => 'Tidal'; + + @override + String get serviceQobuz => 'Qobuz'; + + @override + String get serviceAmazon => 'Amazon'; + + @override + String get serviceDeezer => 'Deezer'; + + @override + String get serviceSpotify => 'Spotify'; + + @override + String get appearanceAmoledDark => 'AMOLED Dark'; + + @override + String get appearanceAmoledDarkSubtitle => 'Pure black background'; + + @override + String get appearanceChooseAccentColor => 'Choose Accent Color'; + + @override + String get appearanceChooseTheme => 'Theme Mode'; + + @override + String get queueTitle => 'Download Queue'; + + @override + String get queueClearAll => 'Clear All'; + + @override + String get queueClearAllMessage => + 'Are you sure you want to clear all downloads?'; + + @override + String get queueEmpty => 'No downloads in queue'; + + @override + String get queueEmptySubtitle => 'Add tracks from the home screen'; + + @override + String get queueClearCompleted => 'Clear completed'; + + @override + String get queueDownloadFailed => 'Download Failed'; + + @override + String get queueTrackLabel => 'Track:'; + + @override + String get queueArtistLabel => 'Artist:'; + + @override + String get queueErrorLabel => 'Error:'; + + @override + String get queueUnknownError => 'Unknown error'; + + @override + String get albumFolderArtistAlbum => 'Artist / Album'; + + @override + String get albumFolderArtistAlbumSubtitle => 'Albums/Artist Name/Album Name/'; + + @override + String get albumFolderArtistYearAlbum => 'Artist / [Year] Album'; + + @override + String get albumFolderArtistYearAlbumSubtitle => + 'Albums/Artist Name/[2005] Album Name/'; + + @override + String get albumFolderAlbumOnly => 'Album Only'; + + @override + String get albumFolderAlbumOnlySubtitle => 'Albums/Album Name/'; + + @override + String get albumFolderYearAlbum => '[Year] Album'; + + @override + String get albumFolderYearAlbumSubtitle => 'Albums/[2005] Album Name/'; + + @override + String get downloadedAlbumDeleteSelected => 'Delete Selected'; + + @override + String downloadedAlbumDeleteMessage(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Delete $count $_temp0 from this album?\n\nThis will also delete the files from storage.'; + } + + @override + String get downloadedAlbumTracksHeader => 'Tracks'; + + @override + String downloadedAlbumDownloadedCount(int count) { + return '$count downloaded'; + } + + @override + String downloadedAlbumSelectedCount(int count) { + return '$count selected'; + } + + @override + String get downloadedAlbumAllSelected => 'All tracks selected'; + + @override + String get downloadedAlbumTapToSelect => 'Tap tracks to select'; + + @override + String downloadedAlbumDeleteCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Delete $count $_temp0'; + } + + @override + String get downloadedAlbumSelectToDelete => 'Select tracks to delete'; + + @override + String get utilityFunctions => 'Utility Functions'; +} + /// The translations for Chinese, as used in Taiwan (`zh_TW`). class AppLocalizationsZhTw extends AppLocalizationsZh { AppLocalizationsZhTw() : super('zh_TW'); diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 3367e863..98366459 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -1054,7 +1054,13 @@ "sectionTheme": "Theme", "@sectionTheme": {"description": "Settings section header"}, "sectionLayout": "Layout", - "@sectionLayout": {"description": "Settings section header"}, +"@sectionLayout": {"description": "Settings section header"}, + "sectionLanguage": "Language", + "@sectionLanguage": {"description": "Settings section header for language"}, + "appearanceLanguage": "App Language", + "@appearanceLanguage": {"description": "Language setting title"}, + "appearanceLanguageSubtitle": "Choose your preferred language", + "@appearanceLanguageSubtitle": {"description": "Language setting subtitle"}, "settingsAppearanceSubtitle": "Theme, colors, display", "@settingsAppearanceSubtitle": {"description": "Appearance settings description"}, diff --git a/lib/l10n/arb/app_zh_CN.arb b/lib/l10n/arb/app_zh_CN.arb new file mode 100644 index 00000000..07634e27 --- /dev/null +++ b/lib/l10n/arb/app_zh_CN.arb @@ -0,0 +1,2577 @@ +{ + "@@locale": "zh_CN", + "@@last_modified": "2026-01-16", + "appName": "SpotiFLAC", + "@appName": { + "description": "App name - DO NOT TRANSLATE" + }, + "appDescription": "Download Spotify tracks in lossless quality from Tidal, Qobuz, and Amazon Music.", + "@appDescription": { + "description": "App description shown in about page" + }, + "navHome": "Home", + "@navHome": { + "description": "Bottom navigation - Home tab" + }, + "navHistory": "History", + "@navHistory": { + "description": "Bottom navigation - History tab" + }, + "navSettings": "Settings", + "@navSettings": { + "description": "Bottom navigation - Settings tab" + }, + "navStore": "Store", + "@navStore": { + "description": "Bottom navigation - Extension store tab" + }, + "homeTitle": "Home", + "@homeTitle": { + "description": "Home screen title" + }, + "homeSearchHint": "Paste Spotify URL or search...", + "@homeSearchHint": { + "description": "Placeholder text in search box" + }, + "homeSearchHintExtension": "Search with {extensionName}...", + "@homeSearchHintExtension": { + "description": "Placeholder when extension search is active", + "placeholders": { + "extensionName": { + "type": "String", + "description": "Name of the active extension" + } + } + }, + "homeSubtitle": "Paste a Spotify link or search by name", + "@homeSubtitle": { + "description": "Subtitle shown below search box" + }, + "homeSupports": "Supports: Track, Album, Playlist, Artist URLs", + "@homeSupports": { + "description": "Info text about supported URL types" + }, + "homeRecent": "Recent", + "@homeRecent": { + "description": "Section header for recent searches" + }, + "historyTitle": "History", + "@historyTitle": { + "description": "History screen title" + }, + "historyDownloading": "Downloading ({count})", + "@historyDownloading": { + "description": "Tab showing active downloads count", + "placeholders": { + "count": { + "type": "int", + "description": "Number of active downloads" + } + } + }, + "historyDownloaded": "Downloaded", + "@historyDownloaded": { + "description": "Tab showing completed downloads" + }, + "historyFilterAll": "All", + "@historyFilterAll": { + "description": "Filter chip - show all items" + }, + "historyFilterAlbums": "Albums", + "@historyFilterAlbums": { + "description": "Filter chip - show albums only" + }, + "historyFilterSingles": "Singles", + "@historyFilterSingles": { + "description": "Filter chip - show singles only" + }, + "historyTracksCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@historyTracksCount": { + "description": "Track count with plural form", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "historyAlbumsCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@historyAlbumsCount": { + "description": "Album count with plural form", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "historyNoDownloads": "No download history", + "@historyNoDownloads": { + "description": "Empty state title" + }, + "historyNoDownloadsSubtitle": "Downloaded tracks will appear here", + "@historyNoDownloadsSubtitle": { + "description": "Empty state subtitle" + }, + "historyNoAlbums": "No album downloads", + "@historyNoAlbums": { + "description": "Empty state when filtering albums" + }, + "historyNoAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@historyNoAlbumsSubtitle": { + "description": "Empty state subtitle for albums filter" + }, + "historyNoSingles": "No single downloads", + "@historyNoSingles": { + "description": "Empty state when filtering singles" + }, + "historyNoSinglesSubtitle": "Single track downloads will appear here", + "@historyNoSinglesSubtitle": { + "description": "Empty state subtitle for singles filter" + }, + "settingsTitle": "Settings", + "@settingsTitle": { + "description": "Settings screen title" + }, + "settingsDownload": "Download", + "@settingsDownload": { + "description": "Settings section - download options" + }, + "settingsAppearance": "Appearance", + "@settingsAppearance": { + "description": "Settings section - visual customization" + }, + "settingsOptions": "Options", + "@settingsOptions": { + "description": "Settings section - app options" + }, + "settingsExtensions": "Extensions", + "@settingsExtensions": { + "description": "Settings section - extension management" + }, + "settingsAbout": "About", + "@settingsAbout": { + "description": "Settings section - app info" + }, + "downloadTitle": "Download", + "@downloadTitle": { + "description": "Download settings page title" + }, + "downloadLocation": "Download Location", + "@downloadLocation": { + "description": "Setting for download folder" + }, + "downloadLocationSubtitle": "Choose where to save files", + "@downloadLocationSubtitle": { + "description": "Subtitle for download location" + }, + "downloadLocationDefault": "Default location", + "@downloadLocationDefault": { + "description": "Shown when using default folder" + }, + "downloadDefaultService": "Default Service", + "@downloadDefaultService": { + "description": "Setting for preferred download service (Tidal/Qobuz/Amazon)" + }, + "downloadDefaultServiceSubtitle": "Service used for downloads", + "@downloadDefaultServiceSubtitle": { + "description": "Subtitle for default service" + }, + "downloadDefaultQuality": "Default Quality", + "@downloadDefaultQuality": { + "description": "Setting for audio quality" + }, + "downloadAskQuality": "Ask Quality Before Download", + "@downloadAskQuality": { + "description": "Toggle to show quality picker" + }, + "downloadAskQualitySubtitle": "Show quality picker for each download", + "@downloadAskQualitySubtitle": { + "description": "Subtitle for ask quality toggle" + }, + "downloadFilenameFormat": "Filename Format", + "@downloadFilenameFormat": { + "description": "Setting for output filename pattern" + }, + "downloadFolderOrganization": "Folder Organization", + "@downloadFolderOrganization": { + "description": "Setting for folder structure" + }, + "downloadSeparateSingles": "Separate Singles", + "@downloadSeparateSingles": { + "description": "Toggle to separate single tracks" + }, + "downloadSeparateSinglesSubtitle": "Put single tracks in a separate folder", + "@downloadSeparateSinglesSubtitle": { + "description": "Subtitle for separate singles toggle" + }, + "qualityBest": "Best Available", + "@qualityBest": { + "description": "Audio quality option - highest available" + }, + "qualityFlac": "FLAC", + "@qualityFlac": { + "description": "Audio quality option - FLAC lossless" + }, + "quality320": "320 kbps", + "@quality320": { + "description": "Audio quality option - 320kbps MP3" + }, + "quality128": "128 kbps", + "@quality128": { + "description": "Audio quality option - 128kbps MP3" + }, + "appearanceTitle": "Appearance", + "@appearanceTitle": { + "description": "Appearance settings page title" + }, + "appearanceTheme": "Theme", + "@appearanceTheme": { + "description": "Theme mode setting" + }, + "appearanceThemeSystem": "System", + "@appearanceThemeSystem": { + "description": "Follow system theme" + }, + "appearanceThemeLight": "Light", + "@appearanceThemeLight": { + "description": "Light theme" + }, + "appearanceThemeDark": "Dark", + "@appearanceThemeDark": { + "description": "Dark theme" + }, + "appearanceDynamicColor": "Dynamic Color", + "@appearanceDynamicColor": { + "description": "Material You dynamic colors" + }, + "appearanceDynamicColorSubtitle": "Use colors from your wallpaper", + "@appearanceDynamicColorSubtitle": { + "description": "Subtitle for dynamic color" + }, + "appearanceAccentColor": "Accent Color", + "@appearanceAccentColor": { + "description": "Custom accent color picker" + }, + "appearanceHistoryView": "History View", + "@appearanceHistoryView": { + "description": "Layout style for history" + }, + "appearanceHistoryViewList": "List", + "@appearanceHistoryViewList": { + "description": "List layout option" + }, + "appearanceHistoryViewGrid": "Grid", + "@appearanceHistoryViewGrid": { + "description": "Grid layout option" + }, + "optionsTitle": "Options", + "@optionsTitle": { + "description": "Options settings page title" + }, + "optionsSearchSource": "Search Source", + "@optionsSearchSource": { + "description": "Section for search provider settings" + }, + "optionsPrimaryProvider": "Primary Provider", + "@optionsPrimaryProvider": { + "description": "Main search provider setting" + }, + "optionsPrimaryProviderSubtitle": "Service used when searching by track name.", + "@optionsPrimaryProviderSubtitle": { + "description": "Subtitle for primary provider" + }, + "optionsUsingExtension": "Using extension: {extensionName}", + "@optionsUsingExtension": { + "description": "Shows active extension name", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "optionsSwitchBack": "Tap Deezer or Spotify to switch back from extension", + "@optionsSwitchBack": { + "description": "Hint to switch back to built-in providers" + }, + "optionsAutoFallback": "Auto Fallback", + "@optionsAutoFallback": { + "description": "Auto-retry with other services" + }, + "optionsAutoFallbackSubtitle": "Try other services if download fails", + "@optionsAutoFallbackSubtitle": { + "description": "Subtitle for auto fallback" + }, + "optionsUseExtensionProviders": "Use Extension Providers", + "@optionsUseExtensionProviders": { + "description": "Enable extension download providers" + }, + "optionsUseExtensionProvidersOn": "Extensions will be tried first", + "@optionsUseExtensionProvidersOn": { + "description": "Status when extension providers enabled" + }, + "optionsUseExtensionProvidersOff": "Using built-in providers only", + "@optionsUseExtensionProvidersOff": { + "description": "Status when extension providers disabled" + }, + "optionsEmbedLyrics": "Embed Lyrics", + "@optionsEmbedLyrics": { + "description": "Embed lyrics in audio files" + }, + "optionsEmbedLyricsSubtitle": "Embed synced lyrics into FLAC files", + "@optionsEmbedLyricsSubtitle": { + "description": "Subtitle for embed lyrics" + }, + "optionsMaxQualityCover": "Max Quality Cover", + "@optionsMaxQualityCover": { + "description": "Download highest quality album art" + }, + "optionsMaxQualityCoverSubtitle": "Download highest resolution cover art", + "@optionsMaxQualityCoverSubtitle": { + "description": "Subtitle for max quality cover" + }, + "optionsConcurrentDownloads": "Concurrent Downloads", + "@optionsConcurrentDownloads": { + "description": "Number of parallel downloads" + }, + "optionsConcurrentSequential": "Sequential (1 at a time)", + "@optionsConcurrentSequential": { + "description": "Download one at a time" + }, + "optionsConcurrentParallel": "{count} parallel downloads", + "@optionsConcurrentParallel": { + "description": "Multiple parallel downloads", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", + "@optionsConcurrentWarning": { + "description": "Warning about rate limits" + }, + "optionsExtensionStore": "Extension Store", + "@optionsExtensionStore": { + "description": "Show/hide store tab" + }, + "optionsExtensionStoreSubtitle": "Show Store tab in navigation", + "@optionsExtensionStoreSubtitle": { + "description": "Subtitle for extension store toggle" + }, + "optionsCheckUpdates": "Check for Updates", + "@optionsCheckUpdates": { + "description": "Auto update check toggle" + }, + "optionsCheckUpdatesSubtitle": "Notify when new version is available", + "@optionsCheckUpdatesSubtitle": { + "description": "Subtitle for update check" + }, + "optionsUpdateChannel": "Update Channel", + "@optionsUpdateChannel": { + "description": "Stable vs preview releases" + }, + "optionsUpdateChannelStable": "Stable releases only", + "@optionsUpdateChannelStable": { + "description": "Only stable updates" + }, + "optionsUpdateChannelPreview": "Get preview releases", + "@optionsUpdateChannelPreview": { + "description": "Include beta/preview updates" + }, + "optionsUpdateChannelWarning": "Preview may contain bugs or incomplete features", + "@optionsUpdateChannelWarning": { + "description": "Warning about preview channel" + }, + "optionsClearHistory": "Clear Download History", + "@optionsClearHistory": { + "description": "Delete all download history" + }, + "optionsClearHistorySubtitle": "Remove all downloaded tracks from history", + "@optionsClearHistorySubtitle": { + "description": "Subtitle for clear history" + }, + "optionsDetailedLogging": "Detailed Logging", + "@optionsDetailedLogging": { + "description": "Enable verbose logs for debugging" + }, + "optionsDetailedLoggingOn": "Detailed logs are being recorded", + "@optionsDetailedLoggingOn": { + "description": "Status when logging enabled" + }, + "optionsDetailedLoggingOff": "Enable for bug reports", + "@optionsDetailedLoggingOff": { + "description": "Status when logging disabled" + }, + "optionsSpotifyCredentials": "Spotify Credentials", + "@optionsSpotifyCredentials": { + "description": "Spotify API credentials setting" + }, + "optionsSpotifyCredentialsConfigured": "Client ID: {clientId}...", + "@optionsSpotifyCredentialsConfigured": { + "description": "Shows configured client ID preview", + "placeholders": { + "clientId": { + "type": "String" + } + } + }, + "optionsSpotifyCredentialsRequired": "Required - tap to configure", + "@optionsSpotifyCredentialsRequired": { + "description": "Prompt to set up credentials" + }, + "optionsSpotifyWarning": "Spotify requires your own API credentials. Get them free from developer.spotify.com", + "@optionsSpotifyWarning": { + "description": "Info about Spotify API requirement" + }, + "extensionsTitle": "Extensions", + "@extensionsTitle": { + "description": "Extensions page title" + }, + "extensionsInstalled": "Installed Extensions", + "@extensionsInstalled": { + "description": "Section header for installed extensions" + }, + "extensionsNone": "No extensions installed", + "@extensionsNone": { + "description": "Empty state title" + }, + "extensionsNoneSubtitle": "Install extensions from the Store tab", + "@extensionsNoneSubtitle": { + "description": "Empty state subtitle" + }, + "extensionsEnabled": "Enabled", + "@extensionsEnabled": { + "description": "Extension status - active" + }, + "extensionsDisabled": "Disabled", + "@extensionsDisabled": { + "description": "Extension status - inactive" + }, + "extensionsVersion": "Version {version}", + "@extensionsVersion": { + "description": "Extension version display", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "extensionsAuthor": "by {author}", + "@extensionsAuthor": { + "description": "Extension author credit", + "placeholders": { + "author": { + "type": "String" + } + } + }, + "extensionsUninstall": "Uninstall", + "@extensionsUninstall": { + "description": "Uninstall extension button" + }, + "extensionsSetAsSearch": "Set as Search Provider", + "@extensionsSetAsSearch": { + "description": "Use extension for search" + }, + "storeTitle": "Extension Store", + "@storeTitle": { + "description": "Store screen title" + }, + "storeSearch": "Search extensions...", + "@storeSearch": { + "description": "Store search placeholder" + }, + "storeInstall": "Install", + "@storeInstall": { + "description": "Install extension button" + }, + "storeInstalled": "Installed", + "@storeInstalled": { + "description": "Already installed badge" + }, + "storeUpdate": "Update", + "@storeUpdate": { + "description": "Update available button" + }, + "aboutTitle": "About", + "@aboutTitle": { + "description": "About page title" + }, + "aboutContributors": "Contributors", + "@aboutContributors": { + "description": "Section for contributors" + }, + "aboutMobileDeveloper": "Mobile version developer", + "@aboutMobileDeveloper": { + "description": "Role description for mobile dev" + }, + "aboutOriginalCreator": "Creator of the original SpotiFLAC", + "@aboutOriginalCreator": { + "description": "Role description for original creator" + }, + "aboutLogoArtist": "The talented artist who created our beautiful app logo!", + "@aboutLogoArtist": { + "description": "Role description for logo artist" + }, + "aboutSpecialThanks": "Special Thanks", + "@aboutSpecialThanks": { + "description": "Section for special thanks" + }, + "aboutLinks": "Links", + "@aboutLinks": { + "description": "Section for external links" + }, + "aboutMobileSource": "Mobile source code", + "@aboutMobileSource": { + "description": "Link to mobile GitHub repo" + }, + "aboutPCSource": "PC source code", + "@aboutPCSource": { + "description": "Link to PC GitHub repo" + }, + "aboutReportIssue": "Report an issue", + "@aboutReportIssue": { + "description": "Link to report bugs" + }, + "aboutReportIssueSubtitle": "Report any problems you encounter", + "@aboutReportIssueSubtitle": { + "description": "Subtitle for report issue" + }, + "aboutFeatureRequest": "Feature request", + "@aboutFeatureRequest": { + "description": "Link to suggest features" + }, + "aboutFeatureRequestSubtitle": "Suggest new features for the app", + "@aboutFeatureRequestSubtitle": { + "description": "Subtitle for feature request" + }, + "aboutSupport": "Support", + "@aboutSupport": { + "description": "Section for support/donation links" + }, + "aboutBuyMeCoffee": "Buy me a coffee", + "@aboutBuyMeCoffee": { + "description": "Donation link" + }, + "aboutBuyMeCoffeeSubtitle": "Support development on Ko-fi", + "@aboutBuyMeCoffeeSubtitle": { + "description": "Subtitle for donation" + }, + "aboutApp": "App", + "@aboutApp": { + "description": "Section for app info" + }, + "aboutVersion": "Version", + "@aboutVersion": { + "description": "Version info label" + }, + "aboutBinimumDesc": "The creator of QQDL & HiFi API. Without this API, Tidal downloads wouldn't exist!", + "@aboutBinimumDesc": { + "description": "Credit description for binimum" + }, + "aboutSachinsenalDesc": "The original HiFi project creator. The foundation of Tidal integration!", + "@aboutSachinsenalDesc": { + "description": "Credit description for sachinsenal0x64" + }, + "aboutDoubleDouble": "DoubleDouble", + "@aboutDoubleDouble": { + "description": "Name of Amazon API service - DO NOT TRANSLATE" + }, + "aboutDoubleDoubleDesc": "Amazing API for Amazon Music downloads. Thank you for making it free!", + "@aboutDoubleDoubleDesc": { + "description": "Credit for DoubleDouble API" + }, + "aboutDabMusic": "DAB Music", + "@aboutDabMusic": { + "description": "Name of Qobuz API service - DO NOT TRANSLATE" + }, + "aboutDabMusicDesc": "The best Qobuz streaming API. Hi-Res downloads wouldn't be possible without this!", + "@aboutDabMusicDesc": { + "description": "Credit for DAB Music API" + }, + "aboutAppDescription": "Download Spotify tracks in lossless quality from Tidal, Qobuz, and Amazon Music.", + "@aboutAppDescription": { + "description": "App description in header card" + }, + "albumTitle": "Album", + "@albumTitle": { + "description": "Album screen title" + }, + "albumTracks": "{count, plural, =1{1 track} other{{count} tracks}}", + "@albumTracks": { + "description": "Album track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "albumDownloadAll": "Download All", + "@albumDownloadAll": { + "description": "Button to download all tracks" + }, + "albumDownloadRemaining": "Download Remaining", + "@albumDownloadRemaining": { + "description": "Button to download remaining tracks" + }, + "playlistTitle": "Playlist", + "@playlistTitle": { + "description": "Playlist screen title" + }, + "artistTitle": "Artist", + "@artistTitle": { + "description": "Artist screen title" + }, + "artistAlbums": "Albums", + "@artistAlbums": { + "description": "Section header for artist albums" + }, + "artistSingles": "Singles & EPs", + "@artistSingles": { + "description": "Section header for singles/EPs" + }, + "artistCompilations": "Compilations", + "@artistCompilations": { + "description": "Section header for compilations" + }, + "artistReleases": "{count, plural, =1{1 release} other{{count} releases}}", + "@artistReleases": { + "description": "Artist release count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "trackMetadataTitle": "Track Info", + "@trackMetadataTitle": { + "description": "Track metadata screen title" + }, + "trackMetadataArtist": "Artist", + "@trackMetadataArtist": { + "description": "Metadata field - artist name" + }, + "trackMetadataAlbum": "Album", + "@trackMetadataAlbum": { + "description": "Metadata field - album name" + }, + "trackMetadataDuration": "Duration", + "@trackMetadataDuration": { + "description": "Metadata field - track length" + }, + "trackMetadataQuality": "Quality", + "@trackMetadataQuality": { + "description": "Metadata field - audio quality" + }, + "trackMetadataPath": "File Path", + "@trackMetadataPath": { + "description": "Metadata field - file location" + }, + "trackMetadataDownloadedAt": "Downloaded", + "@trackMetadataDownloadedAt": { + "description": "Metadata field - download date" + }, + "trackMetadataService": "Service", + "@trackMetadataService": { + "description": "Metadata field - download service used" + }, + "trackMetadataPlay": "Play", + "@trackMetadataPlay": { + "description": "Action button - play track" + }, + "trackMetadataShare": "Share", + "@trackMetadataShare": { + "description": "Action button - share track" + }, + "trackMetadataDelete": "Delete", + "@trackMetadataDelete": { + "description": "Action button - delete track" + }, + "trackMetadataRedownload": "Re-download", + "@trackMetadataRedownload": { + "description": "Action button - download again" + }, + "trackMetadataOpenFolder": "Open Folder", + "@trackMetadataOpenFolder": { + "description": "Action button - open containing folder" + }, + "setupTitle": "Welcome to SpotiFLAC", + "@setupTitle": { + "description": "Setup wizard title" + }, + "setupSubtitle": "Let's get you started", + "@setupSubtitle": { + "description": "Setup wizard subtitle" + }, + "setupStoragePermission": "Storage Permission", + "@setupStoragePermission": { + "description": "Storage permission step title" + }, + "setupStoragePermissionSubtitle": "Required to save downloaded files", + "@setupStoragePermissionSubtitle": { + "description": "Explanation for storage permission" + }, + "setupStoragePermissionGranted": "Permission granted", + "@setupStoragePermissionGranted": { + "description": "Status when permission granted" + }, + "setupStoragePermissionDenied": "Permission denied", + "@setupStoragePermissionDenied": { + "description": "Status when permission denied" + }, + "setupGrantPermission": "Grant Permission", + "@setupGrantPermission": { + "description": "Button to request permission" + }, + "setupDownloadLocation": "Download Location", + "@setupDownloadLocation": { + "description": "Download folder step title" + }, + "setupChooseFolder": "Choose Folder", + "@setupChooseFolder": { + "description": "Button to pick folder" + }, + "setupContinue": "Continue", + "@setupContinue": { + "description": "Continue to next step button" + }, + "setupSkip": "Skip for now", + "@setupSkip": { + "description": "Skip current step button" + }, + "setupStorageAccessRequired": "Storage Access Required", + "@setupStorageAccessRequired": { + "description": "Title when storage access needed" + }, + "setupStorageAccessMessage": "SpotiFLAC needs \"All files access\" permission to save music files to your chosen folder.", + "@setupStorageAccessMessage": { + "description": "Explanation for storage access" + }, + "setupStorageAccessMessageAndroid11": "Android 11+ requires \"All files access\" permission to save files to your chosen download folder.", + "@setupStorageAccessMessageAndroid11": { + "description": "Android 11+ specific explanation" + }, + "setupOpenSettings": "Open Settings", + "@setupOpenSettings": { + "description": "Button to open system settings" + }, + "setupPermissionDeniedMessage": "Permission denied. Please grant all permissions to continue.", + "@setupPermissionDeniedMessage": { + "description": "Error when permission denied" + }, + "setupPermissionRequired": "{permissionType} Permission Required", + "@setupPermissionRequired": { + "description": "Generic permission required title", + "placeholders": { + "permissionType": { + "type": "String", + "description": "Type of permission (Storage/Notification)" + } + } + }, + "setupPermissionRequiredMessage": "{permissionType} permission is required for the best experience. You can change this later in Settings.", + "@setupPermissionRequiredMessage": { + "description": "Generic permission required message", + "placeholders": { + "permissionType": { + "type": "String" + } + } + }, + "setupSelectDownloadFolder": "Select Download Folder", + "@setupSelectDownloadFolder": { + "description": "Folder selection step title" + }, + "setupUseDefaultFolder": "Use Default Folder?", + "@setupUseDefaultFolder": { + "description": "Dialog title for default folder" + }, + "setupNoFolderSelected": "No folder selected. Would you like to use the default Music folder?", + "@setupNoFolderSelected": { + "description": "Prompt when no folder selected" + }, + "setupUseDefault": "Use Default", + "@setupUseDefault": { + "description": "Button to use default folder" + }, + "setupDownloadLocationTitle": "Download Location", + "@setupDownloadLocationTitle": { + "description": "Download location dialog title" + }, + "setupDownloadLocationIosMessage": "On iOS, downloads are saved to the app's Documents folder. You can access them via the Files app.", + "@setupDownloadLocationIosMessage": { + "description": "iOS-specific folder info" + }, + "setupAppDocumentsFolder": "App Documents Folder", + "@setupAppDocumentsFolder": { + "description": "iOS documents folder option" + }, + "setupAppDocumentsFolderSubtitle": "Recommended - accessible via Files app", + "@setupAppDocumentsFolderSubtitle": { + "description": "Subtitle for documents folder" + }, + "setupChooseFromFiles": "Choose from Files", + "@setupChooseFromFiles": { + "description": "iOS file picker option" + }, + "setupChooseFromFilesSubtitle": "Select iCloud or other location", + "@setupChooseFromFilesSubtitle": { + "description": "Subtitle for file picker" + }, + "setupIosEmptyFolderWarning": "iOS limitation: Empty folders cannot be selected. Choose a folder with at least one file.", + "@setupIosEmptyFolderWarning": { + "description": "iOS folder selection warning" + }, + "setupDownloadInFlac": "Download Spotify tracks in FLAC", + "@setupDownloadInFlac": { + "description": "App tagline in setup" + }, + "setupStepStorage": "Storage", + "@setupStepStorage": { + "description": "Setup step indicator - storage" + }, + "setupStepNotification": "Notification", + "@setupStepNotification": { + "description": "Setup step indicator - notification" + }, + "setupStepFolder": "Folder", + "@setupStepFolder": { + "description": "Setup step indicator - folder" + }, + "setupStepSpotify": "Spotify", + "@setupStepSpotify": { + "description": "Setup step indicator - Spotify API" + }, + "setupStepPermission": "Permission", + "@setupStepPermission": { + "description": "Setup step indicator - permission" + }, + "setupStorageGranted": "Storage Permission Granted!", + "@setupStorageGranted": { + "description": "Success message for storage permission" + }, + "setupStorageRequired": "Storage Permission Required", + "@setupStorageRequired": { + "description": "Title when storage permission needed" + }, + "setupStorageDescription": "SpotiFLAC needs storage permission to save your downloaded music files.", + "@setupStorageDescription": { + "description": "Explanation for storage permission" + }, + "setupNotificationGranted": "Notification Permission Granted!", + "@setupNotificationGranted": { + "description": "Success message for notification permission" + }, + "setupNotificationEnable": "Enable Notifications", + "@setupNotificationEnable": { + "description": "Button to enable notifications" + }, + "setupNotificationDescription": "Get notified when downloads complete or require attention.", + "@setupNotificationDescription": { + "description": "Explanation for notifications" + }, + "setupFolderSelected": "Download Folder Selected!", + "@setupFolderSelected": { + "description": "Success message for folder selection" + }, + "setupFolderChoose": "Choose Download Folder", + "@setupFolderChoose": { + "description": "Button to choose folder" + }, + "setupFolderDescription": "Select a folder where your downloaded music will be saved.", + "@setupFolderDescription": { + "description": "Explanation for folder selection" + }, + "setupChangeFolder": "Change Folder", + "@setupChangeFolder": { + "description": "Button to change selected folder" + }, + "setupSelectFolder": "Select Folder", + "@setupSelectFolder": { + "description": "Button to select folder" + }, + "setupSpotifyApiOptional": "Spotify API (Optional)", + "@setupSpotifyApiOptional": { + "description": "Spotify API step title" + }, + "setupSpotifyApiDescription": "Add your Spotify API credentials for better search results and access to Spotify-exclusive content.", + "@setupSpotifyApiDescription": { + "description": "Explanation for Spotify API" + }, + "setupUseSpotifyApi": "Use Spotify API", + "@setupUseSpotifyApi": { + "description": "Toggle to enable Spotify API" + }, + "setupEnterCredentialsBelow": "Enter your credentials below", + "@setupEnterCredentialsBelow": { + "description": "Prompt to enter credentials" + }, + "setupUsingDeezer": "Using Deezer (no account needed)", + "@setupUsingDeezer": { + "description": "Status when using Deezer" + }, + "setupEnterClientId": "Enter Spotify Client ID", + "@setupEnterClientId": { + "description": "Placeholder for client ID field" + }, + "setupEnterClientSecret": "Enter Spotify Client Secret", + "@setupEnterClientSecret": { + "description": "Placeholder for client secret field" + }, + "setupGetFreeCredentials": "Get your free API credentials from the Spotify Developer Dashboard.", + "@setupGetFreeCredentials": { + "description": "Info about getting Spotify credentials" + }, + "setupEnableNotifications": "Enable Notifications", + "@setupEnableNotifications": { + "description": "Button to enable notifications" + }, + "setupProceedToNextStep": "You can now proceed to the next step.", + "@setupProceedToNextStep": { + "description": "Message after completing a step" + }, + "setupNotificationProgressDescription": "You will receive download progress notifications.", + "@setupNotificationProgressDescription": { + "description": "Info about notification usage" + }, + "setupNotificationBackgroundDescription": "Get notified about download progress and completion. This helps you track downloads when the app is in background.", + "@setupNotificationBackgroundDescription": { + "description": "Detailed notification explanation" + }, + "setupSkipForNow": "Skip for now", + "@setupSkipForNow": { + "description": "Skip button text" + }, + "setupBack": "Back", + "@setupBack": { + "description": "Back button text" + }, + "setupNext": "Next", + "@setupNext": { + "description": "Next button text" + }, + "setupGetStarted": "Get Started", + "@setupGetStarted": { + "description": "Final setup button" + }, + "setupSkipAndStart": "Skip & Start", + "@setupSkipAndStart": { + "description": "Skip setup and start app" + }, + "setupAllowAccessToManageFiles": "Please enable \"Allow access to manage all files\" in the next screen.", + "@setupAllowAccessToManageFiles": { + "description": "Instruction for file access permission" + }, + "setupGetCredentialsFromSpotify": "Get credentials from developer.spotify.com", + "@setupGetCredentialsFromSpotify": { + "description": "Link text for Spotify developer portal" + }, + "dialogCancel": "Cancel", + "@dialogCancel": { + "description": "Dialog button - cancel action" + }, + "dialogOk": "OK", + "@dialogOk": { + "description": "Dialog button - confirm/acknowledge" + }, + "dialogSave": "Save", + "@dialogSave": { + "description": "Dialog button - save changes" + }, + "dialogDelete": "Delete", + "@dialogDelete": { + "description": "Dialog button - delete item" + }, + "dialogRetry": "Retry", + "@dialogRetry": { + "description": "Dialog button - retry action" + }, + "dialogClose": "Close", + "@dialogClose": { + "description": "Dialog button - close dialog" + }, + "dialogYes": "Yes", + "@dialogYes": { + "description": "Dialog button - confirm yes" + }, + "dialogNo": "No", + "@dialogNo": { + "description": "Dialog button - confirm no" + }, + "dialogClear": "Clear", + "@dialogClear": { + "description": "Dialog button - clear items" + }, + "dialogConfirm": "Confirm", + "@dialogConfirm": { + "description": "Dialog button - confirm action" + }, + "dialogDone": "Done", + "@dialogDone": { + "description": "Dialog button - action completed" + }, + "dialogImport": "Import", + "@dialogImport": { + "description": "Dialog button - import data" + }, + "dialogDiscard": "Discard", + "@dialogDiscard": { + "description": "Dialog button - discard changes" + }, + "dialogRemove": "Remove", + "@dialogRemove": { + "description": "Dialog button - remove item" + }, + "dialogUninstall": "Uninstall", + "@dialogUninstall": { + "description": "Dialog button - uninstall extension" + }, + "dialogDiscardChanges": "Discard Changes?", + "@dialogDiscardChanges": { + "description": "Dialog title - unsaved changes warning" + }, + "dialogUnsavedChanges": "You have unsaved changes. Do you want to discard them?", + "@dialogUnsavedChanges": { + "description": "Dialog message - unsaved changes" + }, + "dialogDownloadFailed": "Download Failed", + "@dialogDownloadFailed": { + "description": "Dialog title - download error" + }, + "dialogTrackLabel": "Track:", + "@dialogTrackLabel": { + "description": "Label for track name in error dialog" + }, + "dialogArtistLabel": "Artist:", + "@dialogArtistLabel": { + "description": "Label for artist name in error dialog" + }, + "dialogErrorLabel": "Error:", + "@dialogErrorLabel": { + "description": "Label for error message" + }, + "dialogClearAll": "Clear All", + "@dialogClearAll": { + "description": "Dialog title - clear all items" + }, + "dialogClearAllDownloads": "Are you sure you want to clear all downloads?", + "@dialogClearAllDownloads": { + "description": "Dialog message - clear downloads confirmation" + }, + "dialogRemoveFromDevice": "Remove from device?", + "@dialogRemoveFromDevice": { + "description": "Dialog title - delete file confirmation" + }, + "dialogRemoveExtension": "Remove Extension", + "@dialogRemoveExtension": { + "description": "Dialog title - uninstall extension" + }, + "dialogRemoveExtensionMessage": "Are you sure you want to remove this extension? This cannot be undone.", + "@dialogRemoveExtensionMessage": { + "description": "Dialog message - uninstall confirmation" + }, + "dialogUninstallExtension": "Uninstall Extension?", + "@dialogUninstallExtension": { + "description": "Dialog title - uninstall extension" + }, + "dialogUninstallExtensionMessage": "Are you sure you want to remove {extensionName}?", + "@dialogUninstallExtensionMessage": { + "description": "Dialog message - uninstall specific extension", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "dialogClearHistoryTitle": "Clear History", + "@dialogClearHistoryTitle": { + "description": "Dialog title - clear download history" + }, + "dialogClearHistoryMessage": "Are you sure you want to clear all download history? This cannot be undone.", + "@dialogClearHistoryMessage": { + "description": "Dialog message - clear history confirmation" + }, + "dialogDeleteSelectedTitle": "Delete Selected", + "@dialogDeleteSelectedTitle": { + "description": "Dialog title - delete selected items" + }, + "dialogDeleteSelectedMessage": "Delete {count} {count, plural, =1{track} other{tracks}} from history?\n\nThis will also delete the files from storage.", + "@dialogDeleteSelectedMessage": { + "description": "Dialog message - delete selected tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogImportPlaylistTitle": "Import Playlist", + "@dialogImportPlaylistTitle": { + "description": "Dialog title - import CSV playlist" + }, + "dialogImportPlaylistMessage": "Found {count} tracks in CSV. Add them to download queue?", + "@dialogImportPlaylistMessage": { + "description": "Dialog message - import playlist confirmation", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedToQueue": "Added \"{trackName}\" to queue", + "@snackbarAddedToQueue": { + "description": "Snackbar - track added to download queue", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "snackbarAddedTracksToQueue": "Added {count} tracks to queue", + "@snackbarAddedTracksToQueue": { + "description": "Snackbar - multiple tracks added to queue", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAlreadyDownloaded": "\"{trackName}\" already downloaded", + "@snackbarAlreadyDownloaded": { + "description": "Snackbar - track already exists", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "snackbarHistoryCleared": "History cleared", + "@snackbarHistoryCleared": { + "description": "Snackbar - history deleted" + }, + "snackbarCredentialsSaved": "Credentials saved", + "@snackbarCredentialsSaved": { + "description": "Snackbar - Spotify credentials saved" + }, + "snackbarCredentialsCleared": "Credentials cleared", + "@snackbarCredentialsCleared": { + "description": "Snackbar - Spotify credentials removed" + }, + "snackbarDeletedTracks": "Deleted {count} {count, plural, =1{track} other{tracks}}", + "@snackbarDeletedTracks": { + "description": "Snackbar - tracks deleted", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarCannotOpenFile": "Cannot open file: {error}", + "@snackbarCannotOpenFile": { + "description": "Snackbar - file open error", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarFillAllFields": "Please fill all fields", + "@snackbarFillAllFields": { + "description": "Snackbar - validation error" + }, + "snackbarViewQueue": "View Queue", + "@snackbarViewQueue": { + "description": "Snackbar action - view download queue" + }, + "snackbarFailedToLoad": "Failed to load: {error}", + "@snackbarFailedToLoad": { + "description": "Snackbar - loading error", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarUrlCopied": "{platform} URL copied to clipboard", + "@snackbarUrlCopied": { + "description": "Snackbar - URL copied", + "placeholders": { + "platform": { + "type": "String", + "description": "Platform name (Spotify/Deezer)" + } + } + }, + "snackbarFileNotFound": "File not found", + "@snackbarFileNotFound": { + "description": "Snackbar - file doesn't exist" + }, + "snackbarSelectExtFile": "Please select a .spotiflac-ext file", + "@snackbarSelectExtFile": { + "description": "Snackbar - wrong file type selected" + }, + "snackbarProviderPrioritySaved": "Provider priority saved", + "@snackbarProviderPrioritySaved": { + "description": "Snackbar - provider order saved" + }, + "snackbarMetadataProviderSaved": "Metadata provider priority saved", + "@snackbarMetadataProviderSaved": { + "description": "Snackbar - metadata provider order saved" + }, + "snackbarExtensionInstalled": "{extensionName} installed.", + "@snackbarExtensionInstalled": { + "description": "Snackbar - extension installed successfully", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "snackbarExtensionUpdated": "{extensionName} updated.", + "@snackbarExtensionUpdated": { + "description": "Snackbar - extension updated successfully", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "snackbarFailedToInstall": "Failed to install extension", + "@snackbarFailedToInstall": { + "description": "Snackbar - extension install error" + }, + "snackbarFailedToUpdate": "Failed to update extension", + "@snackbarFailedToUpdate": { + "description": "Snackbar - extension update error" + }, + "errorRateLimited": "Rate Limited", + "@errorRateLimited": { + "description": "Error title - too many requests" + }, + "errorRateLimitedMessage": "Too many requests. Please wait a moment before searching again.", + "@errorRateLimitedMessage": { + "description": "Error message - rate limit explanation" + }, + "errorFailedToLoad": "Failed to load {item}", + "@errorFailedToLoad": { + "description": "Error message - loading failed", + "placeholders": { + "item": { + "type": "String", + "description": "Item that failed to load (album/playlist/etc)" + } + } + }, + "errorNoTracksFound": "No tracks found", + "@errorNoTracksFound": { + "description": "Error - search returned no results" + }, + "errorMissingExtensionSource": "Cannot load {item}: missing extension source", + "@errorMissingExtensionSource": { + "description": "Error - extension source not available", + "placeholders": { + "item": { + "type": "String" + } + } + }, + "statusQueued": "Queued", + "@statusQueued": { + "description": "Download status - waiting in queue" + }, + "statusDownloading": "Downloading", + "@statusDownloading": { + "description": "Download status - in progress" + }, + "statusFinalizing": "Finalizing", + "@statusFinalizing": { + "description": "Download status - writing metadata" + }, + "statusCompleted": "Completed", + "@statusCompleted": { + "description": "Download status - finished" + }, + "statusFailed": "Failed", + "@statusFailed": { + "description": "Download status - error occurred" + }, + "statusSkipped": "Skipped", + "@statusSkipped": { + "description": "Download status - already exists" + }, + "statusPaused": "Paused", + "@statusPaused": { + "description": "Download status - paused" + }, + "actionPause": "Pause", + "@actionPause": { + "description": "Action button - pause download" + }, + "actionResume": "Resume", + "@actionResume": { + "description": "Action button - resume download" + }, + "actionCancel": "Cancel", + "@actionCancel": { + "description": "Action button - cancel operation" + }, + "actionStop": "Stop", + "@actionStop": { + "description": "Action button - stop operation" + }, + "actionSelect": "Select", + "@actionSelect": { + "description": "Action button - enter selection mode" + }, + "actionSelectAll": "Select All", + "@actionSelectAll": { + "description": "Action button - select all items" + }, + "actionDeselect": "Deselect", + "@actionDeselect": { + "description": "Action button - deselect all" + }, + "actionPaste": "Paste", + "@actionPaste": { + "description": "Action button - paste from clipboard" + }, + "actionImportCsv": "Import CSV", + "@actionImportCsv": { + "description": "Action button - import CSV file" + }, + "actionRemoveCredentials": "Remove Credentials", + "@actionRemoveCredentials": { + "description": "Action button - delete Spotify credentials" + }, + "actionSaveCredentials": "Save Credentials", + "@actionSaveCredentials": { + "description": "Action button - save Spotify credentials" + }, + "selectionSelected": "{count} selected", + "@selectionSelected": { + "description": "Selection count indicator", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "selectionAllSelected": "All tracks selected", + "@selectionAllSelected": { + "description": "Status - all items selected" + }, + "selectionTapToSelect": "Tap tracks to select", + "@selectionTapToSelect": { + "description": "Hint - how to select items" + }, + "selectionDeleteTracks": "Delete {count} {count, plural, =1{track} other{tracks}}", + "@selectionDeleteTracks": { + "description": "Delete button with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "selectionSelectToDelete": "Select tracks to delete", + "@selectionSelectToDelete": { + "description": "Placeholder when nothing selected" + }, + "progressFetchingMetadata": "Fetching metadata... {current}/{total}", + "@progressFetchingMetadata": { + "description": "Progress indicator - loading track info", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "progressReadingCsv": "Reading CSV...", + "@progressReadingCsv": { + "description": "Progress indicator - parsing CSV file" + }, + "searchSongs": "Songs", + "@searchSongs": { + "description": "Search result category - songs" + }, + "searchArtists": "Artists", + "@searchArtists": { + "description": "Search result category - artists" + }, + "searchAlbums": "Albums", + "@searchAlbums": { + "description": "Search result category - albums" + }, + "searchPlaylists": "Playlists", + "@searchPlaylists": { + "description": "Search result category - playlists" + }, + "tooltipPlay": "Play", + "@tooltipPlay": { + "description": "Tooltip - play button" + }, + "tooltipCancel": "Cancel", + "@tooltipCancel": { + "description": "Tooltip - cancel button" + }, + "tooltipStop": "Stop", + "@tooltipStop": { + "description": "Tooltip - stop button" + }, + "tooltipRetry": "Retry", + "@tooltipRetry": { + "description": "Tooltip - retry button" + }, + "tooltipRemove": "Remove", + "@tooltipRemove": { + "description": "Tooltip - remove button" + }, + "tooltipClear": "Clear", + "@tooltipClear": { + "description": "Tooltip - clear button" + }, + "tooltipPaste": "Paste", + "@tooltipPaste": { + "description": "Tooltip - paste button" + }, + "filenameFormat": "Filename Format", + "@filenameFormat": { + "description": "Setting title - filename pattern" + }, + "filenameFormatPreview": "Preview: {preview}", + "@filenameFormatPreview": { + "description": "Preview of filename pattern", + "placeholders": { + "preview": { + "type": "String" + } + } + }, + "filenameAvailablePlaceholders": "Available placeholders:", + "@filenameAvailablePlaceholders": { + "description": "Label for placeholder list" + }, + "filenameHint": "{artist} - {title}", + "@filenameHint": { + "description": "Default filename format hint" + }, + "folderOrganization": "Folder Organization", + "@folderOrganization": { + "description": "Setting title - folder structure" + }, + "folderOrganizationNone": "No organization", + "@folderOrganizationNone": { + "description": "Folder option - flat structure" + }, + "folderOrganizationByArtist": "By Artist", + "@folderOrganizationByArtist": { + "description": "Folder option - artist folders" + }, + "folderOrganizationByAlbum": "By Album", + "@folderOrganizationByAlbum": { + "description": "Folder option - album folders" + }, + "folderOrganizationByArtistAlbum": "Artist/Album", + "@folderOrganizationByArtistAlbum": { + "description": "Folder option - nested folders" + }, + "folderOrganizationDescription": "Organize downloaded files into folders", + "@folderOrganizationDescription": { + "description": "Folder organization sheet description" + }, + "folderOrganizationNoneSubtitle": "All files in download folder", + "@folderOrganizationNoneSubtitle": { + "description": "Subtitle for no organization option" + }, + "folderOrganizationByArtistSubtitle": "Separate folder for each artist", + "@folderOrganizationByArtistSubtitle": { + "description": "Subtitle for artist folder option" + }, + "folderOrganizationByAlbumSubtitle": "Separate folder for each album", + "@folderOrganizationByAlbumSubtitle": { + "description": "Subtitle for album folder option" + }, + "folderOrganizationByArtistAlbumSubtitle": "Nested folders for artist and album", + "@folderOrganizationByArtistAlbumSubtitle": { + "description": "Subtitle for nested folder option" + }, + "updateAvailable": "Update Available", + "@updateAvailable": { + "description": "Update dialog title" + }, + "updateNewVersion": "Version {version} is available", + "@updateNewVersion": { + "description": "Update available message", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "updateDownload": "Download", + "@updateDownload": { + "description": "Update button - download update" + }, + "updateLater": "Later", + "@updateLater": { + "description": "Update button - dismiss" + }, + "updateChangelog": "Changelog", + "@updateChangelog": { + "description": "Link to changelog" + }, + "updateStartingDownload": "Starting download...", + "@updateStartingDownload": { + "description": "Update status - initializing" + }, + "updateDownloadFailed": "Download failed", + "@updateDownloadFailed": { + "description": "Update error title" + }, + "updateFailedMessage": "Failed to download update", + "@updateFailedMessage": { + "description": "Update error message" + }, + "updateNewVersionReady": "A new version is ready", + "@updateNewVersionReady": { + "description": "Update subtitle" + }, + "updateCurrent": "Current", + "@updateCurrent": { + "description": "Label for current version" + }, + "updateNew": "New", + "@updateNew": { + "description": "Label for new version" + }, + "updateDownloading": "Downloading...", + "@updateDownloading": { + "description": "Update status - downloading" + }, + "updateWhatsNew": "What's New", + "@updateWhatsNew": { + "description": "Changelog section title" + }, + "updateDownloadInstall": "Download & Install", + "@updateDownloadInstall": { + "description": "Update button - download and install" + }, + "updateDontRemind": "Don't remind", + "@updateDontRemind": { + "description": "Update button - skip this version" + }, + "providerPriority": "Provider Priority", + "@providerPriority": { + "description": "Setting title - download provider order" + }, + "providerPrioritySubtitle": "Drag to reorder download providers", + "@providerPrioritySubtitle": { + "description": "Subtitle for provider priority" + }, + "providerPriorityTitle": "Provider Priority", + "@providerPriorityTitle": { + "description": "Provider priority page title" + }, + "providerPriorityDescription": "Drag to reorder download providers. The app will try providers from top to bottom when downloading tracks.", + "@providerPriorityDescription": { + "description": "Provider priority page description" + }, + "providerPriorityInfo": "If a track is not available on the first provider, the app will automatically try the next one.", + "@providerPriorityInfo": { + "description": "Info tip about fallback behavior" + }, + "providerBuiltIn": "Built-in", + "@providerBuiltIn": { + "description": "Label for built-in providers (Tidal/Qobuz/Amazon)" + }, + "providerExtension": "Extension", + "@providerExtension": { + "description": "Label for extension-provided providers" + }, + "metadataProviderPriority": "Metadata Provider Priority", + "@metadataProviderPriority": { + "description": "Setting title - metadata provider order" + }, + "metadataProviderPrioritySubtitle": "Order used when fetching track metadata", + "@metadataProviderPrioritySubtitle": { + "description": "Subtitle for metadata priority" + }, + "metadataProviderPriorityTitle": "Metadata Priority", + "@metadataProviderPriorityTitle": { + "description": "Metadata priority page title" + }, + "metadataProviderPriorityDescription": "Drag to reorder metadata providers. The app will try providers from top to bottom when searching for tracks and fetching metadata.", + "@metadataProviderPriorityDescription": { + "description": "Metadata priority page description" + }, + "metadataProviderPriorityInfo": "Deezer has no rate limits and is recommended as primary. Spotify may rate limit after many requests.", + "@metadataProviderPriorityInfo": { + "description": "Info tip about rate limits" + }, + "metadataNoRateLimits": "No rate limits", + "@metadataNoRateLimits": { + "description": "Deezer provider description" + }, + "metadataMayRateLimit": "May rate limit", + "@metadataMayRateLimit": { + "description": "Spotify provider description" + }, + "logTitle": "Logs", + "@logTitle": { + "description": "Logs screen title" + }, + "logCopy": "Copy Logs", + "@logCopy": { + "description": "Action - copy logs to clipboard" + }, + "logClear": "Clear Logs", + "@logClear": { + "description": "Action - delete all logs" + }, + "logShare": "Share Logs", + "@logShare": { + "description": "Action - share logs file" + }, + "logEmpty": "No logs yet", + "@logEmpty": { + "description": "Empty state title" + }, + "logCopied": "Logs copied to clipboard", + "@logCopied": { + "description": "Snackbar - logs copied" + }, + "logSearchHint": "Search logs...", + "@logSearchHint": { + "description": "Log search placeholder" + }, + "logFilterLevel": "Level", + "@logFilterLevel": { + "description": "Filter by log level" + }, + "logFilterSection": "Filter", + "@logFilterSection": { + "description": "Filter section title" + }, + "logShareLogs": "Share logs", + "@logShareLogs": { + "description": "Share button tooltip" + }, + "logClearLogs": "Clear logs", + "@logClearLogs": { + "description": "Clear button tooltip" + }, + "logClearLogsTitle": "Clear Logs", + "@logClearLogsTitle": { + "description": "Clear logs dialog title" + }, + "logClearLogsMessage": "Are you sure you want to clear all logs?", + "@logClearLogsMessage": { + "description": "Clear logs confirmation message" + }, + "logIspBlocking": "ISP BLOCKING DETECTED", + "@logIspBlocking": { + "description": "Error category - ISP blocking" + }, + "logRateLimited": "RATE LIMITED", + "@logRateLimited": { + "description": "Error category - rate limiting" + }, + "logNetworkError": "NETWORK ERROR", + "@logNetworkError": { + "description": "Error category - network issues" + }, + "logTrackNotFound": "TRACK NOT FOUND", + "@logTrackNotFound": { + "description": "Error category - missing tracks" + }, + "logFilterBySeverity": "Filter logs by severity", + "@logFilterBySeverity": { + "description": "Filter dialog title" + }, + "logNoLogsYet": "No logs yet", + "@logNoLogsYet": { + "description": "Empty state title" + }, + "logNoLogsYetSubtitle": "Logs will appear here as you use the app", + "@logNoLogsYetSubtitle": { + "description": "Empty state subtitle" + }, + "logIssueSummary": "Issue Summary", + "@logIssueSummary": { + "description": "Section header for error summary" + }, + "logIspBlockingDescription": "Your ISP may be blocking access to download services", + "@logIspBlockingDescription": { + "description": "ISP blocking explanation" + }, + "logIspBlockingSuggestion": "Try using a VPN or change DNS to 1.1.1.1 or 8.8.8.8", + "@logIspBlockingSuggestion": { + "description": "ISP blocking fix suggestion" + }, + "logRateLimitedDescription": "Too many requests to the service", + "@logRateLimitedDescription": { + "description": "Rate limit explanation" + }, + "logRateLimitedSuggestion": "Wait a few minutes before trying again", + "@logRateLimitedSuggestion": { + "description": "Rate limit fix suggestion" + }, + "logNetworkErrorDescription": "Connection issues detected", + "@logNetworkErrorDescription": { + "description": "Network error explanation" + }, + "logNetworkErrorSuggestion": "Check your internet connection", + "@logNetworkErrorSuggestion": { + "description": "Network error fix suggestion" + }, + "logTrackNotFoundDescription": "Some tracks could not be found on download services", + "@logTrackNotFoundDescription": { + "description": "Track not found explanation" + }, + "logTrackNotFoundSuggestion": "The track may not be available in lossless quality", + "@logTrackNotFoundSuggestion": { + "description": "Track not found explanation" + }, + "logTotalErrors": "Total errors: {count}", + "@logTotalErrors": { + "description": "Error count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "logAffected": "Affected: {domains}", + "@logAffected": { + "description": "Affected domains display", + "placeholders": { + "domains": { + "type": "String" + } + } + }, + "logEntriesFiltered": "Entries ({count} filtered)", + "@logEntriesFiltered": { + "description": "Log count with filter active", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "logEntries": "Entries ({count})", + "@logEntries": { + "description": "Total log count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "credentialsTitle": "Spotify Credentials", + "@credentialsTitle": { + "description": "Credentials dialog title" + }, + "credentialsDescription": "Enter your Client ID and Secret to use your own Spotify application quota.", + "@credentialsDescription": { + "description": "Credentials dialog explanation" + }, + "credentialsClientId": "Client ID", + "@credentialsClientId": { + "description": "Client ID field label - DO NOT TRANSLATE" + }, + "credentialsClientIdHint": "Paste Client ID", + "@credentialsClientIdHint": { + "description": "Client ID placeholder" + }, + "credentialsClientSecret": "Client Secret", + "@credentialsClientSecret": { + "description": "Client Secret field label - DO NOT TRANSLATE" + }, + "credentialsClientSecretHint": "Paste Client Secret", + "@credentialsClientSecretHint": { + "description": "Client Secret placeholder" + }, + "channelStable": "Stable", + "@channelStable": { + "description": "Update channel - stable releases" + }, + "channelPreview": "Preview", + "@channelPreview": { + "description": "Update channel - beta/preview releases" + }, + "sectionSearchSource": "Search Source", + "@sectionSearchSource": { + "description": "Settings section header" + }, + "sectionDownload": "Download", + "@sectionDownload": { + "description": "Settings section header" + }, + "sectionPerformance": "Performance", + "@sectionPerformance": { + "description": "Settings section header" + }, + "sectionApp": "App", + "@sectionApp": { + "description": "Settings section header" + }, + "sectionData": "Data", + "@sectionData": { + "description": "Settings section header" + }, + "sectionDebug": "Debug", + "@sectionDebug": { + "description": "Settings section header" + }, + "sectionService": "Service", + "@sectionService": { + "description": "Settings section header" + }, + "sectionAudioQuality": "Audio Quality", + "@sectionAudioQuality": { + "description": "Settings section header" + }, + "sectionFileSettings": "File Settings", + "@sectionFileSettings": { + "description": "Settings section header" + }, + "sectionColor": "Color", + "@sectionColor": { + "description": "Settings section header" + }, + "sectionTheme": "Theme", + "@sectionTheme": { + "description": "Settings section header" + }, + "sectionLayout": "Layout", + "@sectionLayout": { + "description": "Settings section header" + }, + "sectionLanguage": "Language", + "@sectionLanguage": { + "description": "Settings section header for language selection" + }, + "appearanceLanguage": "App Language", + "@appearanceLanguage": { + "description": "Setting title for language selection" + }, + "appearanceLanguageSubtitle": "Choose your preferred language", + "@appearanceLanguageSubtitle": { + "description": "Subtitle for language setting" + }, + "languageSystem": "System Default", + "@languageSystem": { + "description": "Use device system language" + }, + "languageEnglish": "English", + "@languageEnglish": { + "description": "English language option" + }, + "languageIndonesian": "Bahasa Indonesia", + "@languageIndonesian": { + "description": "Indonesian language option" + }, + "settingsAppearanceSubtitle": "Theme, colors, display", + "@settingsAppearanceSubtitle": { + "description": "Appearance settings description" + }, + "settingsDownloadSubtitle": "Service, quality, filename format", + "@settingsDownloadSubtitle": { + "description": "Download settings description" + }, + "settingsOptionsSubtitle": "Fallback, lyrics, cover art, updates", + "@settingsOptionsSubtitle": { + "description": "Options settings description" + }, + "settingsExtensionsSubtitle": "Manage download providers", + "@settingsExtensionsSubtitle": { + "description": "Extensions settings description" + }, + "settingsLogsSubtitle": "View app logs for debugging", + "@settingsLogsSubtitle": { + "description": "Logs settings description" + }, + "loadingSharedLink": "Loading shared link...", + "@loadingSharedLink": { + "description": "Status when opening shared URL" + }, + "pressBackAgainToExit": "Press back again to exit", + "@pressBackAgainToExit": { + "description": "Exit confirmation message" + }, + "tracksHeader": "Tracks", + "@tracksHeader": { + "description": "Section header for track list" + }, + "downloadAllCount": "Download All ({count})", + "@downloadAllCount": { + "description": "Download all button with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "tracksCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@tracksCount": { + "description": "Track count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "trackCopyFilePath": "Copy file path", + "@trackCopyFilePath": { + "description": "Action - copy file path" + }, + "trackRemoveFromDevice": "Remove from device", + "@trackRemoveFromDevice": { + "description": "Action - delete downloaded file" + }, + "trackLoadLyrics": "Load Lyrics", + "@trackLoadLyrics": { + "description": "Action - fetch lyrics" + }, + "trackMetadata": "Metadata", + "@trackMetadata": { + "description": "Tab title - track metadata" + }, + "trackFileInfo": "File Info", + "@trackFileInfo": { + "description": "Tab title - file information" + }, + "trackLyrics": "Lyrics", + "@trackLyrics": { + "description": "Tab title - lyrics" + }, + "trackFileNotFound": "File not found", + "@trackFileNotFound": { + "description": "Error - file doesn't exist" + }, + "trackOpenInDeezer": "Open in Deezer", + "@trackOpenInDeezer": { + "description": "Action - open track in Deezer app" + }, + "trackOpenInSpotify": "Open in Spotify", + "@trackOpenInSpotify": { + "description": "Action - open track in Spotify app" + }, + "trackTrackName": "Track name", + "@trackTrackName": { + "description": "Metadata label - track title" + }, + "trackArtist": "Artist", + "@trackArtist": { + "description": "Metadata label - artist name" + }, + "trackAlbumArtist": "Album artist", + "@trackAlbumArtist": { + "description": "Metadata label - album artist" + }, + "trackAlbum": "Album", + "@trackAlbum": { + "description": "Metadata label - album name" + }, + "trackTrackNumber": "Track number", + "@trackTrackNumber": { + "description": "Metadata label - track number" + }, + "trackDiscNumber": "Disc number", + "@trackDiscNumber": { + "description": "Metadata label - disc number" + }, + "trackDuration": "Duration", + "@trackDuration": { + "description": "Metadata label - track length" + }, + "trackAudioQuality": "Audio quality", + "@trackAudioQuality": { + "description": "Metadata label - audio quality" + }, + "trackReleaseDate": "Release date", + "@trackReleaseDate": { + "description": "Metadata label - release date" + }, + "trackDownloaded": "Downloaded", + "@trackDownloaded": { + "description": "Metadata label - download date" + }, + "trackCopyLyrics": "Copy lyrics", + "@trackCopyLyrics": { + "description": "Action - copy lyrics to clipboard" + }, + "trackLyricsNotAvailable": "Lyrics not available for this track", + "@trackLyricsNotAvailable": { + "description": "Message when lyrics not found" + }, + "trackLyricsTimeout": "Request timed out. Try again later.", + "@trackLyricsTimeout": { + "description": "Message when lyrics request times out" + }, + "trackLyricsLoadFailed": "Failed to load lyrics", + "@trackLyricsLoadFailed": { + "description": "Message when lyrics loading fails" + }, + "trackCopiedToClipboard": "Copied to clipboard", + "@trackCopiedToClipboard": { + "description": "Snackbar - content copied" + }, + "trackDeleteConfirmTitle": "Remove from device?", + "@trackDeleteConfirmTitle": { + "description": "Delete confirmation title" + }, + "trackDeleteConfirmMessage": "This will permanently delete the downloaded file and remove it from your history.", + "@trackDeleteConfirmMessage": { + "description": "Delete confirmation message" + }, + "trackCannotOpen": "Cannot open: {message}", + "@trackCannotOpen": { + "description": "Error opening file", + "placeholders": { + "message": { + "type": "String" + } + } + }, + "dateToday": "Today", + "@dateToday": { + "description": "Relative date - today" + }, + "dateYesterday": "Yesterday", + "@dateYesterday": { + "description": "Relative date - yesterday" + }, + "dateDaysAgo": "{count} days ago", + "@dateDaysAgo": { + "description": "Relative date - days ago", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dateWeeksAgo": "{count} weeks ago", + "@dateWeeksAgo": { + "description": "Relative date - weeks ago", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dateMonthsAgo": "{count} months ago", + "@dateMonthsAgo": { + "description": "Relative date - months ago", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "concurrentSequential": "Sequential", + "@concurrentSequential": { + "description": "Download mode - one at a time" + }, + "concurrentParallel2": "2 Parallel", + "@concurrentParallel2": { + "description": "Download mode - 2 simultaneous" + }, + "concurrentParallel3": "3 Parallel", + "@concurrentParallel3": { + "description": "Download mode - 3 simultaneous" + }, + "tapToSeeError": "Tap to see error details", + "@tapToSeeError": { + "description": "Tooltip for failed download" + }, + "storeFilterAll": "All", + "@storeFilterAll": { + "description": "Store filter - all extensions" + }, + "storeFilterMetadata": "Metadata", + "@storeFilterMetadata": { + "description": "Store filter - metadata providers" + }, + "storeFilterDownload": "Download", + "@storeFilterDownload": { + "description": "Store filter - download providers" + }, + "storeFilterUtility": "Utility", + "@storeFilterUtility": { + "description": "Store filter - utility extensions" + }, + "storeFilterLyrics": "Lyrics", + "@storeFilterLyrics": { + "description": "Store filter - lyrics providers" + }, + "storeFilterIntegration": "Integration", + "@storeFilterIntegration": { + "description": "Store filter - integrations" + }, + "storeClearFilters": "Clear filters", + "@storeClearFilters": { + "description": "Button to clear all filters" + }, + "storeNoResults": "No extensions found", + "@storeNoResults": { + "description": "Empty state when no extensions match filters" + }, + "extensionProviderPriority": "Provider Priority", + "@extensionProviderPriority": { + "description": "Extension capability - provider priority" + }, + "extensionInstallButton": "Install Extension", + "@extensionInstallButton": { + "description": "Button to install extension" + }, + "extensionDefaultProvider": "Default (Deezer/Spotify)", + "@extensionDefaultProvider": { + "description": "Default search provider option" + }, + "extensionDefaultProviderSubtitle": "Use built-in search", + "@extensionDefaultProviderSubtitle": { + "description": "Subtitle for default provider" + }, + "extensionAuthor": "Author", + "@extensionAuthor": { + "description": "Extension detail - author" + }, + "extensionId": "ID", + "@extensionId": { + "description": "Extension detail - unique ID" + }, + "extensionError": "Error", + "@extensionError": { + "description": "Extension detail - error message" + }, + "extensionCapabilities": "Capabilities", + "@extensionCapabilities": { + "description": "Section header - extension features" + }, + "extensionMetadataProvider": "Metadata Provider", + "@extensionMetadataProvider": { + "description": "Capability - provides metadata" + }, + "extensionDownloadProvider": "Download Provider", + "@extensionDownloadProvider": { + "description": "Capability - provides downloads" + }, + "extensionLyricsProvider": "Lyrics Provider", + "@extensionLyricsProvider": { + "description": "Capability - provides lyrics" + }, + "extensionUrlHandler": "URL Handler", + "@extensionUrlHandler": { + "description": "Capability - handles URLs" + }, + "extensionQualityOptions": "Quality Options", + "@extensionQualityOptions": { + "description": "Capability - quality selection" + }, + "extensionPostProcessingHooks": "Post-Processing Hooks", + "@extensionPostProcessingHooks": { + "description": "Capability - post-processing" + }, + "extensionPermissions": "Permissions", + "@extensionPermissions": { + "description": "Section header - required permissions" + }, + "extensionSettings": "Settings", + "@extensionSettings": { + "description": "Section header - extension settings" + }, + "extensionRemoveButton": "Remove Extension", + "@extensionRemoveButton": { + "description": "Button to uninstall extension" + }, + "extensionUpdated": "Updated", + "@extensionUpdated": { + "description": "Extension detail - last update" + }, + "extensionMinAppVersion": "Min App Version", + "@extensionMinAppVersion": { + "description": "Extension detail - minimum app version" + }, + "extensionCustomTrackMatching": "Custom Track Matching", + "@extensionCustomTrackMatching": { + "description": "Capability - custom track matching algorithm" + }, + "extensionPostProcessing": "Post-Processing", + "@extensionPostProcessing": { + "description": "Capability - post-download processing" + }, + "extensionHooksAvailable": "{count} hook(s) available", + "@extensionHooksAvailable": { + "description": "Post-processing hooks count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "extensionPatternsCount": "{count} pattern(s)", + "@extensionPatternsCount": { + "description": "URL patterns count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "extensionStrategy": "Strategy: {strategy}", + "@extensionStrategy": { + "description": "Track matching strategy name", + "placeholders": { + "strategy": { + "type": "String" + } + } + }, + "extensionsProviderPrioritySection": "Provider Priority", + "@extensionsProviderPrioritySection": { + "description": "Section header - provider priority" + }, + "extensionsInstalledSection": "Installed Extensions", + "@extensionsInstalledSection": { + "description": "Section header - installed extensions" + }, + "extensionsNoExtensions": "No extensions installed", + "@extensionsNoExtensions": { + "description": "Empty state - no extensions" + }, + "extensionsNoExtensionsSubtitle": "Install .spotiflac-ext files to add new providers", + "@extensionsNoExtensionsSubtitle": { + "description": "Empty state subtitle" + }, + "extensionsInstallButton": "Install Extension", + "@extensionsInstallButton": { + "description": "Button to install extension from file" + }, + "extensionsInfoTip": "Extensions can add new metadata and download providers. Only install extensions from trusted sources.", + "@extensionsInfoTip": { + "description": "Security warning about extensions" + }, + "extensionsInstalledSuccess": "Extension installed successfully", + "@extensionsInstalledSuccess": { + "description": "Success message after install" + }, + "extensionsDownloadPriority": "Download Priority", + "@extensionsDownloadPriority": { + "description": "Setting - download provider order" + }, + "extensionsDownloadPrioritySubtitle": "Set download service order", + "@extensionsDownloadPrioritySubtitle": { + "description": "Subtitle for download priority" + }, + "extensionsNoDownloadProvider": "No extensions with download provider", + "@extensionsNoDownloadProvider": { + "description": "Empty state - no download providers" + }, + "extensionsMetadataPriority": "Metadata Priority", + "@extensionsMetadataPriority": { + "description": "Setting - metadata provider order" + }, + "extensionsMetadataPrioritySubtitle": "Set search & metadata source order", + "@extensionsMetadataPrioritySubtitle": { + "description": "Subtitle for metadata priority" + }, + "extensionsNoMetadataProvider": "No extensions with metadata provider", + "@extensionsNoMetadataProvider": { + "description": "Empty state - no metadata providers" + }, + "extensionsSearchProvider": "Search Provider", + "@extensionsSearchProvider": { + "description": "Setting - search provider selection" + }, + "extensionsNoCustomSearch": "No extensions with custom search", + "@extensionsNoCustomSearch": { + "description": "Empty state - no search providers" + }, + "extensionsSearchProviderDescription": "Choose which service to use for searching tracks", + "@extensionsSearchProviderDescription": { + "description": "Search provider setting description" + }, + "extensionsCustomSearch": "Custom search", + "@extensionsCustomSearch": { + "description": "Label for custom search provider" + }, + "extensionsErrorLoading": "Error loading extension", + "@extensionsErrorLoading": { + "description": "Error message when extension fails to load" + }, + "qualityFlacLossless": "FLAC Lossless", + "@qualityFlacLossless": { + "description": "Quality option - CD quality FLAC" + }, + "qualityFlacLosslessSubtitle": "16-bit / 44.1kHz", + "@qualityFlacLosslessSubtitle": { + "description": "Technical spec for lossless" + }, + "qualityHiResFlac": "Hi-Res FLAC", + "@qualityHiResFlac": { + "description": "Quality option - high resolution FLAC" + }, + "qualityHiResFlacSubtitle": "24-bit / up to 96kHz", + "@qualityHiResFlacSubtitle": { + "description": "Technical spec for hi-res" + }, + "qualityHiResFlacMax": "Hi-Res FLAC Max", + "@qualityHiResFlacMax": { + "description": "Quality option - maximum resolution FLAC" + }, + "qualityHiResFlacMaxSubtitle": "24-bit / up to 192kHz", + "@qualityHiResFlacMaxSubtitle": { + "description": "Technical spec for hi-res max" + }, + "qualityNote": "Actual quality depends on track availability from the service", + "@qualityNote": { + "description": "Note about quality availability" + }, + "downloadAskBeforeDownload": "Ask Before Download", + "@downloadAskBeforeDownload": { + "description": "Setting - show quality picker" + }, + "downloadDirectory": "Download Directory", + "@downloadDirectory": { + "description": "Setting - download folder" + }, + "downloadSeparateSinglesFolder": "Separate Singles Folder", + "@downloadSeparateSinglesFolder": { + "description": "Setting - separate folder for singles" + }, + "downloadAlbumFolderStructure": "Album Folder Structure", + "@downloadAlbumFolderStructure": { + "description": "Setting - album folder organization" + }, + "downloadSaveFormat": "Save Format", + "@downloadSaveFormat": { + "description": "Setting - output file format" + }, + "downloadSelectService": "Select Service", + "@downloadSelectService": { + "description": "Dialog title - choose download service" + }, + "downloadSelectQuality": "Select Quality", + "@downloadSelectQuality": { + "description": "Dialog title - choose audio quality" + }, + "downloadFrom": "Download From", + "@downloadFrom": { + "description": "Label - download source" + }, + "downloadDefaultQualityLabel": "Default Quality", + "@downloadDefaultQualityLabel": { + "description": "Label - default quality setting" + }, + "downloadBestAvailable": "Best available", + "@downloadBestAvailable": { + "description": "Quality option - highest available" + }, + "folderNone": "None", + "@folderNone": { + "description": "Folder option - no organization" + }, + "folderNoneSubtitle": "Save all files directly to download folder", + "@folderNoneSubtitle": { + "description": "Subtitle for no folder organization" + }, + "folderArtist": "Artist", + "@folderArtist": { + "description": "Folder option - by artist" + }, + "folderArtistSubtitle": "Artist Name/filename", + "@folderArtistSubtitle": { + "description": "Folder structure example" + }, + "folderAlbum": "Album", + "@folderAlbum": { + "description": "Folder option - by album" + }, + "folderAlbumSubtitle": "Album Name/filename", + "@folderAlbumSubtitle": { + "description": "Folder structure example" + }, + "folderArtistAlbum": "Artist/Album", + "@folderArtistAlbum": { + "description": "Folder option - nested" + }, + "folderArtistAlbumSubtitle": "Artist Name/Album Name/filename", + "@folderArtistAlbumSubtitle": { + "description": "Folder structure example" + }, + "serviceTidal": "Tidal", + "@serviceTidal": { + "description": "Service name - DO NOT TRANSLATE" + }, + "serviceQobuz": "Qobuz", + "@serviceQobuz": { + "description": "Service name - DO NOT TRANSLATE" + }, + "serviceAmazon": "Amazon", + "@serviceAmazon": { + "description": "Service name - DO NOT TRANSLATE" + }, + "serviceDeezer": "Deezer", + "@serviceDeezer": { + "description": "Service name - DO NOT TRANSLATE" + }, + "serviceSpotify": "Spotify", + "@serviceSpotify": { + "description": "Service name - DO NOT TRANSLATE" + }, + "appearanceAmoledDark": "AMOLED Dark", + "@appearanceAmoledDark": { + "description": "Theme option - pure black" + }, + "appearanceAmoledDarkSubtitle": "Pure black background", + "@appearanceAmoledDarkSubtitle": { + "description": "Subtitle for AMOLED dark" + }, + "appearanceChooseAccentColor": "Choose Accent Color", + "@appearanceChooseAccentColor": { + "description": "Color picker dialog title" + }, + "appearanceChooseTheme": "Theme Mode", + "@appearanceChooseTheme": { + "description": "Theme picker dialog title" + }, + "queueTitle": "Download Queue", + "@queueTitle": { + "description": "Queue screen title" + }, + "queueClearAll": "Clear All", + "@queueClearAll": { + "description": "Button - clear all queue items" + }, + "queueClearAllMessage": "Are you sure you want to clear all downloads?", + "@queueClearAllMessage": { + "description": "Clear queue confirmation" + }, + "queueEmpty": "No downloads in queue", + "@queueEmpty": { + "description": "Empty queue state title" + }, + "queueEmptySubtitle": "Add tracks from the home screen", + "@queueEmptySubtitle": { + "description": "Empty queue state subtitle" + }, + "queueClearCompleted": "Clear completed", + "@queueClearCompleted": { + "description": "Button - clear finished downloads" + }, + "queueDownloadFailed": "Download Failed", + "@queueDownloadFailed": { + "description": "Error dialog title" + }, + "queueTrackLabel": "Track:", + "@queueTrackLabel": { + "description": "Label in error dialog" + }, + "queueArtistLabel": "Artist:", + "@queueArtistLabel": { + "description": "Label in error dialog" + }, + "queueErrorLabel": "Error:", + "@queueErrorLabel": { + "description": "Label in error dialog" + }, + "queueUnknownError": "Unknown error", + "@queueUnknownError": { + "description": "Fallback error message" + }, + "albumFolderArtistAlbum": "Artist / Album", + "@albumFolderArtistAlbum": { + "description": "Album folder option" + }, + "albumFolderArtistAlbumSubtitle": "Albums/Artist Name/Album Name/", + "@albumFolderArtistAlbumSubtitle": { + "description": "Folder structure example" + }, + "albumFolderArtistYearAlbum": "Artist / [Year] Album", + "@albumFolderArtistYearAlbum": { + "description": "Album folder option with year" + }, + "albumFolderArtistYearAlbumSubtitle": "Albums/Artist Name/[2005] Album Name/", + "@albumFolderArtistYearAlbumSubtitle": { + "description": "Folder structure example" + }, + "albumFolderAlbumOnly": "Album Only", + "@albumFolderAlbumOnly": { + "description": "Album folder option" + }, + "albumFolderAlbumOnlySubtitle": "Albums/Album Name/", + "@albumFolderAlbumOnlySubtitle": { + "description": "Folder structure example" + }, + "albumFolderYearAlbum": "[Year] Album", + "@albumFolderYearAlbum": { + "description": "Album folder option with year" + }, + "albumFolderYearAlbumSubtitle": "Albums/[2005] Album Name/", + "@albumFolderYearAlbumSubtitle": { + "description": "Folder structure example" + }, + "downloadedAlbumDeleteSelected": "Delete Selected", + "@downloadedAlbumDeleteSelected": { + "description": "Button - delete selected tracks" + }, + "downloadedAlbumDeleteMessage": "Delete {count} {count, plural, =1{track} other{tracks}} from this album?\n\nThis will also delete the files from storage.", + "@downloadedAlbumDeleteMessage": { + "description": "Delete confirmation with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "downloadedAlbumTracksHeader": "Tracks", + "@downloadedAlbumTracksHeader": { + "description": "Section header for tracks" + }, + "downloadedAlbumDownloadedCount": "{count} downloaded", + "@downloadedAlbumDownloadedCount": { + "description": "Downloaded tracks count badge", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "downloadedAlbumSelectedCount": "{count} selected", + "@downloadedAlbumSelectedCount": { + "description": "Selection count indicator", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "downloadedAlbumAllSelected": "All tracks selected", + "@downloadedAlbumAllSelected": { + "description": "Status - all items selected" + }, + "downloadedAlbumTapToSelect": "Tap tracks to select", + "@downloadedAlbumTapToSelect": { + "description": "Selection hint" + }, + "downloadedAlbumDeleteCount": "Delete {count} {count, plural, =1{track} other{tracks}}", + "@downloadedAlbumDeleteCount": { + "description": "Delete button text with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "downloadedAlbumSelectToDelete": "Select tracks to delete", + "@downloadedAlbumSelectToDelete": { + "description": "Placeholder when nothing selected" + }, + "utilityFunctions": "Utility Functions", + "@utilityFunctions": { + "description": "Extension capability - utility functions" + } +} \ No newline at end of file