diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 88f2981..71a29c0 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -21,13 +21,13 @@ class AppLocalizationsDe extends AppLocalizations { String get navSettings => 'Einstellungen'; @override - String get navStore => 'Store'; + String get navStore => 'Repo'; @override String get homeTitle => 'Startseite'; @override - String get homeSubtitle => 'Spotify-Link einfügen oder nach Namen suchen'; + String get homeSubtitle => 'Unterstützte URL einfügen oder nach Namen suchen'; @override String get homeSupports => @@ -184,21 +184,21 @@ class AppLocalizationsDe extends AppLocalizations { 'Disabled: no loudness normalization tags'; @override - String get optionsArtistTagMode => 'Artist Tag Mode'; + String get optionsArtistTagMode => 'Künstler Tag-Modus'; @override String get optionsArtistTagModeDescription => - 'Choose how multiple artists are written into embedded tags.'; + 'Wähle aus, wie mehrere Künstler in eingebetteten Tags geschrieben sind.'; @override - String get optionsArtistTagModeJoined => 'Single joined value'; + String get optionsArtistTagModeJoined => 'Einzelne beigefügte Werte'; @override String get optionsArtistTagModeJoinedSubtitle => - 'Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.'; + 'Einen Künstler wert wie \"Artist A, Artist B\" für maximale Spieler-Kompatibilität schreiben.'; @override - String get optionsArtistTagModeSplitVorbis => 'Split tags for FLAC/Opus'; + String get optionsArtistTagModeSplitVorbis => 'Tags für FLAC/Opus aufteilen'; @override String get optionsArtistTagModeSplitVorbisSubtitle => @@ -220,11 +220,11 @@ class AppLocalizationsDe extends AppLocalizations { 'Parallele Downloads können Ratenlimitierung auslösen'; @override - String get optionsExtensionStore => 'Erweiterungs-Store'; + String get optionsExtensionStore => 'Erweiterungs-Repo'; @override String get optionsExtensionStoreSubtitle => - 'Store-Tab in Navigation anzeigen'; + 'Repo-Tab in der Navigation anzeigen'; @override String get optionsCheckUpdates => 'Nach Updates suchen'; @@ -303,7 +303,7 @@ class AppLocalizationsDe extends AppLocalizations { String get extensionsUninstall => 'Deinstallieren'; @override - String get storeTitle => 'Erweiterungs-Store'; + String get storeTitle => 'Erweiterungs-Repo'; @override String get storeSearch => 'Erweiterungen suchen...'; @@ -586,7 +586,7 @@ class AppLocalizationsDe extends AppLocalizations { String get dialogImport => 'Importieren'; @override - String get dialogDownload => 'Download'; + String get dialogDownload => 'Herunterladen'; @override String get dialogDiscard => 'Verwerfen'; @@ -819,37 +819,37 @@ class AppLocalizationsDe extends AppLocalizations { String get searchAlbums => 'Alben'; @override - String get searchPlaylists => 'Playlisten'; + String get searchPlaylists => 'Playlists'; @override - String get searchSortTitle => 'Sort Results'; + String get searchSortTitle => 'Ergebnisse sortieren'; @override - String get searchSortDefault => 'Default'; + String get searchSortDefault => 'Standard'; @override - String get searchSortTitleAZ => 'Title (A-Z)'; + String get searchSortTitleAZ => 'Titel (A-Z)'; @override - String get searchSortTitleZA => 'Title (Z-A)'; + String get searchSortTitleZA => 'Titel (Z-A)'; @override - String get searchSortArtistAZ => 'Artist (A-Z)'; + String get searchSortArtistAZ => 'Künstler (A-Z)'; @override - String get searchSortArtistZA => 'Artist (Z-A)'; + String get searchSortArtistZA => 'Künstler (Z-A)'; @override - String get searchSortDurationShort => 'Duration (Shortest)'; + String get searchSortDurationShort => 'Dauer (kürzeste)'; @override - String get searchSortDurationLong => 'Duration (Longest)'; + String get searchSortDurationLong => 'Dauer (längste)'; @override - String get searchSortDateOldest => 'Release Date (Oldest)'; + String get searchSortDateOldest => 'Veröffentlichungsdatum (älteste)'; @override - String get searchSortDateNewest => 'Release Date (Newest)'; + String get searchSortDateNewest => 'Veröffentlichungsdatum (Neueste)'; @override String get tooltipPlay => 'Abspielen'; @@ -1315,36 +1315,36 @@ class AppLocalizationsDe extends AppLocalizations { String get storeClearFilters => 'Filter entfernen'; @override - String get storeAddRepoTitle => 'Add Extension Repository'; + String get storeAddRepoTitle => 'Erweiterungs-Repository hinzufügen'; @override String get storeAddRepoDescription => - 'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.'; + 'Gib eine GitHub Repository-URL ein, die eine Registry.json Datei enthält, um Erweiterungen zu durchsuchen und zu installieren.'; @override - String get storeRepoUrlLabel => 'Repository URL'; + String get storeRepoUrlLabel => 'Repository-URL'; @override String get storeRepoUrlHint => 'https://github.com/user/repo'; @override String get storeRepoUrlHelper => - 'e.g. https://github.com/user/extensions-repo'; + 'z.B. https://github.com/user/extensions-repo'; @override - String get storeAddRepoButton => 'Add Repository'; + String get storeAddRepoButton => 'Repository hinzufügen'; @override - String get storeChangeRepoTooltip => 'Change repository'; + String get storeChangeRepoTooltip => 'Repository ändern'; @override - String get storeRepoDialogTitle => 'Extension Repository'; + String get storeRepoDialogTitle => 'Erweiterungs-Repository'; @override - String get storeRepoDialogCurrent => 'Current repository:'; + String get storeRepoDialogCurrent => 'Aktuelles Repository:'; @override - String get storeNewRepoUrlLabel => 'New Repository URL'; + String get storeNewRepoUrlLabel => 'Neue Repository-URL'; @override String get storeLoadError => 'Failed to load repository'; @@ -1356,7 +1356,7 @@ class AppLocalizationsDe extends AppLocalizations { String get storeEmptyNoResults => 'No extensions found'; @override - String get extensionDefaultProvider => 'Standard (Deezer/Spotify)'; + String get extensionDefaultProvider => 'Standard (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Eingebaute Suche verwenden'; @@ -1517,36 +1517,36 @@ class AppLocalizationsDe extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-Bit / bis 192kHz'; @override - String get downloadLossy320 => 'Lossy 320kbps'; + String get downloadLossy320 => 'Verlustbehaftet 320kbps'; @override - String get downloadLossyFormat => 'Lossy Format'; + String get downloadLossyFormat => 'Verlustbehaftetes Format'; @override String get downloadLossy320Format => 'Lossy 320kbps Format'; @override String get downloadLossy320FormatDesc => - 'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.'; + 'Wähle das Ausgabeformat für Tidal 320kbps verlustbehaftete Downloads. Der ursprüngliche AAC Stream wird in das ausgewählte Format konvertiert.'; @override String get downloadLossyMp3 => 'MP3 320kbps'; @override - String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track'; + String get downloadLossyMp3Subtitle => + 'Beste Kompatibilität, ~10MB pro Titel'; @override String get downloadLossyOpus256 => 'Opus 256kbps'; @override - String get downloadLossyOpus256Subtitle => - 'Best quality Opus, ~8MB per track'; + String get downloadLossyOpus256Subtitle => 'Beste Qualität, ~8MB pro Titel'; @override String get downloadLossyOpus128 => 'Opus 128kbps'; @override - String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track'; + String get downloadLossyOpus128Subtitle => 'Kleinste Größe, ~4MB pro Track'; @override String get qualityNote => @@ -1856,23 +1856,23 @@ class AppLocalizationsDe extends AppLocalizations { 'Bei der Suche nach vorhandenen Titeln anzeigen'; @override - String get libraryAutoScan => 'Auto Scan'; + String get libraryAutoScan => 'Auto-Scan'; @override String get libraryAutoScanSubtitle => 'Automatically scan your library for new files'; @override - String get libraryAutoScanOff => 'Off'; + String get libraryAutoScanOff => 'Aus'; @override - String get libraryAutoScanOnOpen => 'Every app open'; + String get libraryAutoScanOnOpen => 'Bei jeder App Öffnung'; @override - String get libraryAutoScanDaily => 'Daily'; + String get libraryAutoScanDaily => 'Täglich'; @override - String get libraryAutoScanWeekly => 'Weekly'; + String get libraryAutoScanWeekly => 'Wöchentlich'; @override String get libraryActions => 'Aktionen'; @@ -1929,8 +1929,8 @@ class AppLocalizationsDe extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'files', - one: 'file', + other: '$count Datein', + one: '1 Datei', ); return '$_temp0'; } @@ -1947,7 +1947,7 @@ class AppLocalizationsDe extends AppLocalizations { String get libraryScanning => 'Scannen...'; @override - String get libraryScanFinalizing => 'Finalizing library...'; + String get libraryScanFinalizing => 'Bibliothek wird aktualisiert...'; @override String libraryScanProgress(String progress, int total) { @@ -2018,22 +2018,23 @@ class AppLocalizationsDe extends AppLocalizations { String get libraryFilterFormat => 'Format'; @override - String get libraryFilterMetadata => 'Metadata'; + String get libraryFilterMetadata => 'Metadaten'; @override - String get libraryFilterMetadataComplete => 'Complete metadata'; + String get libraryFilterMetadataComplete => 'Komplette Metadaten'; @override - String get libraryFilterMetadataMissingAny => 'Missing any metadata'; + String get libraryFilterMetadataMissingAny => 'Metadaten fehlen'; @override - String get libraryFilterMetadataMissingYear => 'Missing year'; + String get libraryFilterMetadataMissingYear => 'Jahr fehlt'; @override - String get libraryFilterMetadataMissingGenre => 'Missing genre'; + String get libraryFilterMetadataMissingGenre => 'Genre fehlt'; @override - String get libraryFilterMetadataMissingAlbumArtist => 'Missing album artist'; + String get libraryFilterMetadataMissingAlbumArtist => + 'Fehlender Album-Künstler'; @override String get libraryFilterSort => 'Sortieren'; @@ -2065,7 +2066,7 @@ class AppLocalizationsDe extends AppLocalizations { count, locale: localeName, other: 'vor $count Minuten', - one: 'vor $count Minute', + one: 'vor 1 Minute', ); return '$_temp0'; } @@ -2076,7 +2077,7 @@ class AppLocalizationsDe extends AppLocalizations { count, locale: localeName, other: 'vor $count Stunden', - one: 'vor $count Stunde', + one: 'vor 1 Stunde', ); return '$_temp0'; } @@ -2142,7 +2143,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String get tutorialExtensionsTip1 => - 'Im Store Tab findest du nützliche Erweiterungen'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -2396,11 +2397,11 @@ class AppLocalizationsDe extends AppLocalizations { 'FFmpeg Metadaten-Einbettung fehlgeschlagen'; @override - String get queueFlacAction => 'Queue FLAC'; + String get queueFlacAction => 'Warteschlange FLAC'; @override String queueFlacConfirmMessage(int count) { - return 'Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n$count selected'; + return 'Suche Online-Matches für ausgewählte Titel und Playlists für FLAC-Downloads.\n\nVorhandene Dateien werden weder geändert noch gelöscht.\n\nNur eindeutige Treffer werden automatisch zur Warteschlange hinzugefügt.\n\n$count ausgewählt'; } @override @@ -2426,7 +2427,8 @@ class AppLocalizationsDe extends AppLocalizations { String get trackConvertFormat => 'Format konvertieren'; @override - String get trackConvertFormatSubtitle => 'In MP3 oder Opus konvertieren'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Audio konvertieren'; @@ -2454,7 +2456,7 @@ class AppLocalizationsDe extends AppLocalizations { String sourceFormat, String targetFormat, ) { - return 'Convert from $sourceFormat to $targetFormat? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.'; + return 'Konvertieren von $sourceFormat in $targetFormat? (kein Qualitätsverlust)\n\nDie Originaldatei wird nach der Konvertierung gelöscht.'; } @override @@ -2534,7 +2536,7 @@ class AppLocalizationsDe extends AppLocalizations { String get collectionLoved => 'Lieblingssongs'; @override - String get collectionPlaylists => 'Playlisten'; + String get collectionPlaylists => 'Playlists'; @override String get collectionPlaylist => 'Playlist'; @@ -2721,10 +2723,10 @@ class AppLocalizationsDe extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'tracks', - one: 'track', + other: 'Titel', + one: 'Titel', ); - return 'Convert $count $_temp0 to $format? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.'; + return 'Konvertiere $count $_temp0 in $format? (kein Qualitätsverlust)\n\nOriginaldateien werden nach der Konvertierung gelöscht.'; } @override @@ -2751,24 +2753,24 @@ class AppLocalizationsDe extends AppLocalizations { 'Künstler-Ordner nur für Titel-Künstler'; @override - String get lyricsProvidersTitle => 'Lyrics Providers'; + String get lyricsProvidersTitle => 'Lyrics-Anbieter'; @override String get lyricsProvidersDescription => - 'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.'; + 'Lyrics aktivieren, deaktivieren und neu ordnen. Anbieter werden von oben nach unten ausprobiert, bis Lyrics gefunden werden.'; @override String get lyricsProvidersInfoText => - 'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.'; + 'Erweiterungsanbieter werden immer vor eingebauten ausgeführt. Mindestens ein Anbieter muss aktiviert bleiben.'; @override String lyricsProvidersEnabledSection(int count) { - return 'Enabled ($count)'; + return '($count) aktiviert'; } @override String lyricsProvidersDisabledSection(int count) { - return 'Disabled ($count)'; + return '($count) deaktiviert'; } @override @@ -2787,52 +2789,53 @@ class AppLocalizationsDe extends AppLocalizations { @override String get lyricsProviderNeteaseDesc => - 'NetEase Cloud Music (good for Asian songs)'; + 'NetEase Cloud Music (gut für asiatische Lieder)'; @override String get lyricsProviderMusixmatchDesc => - 'Largest lyrics database (multi-language)'; + 'Größte Lyrics-Datenbank (mehrsprachig)'; @override String get lyricsProviderAppleMusicDesc => - 'Word-by-word synced lyrics (via proxy)'; + 'Wort-für-Wort-synchronisierte Lyrics (via Proxy)'; @override String get lyricsProviderQqMusicDesc => - 'QQ Music (good for Chinese songs, via proxy)'; + 'QQ Music (gut für chinesische Lieder, via Proxy)'; @override - String get lyricsProviderExtensionDesc => 'Extension provider'; + String get lyricsProviderExtensionDesc => 'Erweiterungsanbieter'; @override - String get safMigrationTitle => 'Storage Update Required'; + String get safMigrationTitle => 'Speicheraktualisierung erforderlich'; @override String get safMigrationMessage1 => - 'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.'; + 'SpotiFLAC verwendet jetzt Android Storage Access Framework (SAF) beim Herunterladen. Dies behebt Fehler bei Android 10+.'; @override String get safMigrationMessage2 => - 'Please select your download folder again to switch to the new storage system.'; + 'Bitte wähle dein Download-Ordner erneut aus, um zum neuen System zu wechseln.'; @override String get safMigrationSuccess => 'Download folder updated to SAF mode'; @override - String get settingsDonate => 'Donate'; + String get settingsDonate => 'Unterstützen'; @override - String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development'; + String get settingsDonateSubtitle => + 'Unterstütze die SpotiFLAC-Mobile Entwickler'; @override - String get tooltipLoveAll => 'Love All'; + String get tooltipLoveAll => 'Alle lieben'; @override - String get tooltipAddToPlaylist => 'Add to Playlist'; + String get tooltipAddToPlaylist => 'Zur Wiedergabeliste hinzufügen'; @override String snackbarRemovedTracksFromLoved(int count) { - return 'Removed $count tracks from Loved'; + return '$count Titel von geliebt entfernt'; } @override @@ -2841,7 +2844,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get dialogDownloadAllTitle => 'Download All'; + String get dialogDownloadAllTitle => 'Alle Herunterladen'; @override String dialogDownloadAllMessage(int count) { @@ -2852,7 +2855,7 @@ class AppLocalizationsDe extends AppLocalizations { String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs'; @override - String get homeGoToAlbum => 'Go to Album'; + String get homeGoToAlbum => 'Zum Album gehen'; @override String get homeAlbumInfoUnavailable => 'Album info not available'; @@ -2871,7 +2874,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String snackbarError(String error) { - return 'Error: $error'; + return 'Fehler: $error'; } @override @@ -2891,7 +2894,7 @@ class AppLocalizationsDe extends AppLocalizations { String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path'; @override - String get storageModeSaf => 'SAF folder'; + String get storageModeSaf => 'SAF-Ordner'; @override String get storageModeSafSubtitle => @@ -2902,7 +2905,7 @@ class AppLocalizationsDe extends AppLocalizations { 'Customize how your files are named.'; @override - String get downloadFilenameInsertTag => 'Tap to insert tag:'; + String get downloadFilenameInsertTag => 'Tippe, um Tag einzufügen:'; @override String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders'; @@ -2930,10 +2933,10 @@ class AppLocalizationsDe extends AppLocalizations { 'By Playlist already places downloads inside a playlist folder.'; @override - String get downloadSongLinkRegion => 'SongLink Region'; + String get downloadSongLinkRegion => 'SongLink-Region'; @override - String get downloadNetworkCompatibilityMode => 'Network compatibility mode'; + String get downloadNetworkCompatibilityMode => 'Netzwerkkompatibilitätsmodus'; @override String get downloadNetworkCompatibilityModeEnabled => @@ -2976,7 +2979,7 @@ class AppLocalizationsDe extends AppLocalizations { 'Append romanized lyrics when available'; @override - String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled'; + String get downloadNeteaseIncludeRomanizationDisabled => 'Deaktiviert'; @override String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word'; @@ -3008,10 +3011,10 @@ class AppLocalizationsDe extends AppLocalizations { 'Keep full Album Artist metadata value'; @override - String get downloadProvidersNoneEnabled => 'None enabled'; + String get downloadProvidersNoneEnabled => 'Keine aktiviert'; @override - String get downloadMusixmatchLanguageCode => 'Language code'; + String get downloadMusixmatchLanguageCode => 'Sprach-Code'; @override String get downloadMusixmatchLanguageHint => 'auto / en / es / ja'; @@ -3024,7 +3027,7 @@ class AppLocalizationsDe extends AppLocalizations { String get downloadMusixmatchAuto => 'Auto'; @override - String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data'; + String get downloadNetworkAnySubtitle => 'WLAN + Mobile Daten'; @override String get downloadNetworkWifiOnlySubtitle => @@ -3038,23 +3041,23 @@ class AppLocalizationsDe extends AppLocalizations { String get snackbarUnsupportedAudioFormat => 'Unsupported audio format'; @override - String get cacheRefresh => 'Refresh'; + String get cacheRefresh => 'Aktualisieren'; @override String dialogDownloadPlaylistsMessage(int trackCount, int playlistCount) { String _temp0 = intl.Intl.pluralLogic( trackCount, locale: localeName, - other: 'tracks', - one: 'track', + other: 'Titel', + one: 'Titel', ); String _temp1 = intl.Intl.pluralLogic( playlistCount, locale: localeName, - other: 'playlists', - one: 'playlist', + other: 'Playlists', + one: 'Playlist', ); - return 'Download $trackCount $_temp0 from $playlistCount $_temp1?'; + return 'Lade $trackCount $_temp0 von $playlistCount $_temp1?'; } @override @@ -3094,7 +3097,7 @@ class AppLocalizationsDe extends AppLocalizations { 'Select fields to fill automatically from online metadata'; @override - String get editMetadataAutoFillFetch => 'Fetch & Fill'; + String get editMetadataAutoFillFetch => 'Abrufen & Ausfüllen'; @override String get editMetadataAutoFillSearching => 'Searching online...'; @@ -3119,25 +3122,25 @@ class AppLocalizationsDe extends AppLocalizations { 'Select at least one field to auto-fill'; @override - String get editMetadataFieldTitle => 'Title'; + String get editMetadataFieldTitle => 'Titel'; @override - String get editMetadataFieldArtist => 'Artist'; + String get editMetadataFieldArtist => 'Künstler'; @override String get editMetadataFieldAlbum => 'Album'; @override - String get editMetadataFieldAlbumArtist => 'Album Artist'; + String get editMetadataFieldAlbumArtist => 'Album Künstler'; @override - String get editMetadataFieldDate => 'Date'; + String get editMetadataFieldDate => 'Datum'; @override - String get editMetadataFieldTrackNum => 'Track #'; + String get editMetadataFieldTrackNum => 'Titel #'; @override - String get editMetadataFieldDiscNum => 'Disc #'; + String get editMetadataFieldDiscNum => 'Disk #'; @override String get editMetadataFieldGenre => 'Genre'; @@ -3149,16 +3152,16 @@ class AppLocalizationsDe extends AppLocalizations { String get editMetadataFieldLabel => 'Label'; @override - String get editMetadataFieldCopyright => 'Copyright'; + String get editMetadataFieldCopyright => 'Urheberrecht'; @override - String get editMetadataFieldCover => 'Cover Art'; + String get editMetadataFieldCover => 'Cover-Art'; @override - String get editMetadataSelectAll => 'All'; + String get editMetadataSelectAll => 'Alle'; @override - String get editMetadataSelectEmpty => 'Empty only'; + String get editMetadataSelectEmpty => 'Nur leer'; @override String queueDownloadingCount(int count) { @@ -3166,10 +3169,10 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get queueDownloadedHeader => 'Downloaded'; + String get queueDownloadedHeader => 'Heruntergeladen'; @override - String get queueFilteringIndicator => 'Filtering...'; + String get queueFilteringIndicator => 'Filtere...'; @override String queueTrackCount(int count) { @@ -3194,7 +3197,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get queueEmptyAlbums => 'No album downloads'; + String get queueEmptyAlbums => 'Keine Album-Downloads'; @override String get queueEmptyAlbumsSubtitle => @@ -3220,7 +3223,7 @@ class AppLocalizationsDe extends AppLocalizations { String get selectionTapPlaylistsToSelect => 'Tap playlists to select'; @override - String get selectionSelectPlaylistsToDelete => 'Select playlists to delete'; + String get selectionSelectPlaylistsToDelete => 'Playlist zum Löschen wählen'; @override String get audioAnalysisTitle => 'Audio Quality Analysis'; @@ -3230,37 +3233,37 @@ class AppLocalizationsDe extends AppLocalizations { 'Verify lossless quality with spectrum analysis'; @override - String get audioAnalysisAnalyzing => 'Analyzing audio...'; + String get audioAnalysisAnalyzing => 'Audio wird analysiert...'; @override String get audioAnalysisSampleRate => 'Sample Rate'; @override - String get audioAnalysisBitDepth => 'Bit Depth'; + String get audioAnalysisBitDepth => 'Bit-Tiefe'; @override - String get audioAnalysisChannels => 'Channels'; + String get audioAnalysisChannels => 'Kanäle'; @override - String get audioAnalysisDuration => 'Duration'; + String get audioAnalysisDuration => 'Länge'; @override String get audioAnalysisNyquist => 'Nyquist'; @override - String get audioAnalysisFileSize => 'Size'; + String get audioAnalysisFileSize => 'Größe'; @override - String get audioAnalysisDynamicRange => 'Dynamic Range'; + String get audioAnalysisDynamicRange => 'Dynamischer Bereich'; @override - String get audioAnalysisPeak => 'Peak'; + String get audioAnalysisPeak => 'Maximum'; @override String get audioAnalysisRms => 'RMS'; @override - String get audioAnalysisSamples => 'Samples'; + String get audioAnalysisSamples => 'Proben'; @override String extensionsSearchWith(String providerName) { @@ -3268,7 +3271,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get extensionsHomeFeedProvider => 'Home Feed Provider'; + String get extensionsHomeFeedProvider => 'Home Feed Anbieter'; @override String get extensionsHomeFeedDescription => @@ -3296,7 +3299,7 @@ class AppLocalizationsDe extends AppLocalizations { String get sortAlphaDesc => 'Z-A'; @override - String get cancelDownloadTitle => 'Cancel download?'; + String get cancelDownloadTitle => 'Download abbrechen?'; @override String cancelDownloadContent(String trackName) { @@ -3304,7 +3307,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get cancelDownloadKeep => 'Keep'; + String get cancelDownloadKeep => 'Behalten'; @override String get metadataSaveFailedFfmpeg => 'Failed to save metadata via FFmpeg'; @@ -3319,22 +3322,22 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get errorLoadAlbum => 'Failed to load album'; + String get errorLoadAlbum => 'Fehler beim Laden des Albums'; @override - String get errorLoadPlaylist => 'Failed to load playlist'; + String get errorLoadPlaylist => 'Fehler beim Laden der Playlist'; @override - String get errorLoadArtist => 'Failed to load artist'; + String get errorLoadArtist => 'Fehler beim Laden des Interpreten'; @override - String get notifChannelDownloadName => 'Download Progress'; + String get notifChannelDownloadName => 'Download Fortschritt'; @override String get notifChannelDownloadDesc => 'Shows download progress for tracks'; @override - String get notifChannelLibraryScanName => 'Library Scan'; + String get notifChannelLibraryScanName => 'Bibliotheksscan'; @override String get notifChannelLibraryScanDesc => 'Shows local library scan progress'; @@ -3358,7 +3361,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get notifAlreadyInLibrary => 'Already in Library'; + String get notifAlreadyInLibrary => 'Bereits in der Bibliothek'; @override String notifDownloadCompleteCount(int completed, int total) { @@ -3366,7 +3369,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get notifDownloadComplete => 'Download Complete'; + String get notifDownloadComplete => 'Download abgeschlossen'; @override String notifDownloadsFinished(int completed, int failed) { @@ -3408,12 +3411,12 @@ class AppLocalizationsDe extends AppLocalizations { @override String notifLibraryScanExcluded(int count) { - return '$count excluded'; + return '$count ausgeschlossen'; } @override String notifLibraryScanErrors(int count) { - return '$count errors'; + return '$count Fehler'; } @override @@ -3436,7 +3439,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get notifUpdateReady => 'Update Ready'; + String get notifUpdateReady => 'Update bereit'; @override String notifUpdateReadyBody(String version) { @@ -3444,7 +3447,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get notifUpdateFailed => 'Update Failed'; + String get notifUpdateFailed => 'Update fehlgeschlagen'; @override String get notifUpdateFailedBody => diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index c813f73..45f7466 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -3436,13 +3436,13 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get navSettings => 'Ajustes'; @override - String get navStore => 'Tienda'; + String get navStore => 'Repositorio'; @override String get homeTitle => 'Inicio'; @override - String get homeSubtitle => 'Pegar enlace de Spotify o buscar por nombre'; + String get homeSubtitle => 'Pega una URL compatible o busca por nombre'; @override String get homeSupports => @@ -3491,6 +3491,13 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get downloadFilenameFormat => 'Formato del nombre del archivo'; + @override + String get downloadSingleFilenameFormat => 'Formato de título único'; + + @override + String get downloadSingleFilenameFormatDescription => + 'Patrón de título para sencillos y mini-álbumes. Usa las mismas etiquetas que un álbum completo.'; + @override String get downloadFolderOrganization => 'Organización de carpetas'; @@ -3537,6 +3544,13 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { return 'Usando la extensión: $extensionName'; } + @override + String get optionsDefaultSearchTab => 'Default Search Tab'; + + @override + String get optionsDefaultSearchTabSubtitle => + 'Choose which tab opens first for new search results.'; + @override String get optionsSwitchBack => 'Toque Deezer o Spotify para volver desde la extensión'; @@ -3573,6 +3587,39 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get optionsMaxQualityCoverSubtitle => 'Descargar carátula de resolución máxima'; + @override + String get optionsReplayGain => 'Nivelación de Ganancia'; + + @override + String get optionsReplayGainSubtitleOn => + 'Analizar volumen e incrustar etiquetas de RG (EBU-R128)'; + + @override + String get optionsReplayGainSubtitleOff => + 'Desactivado: sin etiquetas de normalización de volumen'; + + @override + String get optionsArtistTagMode => 'Modo de Etiqueta de Artista'; + + @override + String get optionsArtistTagModeDescription => + 'Elija cómo se ingresan múltiples artistas en etiquetas incrustadas.'; + + @override + String get optionsArtistTagModeJoined => 'Valor único ingresado'; + + @override + String get optionsArtistTagModeJoinedSubtitle => + 'Escribe un valor ARTIST, como \"Artista A, Artista B\" para mejor compatibilidad en reproductores.'; + + @override + String get optionsArtistTagModeSplitVorbis => + 'Dividir (recortar) etiquetar para FLAC/OPUS'; + + @override + String get optionsArtistTagModeSplitVorbisSubtitle => + 'Escribe una etiqueta de artista por artista para FLAC y OPUS; MP3 y M4A se mantienen agrupados.'; + @override String get optionsConcurrentDownloads => 'Descargas Simultáneas'; @@ -3589,11 +3636,10 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { 'Las descargas paralelas pueden activar la limitación de velocidad'; @override - String get optionsExtensionStore => 'Tienda de extensiones'; + String get optionsExtensionStore => 'Extensión .Repo (repositorio)'; @override - String get optionsExtensionStoreSubtitle => - 'Mostrar pestaña de tienda en la navegación'; + String get optionsExtensionStoreSubtitle => 'Mostar barra de navegación repo'; @override String get optionsCheckUpdates => 'Comprobar actualizaciones'; @@ -3650,7 +3696,7 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get optionsSpotifyDeprecationWarning => - 'Spotify search will be deprecated on March 3, 2026 due to Spotify API changes. Please switch to Deezer.'; + 'La función de búsqueda de Spotify dejará de estar disponible el 3 de marzo de 2026 debido a cambios en la API de Spotify. Te recomendamos que te pases a Deezer.'; @override String get extensionsTitle => 'Extensiones'; @@ -3672,7 +3718,7 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get extensionsUninstall => 'Desinstalar'; @override - String get storeTitle => 'Tienda de extensiones'; + String get storeTitle => 'Extensión .Repo'; @override String get storeSearch => 'Buscar extensiones...'; @@ -3783,7 +3829,7 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get aboutAppDescription => - 'Download Spotify tracks in lossless quality from Tidal and Qobuz.'; + 'Descargar pistas de Spotify en alta calidad (sin pérdida) de Tidal y Qobuz.'; @override String get artistAlbums => 'Álbumes'; @@ -3954,6 +4000,9 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get dialogImport => 'Importar'; + @override + String get dialogDownload => 'Descargar'; + @override String get dialogDiscard => 'Descartar'; @@ -4119,15 +4168,15 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get errorNoTracksFound => 'No se encontraron pistas'; @override - String get errorUrlNotRecognized => 'Link not recognized'; + String get errorUrlNotRecognized => 'Enlace no reconocido'; @override String get errorUrlNotRecognizedMessage => - 'This link is not supported. Make sure the URL is correct and a compatible extension is installed.'; + 'Este enlace no es compatible. Asegúrate de que la URL sea correcta y de tener instalada una extensión compatible.'; @override String get errorUrlFetchFailed => - 'Failed to load content from this link. Please try again.'; + 'No se ha podido cargar el contenido de este enlace. Inténtalo de nuevo.'; @override String errorMissingExtensionSource(String item) { @@ -4186,6 +4235,36 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get searchPlaylists => 'Listas de reproducción'; + @override + String get searchSortTitle => 'Ordenar resultados'; + + @override + String get searchSortDefault => 'Por defecto'; + + @override + String get searchSortTitleAZ => 'Nombre (A-Z)'; + + @override + String get searchSortTitleZA => 'Nombre (Z-A)'; + + @override + String get searchSortArtistAZ => 'Artista (A-Z)'; + + @override + String get searchSortArtistZA => 'Artista (Z-A)'; + + @override + String get searchSortDurationShort => 'Duración (más corto)'; + + @override + String get searchSortDurationLong => 'Duración (más largo)'; + + @override + String get searchSortDateOldest => 'Fecha de lanzamiento (antiguo)'; + + @override + String get searchSortDateNewest => 'Fecha de lanzamiento (reciente)'; + @override String get tooltipPlay => 'Reproducir'; @@ -4193,21 +4272,21 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get filenameFormat => 'Formato del nombre del archivo'; @override - String get filenameShowAdvancedTags => 'Show advanced tags'; + String get filenameShowAdvancedTags => 'Mostrar etiquetas avanzadas'; @override String get filenameShowAdvancedTagsDescription => - 'Enable formatted tags for track padding and date patterns'; + 'Habilitar etiquetas con formato para el relleno de pistas y los formatos de fecha'; @override String get folderOrganizationNone => 'Ninguna organización'; @override - String get folderOrganizationByPlaylist => 'By Playlist'; + String get folderOrganizationByPlaylist => 'Por Playlist'; @override String get folderOrganizationByPlaylistSubtitle => - 'Separate folder for each playlist'; + 'Una carpeta independiente para cada Playlist'; @override String get folderOrganizationByArtist => 'Por Artista'; @@ -4285,6 +4364,17 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get providerPriorityInfo => 'Si una pista no está disponible en el primer proveedor, la aplicación intentará automáticamente el siguiente.'; + @override + String get providerPriorityFallbackExtensionsTitle => 'Fallback de extensión'; + + @override + String get providerPriorityFallbackExtensionsDescription => + 'Elije qué extensiones instaladas se pueden utilizar durante el cambio automático a una alternativa. Los proveedores integrados siguen el orden de prioridad indicado anteriormente.'; + + @override + String get providerPriorityFallbackExtensionsHint => + 'Solo las extensiones activas con proveedor de descarga se listan aquí.'; + @override String get providerBuiltIn => 'Integrado'; @@ -4566,6 +4656,12 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get trackLyricsNotAvailable => 'Letras no disponibles para este tema'; + @override + String get trackLyricsNotInFile => 'No se encontraron letras'; + + @override + String get trackFetchOnlineLyrics => 'Obtener en línea'; + @override String get trackLyricsTimeout => 'Tiempo de espera agotado. Inténtalo de nuevo más tarde.'; @@ -4635,7 +4731,48 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get storeClearFilters => 'Limpiar filtros'; @override - String get extensionDefaultProvider => 'Por defecto (Deezer/Spotify)'; + String get storeAddRepoTitle => 'Añadir repositorio de extensiones'; + + @override + String get storeAddRepoDescription => + 'Introduzca una URL de repositorio de GitHub que contenga un archivo registry.json para navegar e instalar extensiones.'; + + @override + String get storeRepoUrlLabel => 'URL del repositorio'; + + @override + String get storeRepoUrlHint => 'https://github.com/user/repo'; + + @override + String get storeRepoUrlHelper => + 'Ejemplo: https://github.com/user/extensions-repo'; + + @override + String get storeAddRepoButton => 'Añadir repositorio'; + + @override + String get storeChangeRepoTooltip => 'Cambiar repositorio'; + + @override + String get storeRepoDialogTitle => 'Repositorio de extensiones'; + + @override + String get storeRepoDialogCurrent => 'Repositorio actual:'; + + @override + String get storeNewRepoUrlLabel => 'Nueva URL del repositorio'; + + @override + String get storeLoadError => 'Falló al carga repositorio'; + + @override + String get storeEmptyNoExtensions => 'No hay extensiones disponibles'; + + @override + String get storeEmptyNoResults => 'No se encontraron extensiones'; + + @override + String get extensionDefaultProvider => 'Predeterminado (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Usar búsqueda integrada'; @@ -4737,6 +4874,13 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get extensionsDownloadPrioritySubtitle => 'Establecer orden de servicio de descarga'; + @override + String get extensionsFallbackTitle => 'Fallback de extensiones'; + + @override + String get extensionsFallbackSubtitle => + 'Elija que extensiones pueden usarse como reserva'; + @override String get extensionsNoDownloadProvider => 'No hay extensiones con proveedor de descargas'; @@ -4787,6 +4931,39 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get qualityHiResFlacMaxSubtitle => '24 bits / hasta 192kHz'; + @override + String get downloadLossy320 => 'Con pérdida, 320 kbps'; + + @override + String get downloadLossyFormat => 'Formato con pérdida'; + + @override + String get downloadLossy320Format => 'Formato con pérdida a 320 kbps'; + + @override + String get downloadLossy320FormatDesc => + 'Elige el formato de salida para las descargas con pérdida de Tidal a 320kbps. La transmisión AAC original se convertirá al formato que hayas seleccionado.'; + + @override + String get downloadLossyMp3 => 'MP3 (320kbps)'; + + @override + String get downloadLossyMp3Subtitle => + 'Óptima compatibilidad, ~10 MB por pista'; + + @override + String get downloadLossyOpus256 => 'OPUS (256kbps)'; + + @override + String get downloadLossyOpus256Subtitle => + 'Opus de la mejor calidad, ~8 MB por pista'; + + @override + String get downloadLossyOpus128 => 'OPUS (128kbps)'; + + @override + String get downloadLossyOpus128Subtitle => 'Tamaño mínimo: ~4 MB por pista'; + @override String get qualityNote => 'La calidad real depende de la disponibilidad de la pista del servicio'; @@ -4804,18 +4981,20 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get downloadAlbumFolderStructure => 'Estructura de carpeta del álbum'; @override - String get downloadUseAlbumArtistForFolders => 'Use Album Artist for folders'; + String get downloadUseAlbumArtistForFolders => + 'Usar álbum de artista cómo carpeta'; @override - String get downloadUsePrimaryArtistOnly => 'Primary artist only for folders'; + String get downloadUsePrimaryArtistOnly => + 'Artista principal solo para carpetas'; @override String get downloadUsePrimaryArtistOnlyEnabled => - 'Featured artists removed from folder name (e.g. Justin Bieber, Quavo → Justin Bieber)'; + 'Se han eliminado los nombres de los artistas destacados del nombre de la carpeta (p. ej., Justin Bieber, Quavo → Justin Bieber)'; @override String get downloadUsePrimaryArtistOnlyDisabled => - 'Full artist string used for folder name'; + 'Se utiliza el nombre completo del artista como nombre de la carpeta'; @override String get downloadSelectQuality => 'Seleccionar Calidad'; @@ -4889,6 +5068,13 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get albumFolderArtistAlbumSinglesSubtitle => 'Artista/Álbum/ y Artista/pistas/'; + @override + String get albumFolderArtistAlbumFlat => 'Artista / Álbum (sencillos planos)'; + + @override + String get albumFolderArtistAlbumFlatSubtitle => + 'Artist/Album/ and Artist/song.flac'; + @override String get downloadedAlbumDeleteSelected => 'Borrar Seleccionados'; @@ -4946,10 +5132,10 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get recentTypePlaylist => 'Lista de reproducción'; @override - String get recentEmpty => 'No recent items yet'; + String get recentEmpty => 'Aún no hay entradas recientes'; @override - String get recentShowAllDownloads => 'Show All Downloads'; + String get recentShowAllDownloads => 'Mostrar todas las descargas'; @override String recentPlaylistInfo(String name) { @@ -4980,31 +5166,31 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String discographySinglesOnlySubtitle(int count, int albumCount) { - return '$count tracks from $albumCount singles'; + return '$count Pistas de $albumCount sencillos'; } @override - String get discographySelectAlbums => 'Select Albums...'; + String get discographySelectAlbums => 'Seleccionar álbumes...'; @override String get discographySelectAlbumsSubtitle => - 'Choose specific albums or singles'; + 'Elige álbumes o sencillos concretos'; @override - String get discographyFetchingTracks => 'Fetching tracks...'; + String get discographyFetchingTracks => 'Cargando canciones...'; @override String discographyFetchingAlbum(int current, int total) { - return 'Fetching $current of $total...'; + return 'Cargando $current de $total...'; } @override String discographySelectedCount(int count) { - return '$count selected'; + return '$count seleccionados'; } @override - String get discographyDownloadSelected => 'Download Selected'; + String get discographyDownloadSelected => 'Descargar seleccionados'; @override String discographyAddedToQueue(int count) { @@ -5053,10 +5239,10 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get settingsLocalLibrarySubtitle => 'Scan music & detect duplicates'; @override - String get settingsCache => 'Storage & Cache'; + String get settingsCache => 'Almacenamiento & Caché'; @override - String get settingsCacheSubtitle => 'View size and clear cached data'; + String get settingsCacheSubtitle => 'Ver tamaño y borrar datos en caché'; @override String get libraryTitle => 'Local Library'; @@ -5069,7 +5255,7 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get libraryEnableLocalLibrarySubtitle => - 'Scan and track your existing music'; + 'Escanea y rastrea tu música existente'; @override String get libraryFolder => 'Library Folder'; @@ -5084,6 +5270,25 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get libraryShowDuplicateIndicatorSubtitle => 'Show when searching for existing tracks'; + @override + String get libraryAutoScan => 'Escaneo Automático'; + + @override + String get libraryAutoScanSubtitle => + 'Automatically scan your library for new files'; + + @override + String get libraryAutoScanOff => 'Apagado'; + + @override + String get libraryAutoScanOnOpen => 'Every app open'; + + @override + String get libraryAutoScanDaily => 'Daily'; + + @override + String get libraryAutoScanWeekly => 'Weekly'; + @override String get libraryActions => 'Actions'; @@ -5134,6 +5339,17 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { return '$_temp0'; } + @override + String libraryFilesUnit(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'files', + one: 'file', + ); + return '$_temp0'; + } + @override String libraryLastScanned(String time) { return 'Last scanned: $time'; @@ -5145,6 +5361,9 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get libraryScanning => 'Scanning...'; + @override + String get libraryScanFinalizing => 'Finalizing library...'; + @override String libraryScanProgress(String progress, int total) { return '$progress% of $total files'; @@ -5213,6 +5432,24 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get libraryFilterFormat => 'Format'; + @override + String get libraryFilterMetadata => 'Metadata'; + + @override + String get libraryFilterMetadataComplete => 'Complete metadata'; + + @override + String get libraryFilterMetadataMissingAny => 'Missing any metadata'; + + @override + String get libraryFilterMetadataMissingYear => 'Missing year'; + + @override + String get libraryFilterMetadataMissingGenre => 'Missing genre'; + + @override + String get libraryFilterMetadataMissingAlbumArtist => 'Missing album artist'; + @override String get libraryFilterSort => 'Sort'; @@ -5222,6 +5459,18 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get libraryFilterSortOldest => 'Oldest'; + @override + String get libraryFilterSortAlbumAsc => 'Album (A-Z)'; + + @override + String get libraryFilterSortAlbumDesc => 'Album (Z-A)'; + + @override + String get libraryFilterSortGenreAsc => 'Genre (A-Z)'; + + @override + String get libraryFilterSortGenreDesc => 'Genre (Z-A)'; + @override String get timeJustNow => 'Just now'; @@ -5308,7 +5557,7 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -5506,6 +5755,30 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get trackReEnrichOnlineSubtitle => 'Search metadata online and embed into file'; + @override + String get trackReEnrichFieldsTitle => 'Fields to update'; + + @override + String get trackReEnrichFieldCover => 'Cover Art'; + + @override + String get trackReEnrichFieldLyrics => 'Lyrics'; + + @override + String get trackReEnrichFieldBasicTags => 'Album, Album Artist'; + + @override + String get trackReEnrichFieldTrackInfo => 'Track & Disc Number'; + + @override + String get trackReEnrichFieldReleaseInfo => 'Date & ISRC'; + + @override + String get trackReEnrichFieldExtra => 'Genre, Label, Copyright'; + + @override + String get trackReEnrichSelectAll => 'Select All'; + @override String get trackEditMetadata => 'Edit Metadata'; @@ -5534,6 +5807,28 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get trackReEnrichFfmpegFailed => 'FFmpeg metadata embed failed'; + @override + String get queueFlacAction => 'Queue FLAC'; + + @override + String queueFlacConfirmMessage(int count) { + return 'Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n$count selected'; + } + + @override + String queueFlacFindingProgress(int current, int total) { + return 'Finding FLAC matches... ($current/$total)'; + } + + @override + String get queueFlacNoReliableMatches => + 'No reliable online matches found for the selection'; + + @override + String queueFlacQueuedWithSkipped(int addedCount, int skippedCount) { + return 'Added $addedCount tracks to queue, skipped $skippedCount'; + } + @override String trackSaveFailed(String error) { return 'Failed: $error'; @@ -5543,7 +5838,8 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get trackConvertFormat => 'Convert Format'; @override - String get trackConvertFormatSubtitle => 'Convert to MP3 or Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; @@ -5566,6 +5862,18 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { return 'Convert from $sourceFormat to $targetFormat at $bitrate?\n\nThe original file will be deleted after conversion.'; } + @override + String trackConvertConfirmMessageLossless( + String sourceFormat, + String targetFormat, + ) { + return 'Convert from $sourceFormat to $targetFormat? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.'; + } + + @override + String get trackConvertLosslessHint => + 'Lossless conversion — no quality loss'; + @override String get trackConvertConverting => 'Converting audio...'; @@ -5819,6 +6127,17 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { return 'Convert $count $_temp0 to $format at $bitrate?\n\nOriginal files will be deleted after conversion.'; } + @override + String selectionBatchConvertConfirmMessageLossless(int count, String format) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Convert $count $_temp0 to $format? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.'; + } + @override String selectionBatchConvertProgress(int current, int total) { return 'Converting $current of $total...'; @@ -5841,4 +6160,704 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { @override String get downloadUseAlbumArtistForFoldersTrackSubtitle => 'Artist folders use Track Artist only'; + + @override + String get lyricsProvidersTitle => 'Lyrics Providers'; + + @override + String get lyricsProvidersDescription => + 'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.'; + + @override + String get lyricsProvidersInfoText => + 'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.'; + + @override + String lyricsProvidersEnabledSection(int count) { + return 'Enabled ($count)'; + } + + @override + String lyricsProvidersDisabledSection(int count) { + return 'Disabled ($count)'; + } + + @override + String get lyricsProvidersAtLeastOne => + 'At least one provider must remain enabled'; + + @override + String get lyricsProvidersSaved => 'Lyrics provider priority saved'; + + @override + String get lyricsProvidersDiscardContent => + 'You have unsaved changes that will be lost.'; + + @override + String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database'; + + @override + String get lyricsProviderNeteaseDesc => + 'NetEase Cloud Music (good for Asian songs)'; + + @override + String get lyricsProviderMusixmatchDesc => + 'Largest lyrics database (multi-language)'; + + @override + String get lyricsProviderAppleMusicDesc => + 'Word-by-word synced lyrics (via proxy)'; + + @override + String get lyricsProviderQqMusicDesc => + 'QQ Music (good for Chinese songs, via proxy)'; + + @override + String get lyricsProviderExtensionDesc => 'Extension provider'; + + @override + String get safMigrationTitle => 'Storage Update Required'; + + @override + String get safMigrationMessage1 => + 'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.'; + + @override + String get safMigrationMessage2 => + 'Please select your download folder again to switch to the new storage system.'; + + @override + String get safMigrationSuccess => 'Download folder updated to SAF mode'; + + @override + String get settingsDonate => 'Donate'; + + @override + String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development'; + + @override + String get tooltipLoveAll => 'Love All'; + + @override + String get tooltipAddToPlaylist => 'Add to Playlist'; + + @override + String snackbarRemovedTracksFromLoved(int count) { + return 'Removed $count tracks from Loved'; + } + + @override + String snackbarAddedTracksToLoved(int count) { + return 'Added $count tracks to Loved'; + } + + @override + String get dialogDownloadAllTitle => 'Download All'; + + @override + String dialogDownloadAllMessage(int count) { + return 'Download $count tracks?'; + } + + @override + String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs'; + + @override + String get homeGoToAlbum => 'Go to Album'; + + @override + String get homeAlbumInfoUnavailable => 'Album info not available'; + + @override + String get snackbarLoadingCueSheet => 'Loading CUE sheet...'; + + @override + String get snackbarMetadataSaved => 'Metadata saved successfully'; + + @override + String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics'; + + @override + String get snackbarFailedToWriteStorage => 'Failed to write back to storage'; + + @override + String snackbarError(String error) { + return 'Error: $error'; + } + + @override + String get snackbarNoActionDefined => 'No action defined for this button'; + + @override + String get noTracksFoundForAlbum => 'No tracks found for this album'; + + @override + String get downloadLocationSubtitle => + 'Choose storage mode for downloaded files.'; + + @override + String get storageModeAppFolder => 'App folder (non-SAF)'; + + @override + String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path'; + + @override + String get storageModeSaf => 'SAF folder'; + + @override + String get storageModeSafSubtitle => + 'Pick folder via Android Storage Access Framework'; + + @override + String get downloadFilenameDescription => + 'Customize how your files are named.'; + + @override + String get downloadFilenameInsertTag => 'Tap to insert tag:'; + + @override + String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders'; + + @override + String get downloadSeparateSinglesDisabled => 'All files in same structure'; + + @override + String get downloadArtistNameFilters => 'Artist Name Filters'; + + @override + String get downloadCreatePlaylistSourceFolder => + 'Create playlist source folder'; + + @override + String get downloadCreatePlaylistSourceFolderEnabled => + 'Playlist downloads use Playlist/ plus your normal folder structure.'; + + @override + String get downloadCreatePlaylistSourceFolderDisabled => + 'Playlist downloads use the normal folder structure only.'; + + @override + String get downloadCreatePlaylistSourceFolderRedundant => + 'By Playlist already places downloads inside a playlist folder.'; + + @override + String get downloadSongLinkRegion => 'SongLink Region'; + + @override + String get downloadNetworkCompatibilityMode => 'Network compatibility mode'; + + @override + String get downloadNetworkCompatibilityModeEnabled => + 'Enabled: try HTTP + accept invalid TLS certificates (unsafe)'; + + @override + String get downloadNetworkCompatibilityModeDisabled => + 'Off: strict HTTPS certificate validation (recommended)'; + + @override + String get downloadSelectServiceToEnable => + 'Select a built-in service to enable'; + + @override + String get downloadSelectTidalQobuz => + 'Select Tidal or Qobuz above to configure quality'; + + @override + String get downloadEmbedLyricsDisabled => + 'Disabled while Embed Metadata is turned off'; + + @override + String get downloadNeteaseIncludeTranslation => + 'Netease: Include Translation'; + + @override + String get downloadNeteaseIncludeTranslationEnabled => + 'Append translated lyrics when available'; + + @override + String get downloadNeteaseIncludeTranslationDisabled => + 'Use original lyrics only'; + + @override + String get downloadNeteaseIncludeRomanization => + 'Netease: Include Romanization'; + + @override + String get downloadNeteaseIncludeRomanizationEnabled => + 'Append romanized lyrics when available'; + + @override + String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled'; + + @override + String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word'; + + @override + String get downloadAppleQqMultiPersonEnabled => + 'Enable v1/v2 speaker and [bg:] tags'; + + @override + String get downloadAppleQqMultiPersonDisabled => + 'Simplified word-by-word formatting'; + + @override + String get downloadMusixmatchLanguage => 'Musixmatch Language'; + + @override + String get downloadMusixmatchLanguageAuto => 'Auto (original)'; + + @override + String get downloadFilterContributing => + 'Filter contributing artists in Album Artist'; + + @override + String get downloadFilterContributingEnabled => + 'Album Artist metadata uses primary artist only'; + + @override + String get downloadFilterContributingDisabled => + 'Keep full Album Artist metadata value'; + + @override + String get downloadProvidersNoneEnabled => 'None enabled'; + + @override + String get downloadMusixmatchLanguageCode => 'Language code'; + + @override + String get downloadMusixmatchLanguageHint => 'auto / en / es / ja'; + + @override + String get downloadMusixmatchLanguageDesc => + 'Set preferred language code (example: en, es, ja). Leave empty for auto.'; + + @override + String get downloadMusixmatchAuto => 'Auto'; + + @override + String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data'; + + @override + String get downloadNetworkWifiOnlySubtitle => + 'Pause downloads on mobile data'; + + @override + String get downloadSongLinkRegionDesc => + 'Used as userCountry for SongLink API lookup.'; + + @override + String get snackbarUnsupportedAudioFormat => 'Unsupported audio format'; + + @override + String get cacheRefresh => 'Refresh'; + + @override + String dialogDownloadPlaylistsMessage(int trackCount, int playlistCount) { + String _temp0 = intl.Intl.pluralLogic( + trackCount, + locale: localeName, + other: 'tracks', + one: 'track', + ); + String _temp1 = intl.Intl.pluralLogic( + playlistCount, + locale: localeName, + other: 'playlists', + one: 'playlist', + ); + return 'Download $trackCount $_temp0 from $playlistCount $_temp1?'; + } + + @override + String bulkDownloadPlaylistsButton(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'playlists', + one: 'playlist', + ); + return 'Download $count $_temp0'; + } + + @override + String get bulkDownloadSelectPlaylists => 'Select playlists to download'; + + @override + String get snackbarSelectedPlaylistsEmpty => + 'Selected playlists have no tracks'; + + @override + String playlistsCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count playlists', + one: '1 playlist', + ); + return '$_temp0'; + } + + @override + String get editMetadataAutoFill => 'Auto-fill from online'; + + @override + String get editMetadataAutoFillDesc => + 'Select fields to fill automatically from online metadata'; + + @override + String get editMetadataAutoFillFetch => 'Fetch & Fill'; + + @override + String get editMetadataAutoFillSearching => 'Searching online...'; + + @override + String get editMetadataAutoFillNoResults => + 'No matching metadata found online'; + + @override + String editMetadataAutoFillDone(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'fields', + one: 'field', + ); + return 'Filled $count $_temp0 from online metadata'; + } + + @override + String get editMetadataAutoFillNoneSelected => + 'Select at least one field to auto-fill'; + + @override + String get editMetadataFieldTitle => 'Title'; + + @override + String get editMetadataFieldArtist => 'Artist'; + + @override + String get editMetadataFieldAlbum => 'Album'; + + @override + String get editMetadataFieldAlbumArtist => 'Album Artist'; + + @override + String get editMetadataFieldDate => 'Date'; + + @override + String get editMetadataFieldTrackNum => 'Track #'; + + @override + String get editMetadataFieldDiscNum => 'Disc #'; + + @override + String get editMetadataFieldGenre => 'Genre'; + + @override + String get editMetadataFieldIsrc => 'ISRC'; + + @override + String get editMetadataFieldLabel => 'Label'; + + @override + String get editMetadataFieldCopyright => 'Copyright'; + + @override + String get editMetadataFieldCover => 'Cover Art'; + + @override + String get editMetadataSelectAll => 'All'; + + @override + String get editMetadataSelectEmpty => 'Empty only'; + + @override + String queueDownloadingCount(int count) { + return 'Downloading ($count)'; + } + + @override + String get queueDownloadedHeader => 'Downloaded'; + + @override + String get queueFilteringIndicator => 'Filtering...'; + + @override + String queueTrackCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count tracks', + one: '1 track', + ); + return '$_temp0'; + } + + @override + String queueAlbumCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count albums', + one: '1 album', + ); + return '$_temp0'; + } + + @override + String get queueEmptyAlbums => 'No album downloads'; + + @override + String get queueEmptyAlbumsSubtitle => + 'Download multiple tracks from an album to see them here'; + + @override + String get queueEmptySingles => 'No single downloads'; + + @override + String get queueEmptySinglesSubtitle => + 'Single track downloads will appear here'; + + @override + String get queueEmptyHistory => 'No download history'; + + @override + String get queueEmptyHistorySubtitle => 'Downloaded tracks will appear here'; + + @override + String get selectionAllPlaylistsSelected => 'All playlists selected'; + + @override + String get selectionTapPlaylistsToSelect => 'Tap playlists to select'; + + @override + String get selectionSelectPlaylistsToDelete => 'Select playlists to delete'; + + @override + String get audioAnalysisTitle => 'Audio Quality Analysis'; + + @override + String get audioAnalysisDescription => + 'Verify lossless quality with spectrum analysis'; + + @override + String get audioAnalysisAnalyzing => 'Analyzing audio...'; + + @override + String get audioAnalysisSampleRate => 'Sample Rate'; + + @override + String get audioAnalysisBitDepth => 'Bit Depth'; + + @override + String get audioAnalysisChannels => 'Channels'; + + @override + String get audioAnalysisDuration => 'Duration'; + + @override + String get audioAnalysisNyquist => 'Nyquist'; + + @override + String get audioAnalysisFileSize => 'Size'; + + @override + String get audioAnalysisDynamicRange => 'Dynamic Range'; + + @override + String get audioAnalysisPeak => 'Peak'; + + @override + String get audioAnalysisRms => 'RMS'; + + @override + String get audioAnalysisSamples => 'Samples'; + + @override + String extensionsSearchWith(String providerName) { + return 'Search with $providerName'; + } + + @override + String get extensionsHomeFeedProvider => 'Home Feed Provider'; + + @override + String get extensionsHomeFeedDescription => + 'Choose which extension provides the home feed on the main screen'; + + @override + String get extensionsHomeFeedAuto => 'Auto'; + + @override + String get extensionsHomeFeedAutoSubtitle => + 'Automatically select the best available'; + + @override + String extensionsHomeFeedUse(String extensionName) { + return 'Use $extensionName home feed'; + } + + @override + String get extensionsNoHomeFeedExtensions => 'No extensions with home feed'; + + @override + String get sortAlphaAsc => 'A-Z'; + + @override + String get sortAlphaDesc => 'Z-A'; + + @override + String get cancelDownloadTitle => 'Cancel download?'; + + @override + String cancelDownloadContent(String trackName) { + return 'This will cancel the active download for \"$trackName\".'; + } + + @override + String get cancelDownloadKeep => 'Keep'; + + @override + String get metadataSaveFailedFfmpeg => 'Failed to save metadata via FFmpeg'; + + @override + String get metadataSaveFailedStorage => + 'Failed to write metadata back to storage'; + + @override + String snackbarFolderPickerFailed(String error) { + return 'Failed to open folder picker: $error'; + } + + @override + String get errorLoadAlbum => 'Failed to load album'; + + @override + String get errorLoadPlaylist => 'Failed to load playlist'; + + @override + String get errorLoadArtist => 'Failed to load artist'; + + @override + String get notifChannelDownloadName => 'Download Progress'; + + @override + String get notifChannelDownloadDesc => 'Shows download progress for tracks'; + + @override + String get notifChannelLibraryScanName => 'Library Scan'; + + @override + String get notifChannelLibraryScanDesc => 'Shows local library scan progress'; + + @override + String notifDownloadingTrack(String trackName) { + return 'Downloading $trackName'; + } + + @override + String notifFinalizingTrack(String trackName) { + return 'Finalizing $trackName'; + } + + @override + String get notifEmbeddingMetadata => 'Embedding metadata...'; + + @override + String notifAlreadyInLibraryCount(int completed, int total) { + return 'Already in Library ($completed/$total)'; + } + + @override + String get notifAlreadyInLibrary => 'Already in Library'; + + @override + String notifDownloadCompleteCount(int completed, int total) { + return 'Download Complete ($completed/$total)'; + } + + @override + String get notifDownloadComplete => 'Download Complete'; + + @override + String notifDownloadsFinished(int completed, int failed) { + return 'Downloads Finished ($completed done, $failed failed)'; + } + + @override + String get notifAllDownloadsComplete => 'All Downloads Complete'; + + @override + String notifTracksDownloadedSuccess(int count) { + return '$count tracks downloaded successfully'; + } + + @override + String get notifScanningLibrary => 'Scanning local library'; + + @override + String notifLibraryScanProgressWithTotal( + int scanned, + int total, + int percentage, + ) { + return '$scanned/$total files • $percentage%'; + } + + @override + String notifLibraryScanProgressNoTotal(int scanned, int percentage) { + return '$scanned files scanned • $percentage%'; + } + + @override + String get notifLibraryScanComplete => 'Library scan complete'; + + @override + String notifLibraryScanCompleteBody(int count) { + return '$count tracks indexed'; + } + + @override + String notifLibraryScanExcluded(int count) { + return '$count excluded'; + } + + @override + String notifLibraryScanErrors(int count) { + return '$count errors'; + } + + @override + String get notifLibraryScanFailed => 'Library scan failed'; + + @override + String get notifLibraryScanCancelled => 'Library scan cancelled'; + + @override + String get notifLibraryScanStopped => 'Scan stopped before completion.'; + + @override + String notifDownloadingUpdate(String version) { + return 'Downloading SpotiFLAC v$version'; + } + + @override + String notifUpdateProgress(String received, String total, int percentage) { + return '$received / $total MB • $percentage%'; + } + + @override + String get notifUpdateReady => 'Update Ready'; + + @override + String notifUpdateReadyBody(String version) { + return 'SpotiFLAC v$version downloaded. Tap to install.'; + } + + @override + String get notifUpdateFailed => 'Update Failed'; + + @override + String get notifUpdateFailedBody => + 'Could not download update. Try again later.'; } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 95aa50b..05d4627 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -21,13 +21,13 @@ class AppLocalizationsFr extends AppLocalizations { String get navSettings => 'Paramètres'; @override - String get navStore => 'Magasin'; + String get navStore => 'Repo'; @override String get homeTitle => 'Accueil'; @override - String get homeSubtitle => 'Coller un lien Spotify ou rechercher par nom'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => 'Supports: Piste, Album, Playlist, Artiste URLs'; @@ -218,10 +218,10 @@ class AppLocalizationsFr extends AppLocalizations { 'Parallel downloads may trigger rate limiting'; @override - String get optionsExtensionStore => 'Extension Store'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => 'Show Store tab in navigation'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => 'Check for Updates'; @@ -282,7 +282,7 @@ class AppLocalizationsFr extends AppLocalizations { String get extensionsTitle => 'Extensions'; @override - String get extensionsDisabled => 'Disabled'; + String get extensionsDisabled => 'Désactivée'; @override String extensionsVersion(String version) { @@ -291,38 +291,38 @@ class AppLocalizationsFr extends AppLocalizations { @override String extensionsAuthor(String author) { - return 'by $author'; + return 'par $author'; } @override String get extensionsUninstall => 'Désinstaller'; @override - String get storeTitle => 'Magasin d\'extension'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => 'Recherche d\'extensions...'; @override - String get storeInstall => 'Install'; + String get storeInstall => 'Installer'; @override - String get storeInstalled => 'Installed'; + String get storeInstalled => 'Installé'; @override - String get storeUpdate => 'Update'; + String get storeUpdate => 'Mettre à jour'; @override - String get aboutTitle => 'About'; + String get aboutTitle => 'À propos de'; @override - String get aboutContributors => 'Contributors'; + String get aboutContributors => 'Contributeurs'; @override - String get aboutMobileDeveloper => 'Mobile version developer'; + String get aboutMobileDeveloper => 'Développeur de la version mobile'; @override - String get aboutOriginalCreator => 'Creator of the original SpotiFLAC'; + String get aboutOriginalCreator => 'Créateur de SpotiFLAC original'; @override String get aboutLogoArtist => @@ -362,7 +362,7 @@ class AppLocalizationsFr extends AppLocalizations { String get aboutTelegramChannel => 'Telegram Channel'; @override - String get aboutTelegramChannelSubtitle => 'Announcements and updates'; + String get aboutTelegramChannelSubtitle => 'Annonces et mises à jour'; @override String get aboutTelegramChat => 'Telegram Community'; @@ -520,10 +520,11 @@ class AppLocalizationsFr extends AppLocalizations { 'SpotiFLAC needs storage permission to save your downloaded music files.'; @override - String get setupNotificationGranted => 'Notification Permission Granted!'; + String get setupNotificationGranted => + 'Autorisation de notifications accordée!'; @override - String get setupNotificationEnable => 'Enable Notifications'; + String get setupNotificationEnable => 'Activer les notifications'; @override String get setupFolderChoose => 'Choisissez le dossier pour télécharger'; @@ -533,39 +534,39 @@ class AppLocalizationsFr extends AppLocalizations { 'Sélectionnez un dossier dans lequel votre musique téléchargée sera enregistrée.'; @override - String get setupSelectFolder => 'Select Folder'; + String get setupSelectFolder => 'Sélectionner un dossier'; @override - String get setupEnableNotifications => 'Enable Notifications'; + String get setupEnableNotifications => 'Activer les 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'; + String get setupSkipForNow => 'Ignorer pour le moment'; @override - String get setupNext => 'Next'; + String get setupNext => 'Suivant'; @override - String get setupGetStarted => 'Get Started'; + String get setupGetStarted => 'Démarrer'; @override String get setupAllowAccessToManageFiles => - 'Please enable \"Allow access to manage all files\" in the next screen.'; + 'Veuillez activer \"Autoriser l\'accès à tous les fichiers\" sur l\'écran suivant.'; @override - String get dialogCancel => 'Cancel'; + String get dialogCancel => 'Annuler'; @override - String get dialogSave => 'Save'; + String get dialogSave => 'Sauvegarder'; @override - String get dialogDelete => 'Delete'; + String get dialogDelete => 'Supprimer'; @override - String get dialogRetry => 'Retry'; + String get dialogRetry => 'Réessayer'; @override String get dialogClear => 'Clear'; @@ -577,7 +578,7 @@ class AppLocalizationsFr extends AppLocalizations { String get dialogImport => 'Import'; @override - String get dialogDownload => 'Download'; + String get dialogDownload => 'Télécharger'; @override String get dialogDiscard => 'Discard'; @@ -586,10 +587,10 @@ class AppLocalizationsFr extends AppLocalizations { String get dialogRemove => 'Remove'; @override - String get dialogUninstall => 'Uninstall'; + String get dialogUninstall => 'Désinstaller'; @override - String get dialogDiscardChanges => 'Discard Changes?'; + String get dialogDiscardChanges => 'Ignorer les modifications ?'; @override String get dialogUnsavedChanges => @@ -1338,7 +1339,7 @@ class AppLocalizationsFr extends AppLocalizations { String get storeEmptyNoResults => 'No extensions found'; @override - String get extensionDefaultProvider => 'Default (Deezer/Spotify)'; + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Use built-in search'; @@ -2116,7 +2117,7 @@ class AppLocalizationsFr extends AppLocalizations { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -2397,7 +2398,8 @@ class AppLocalizationsFr extends AppLocalizations { String get trackConvertFormat => 'Convert Format'; @override - String get trackConvertFormatSubtitle => 'Convert to MP3 or Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; diff --git a/lib/l10n/app_localizations_hi.dart b/lib/l10n/app_localizations_hi.dart index d542fc6..ea56b41 100644 --- a/lib/l10n/app_localizations_hi.dart +++ b/lib/l10n/app_localizations_hi.dart @@ -21,13 +21,13 @@ class AppLocalizationsHi extends AppLocalizations { String get navSettings => 'विकल्प'; @override - String get navStore => 'Store'; + String get navStore => 'Repo'; @override String get homeTitle => 'Home'; @override - String get homeSubtitle => 'Paste a Spotify link or search by name'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => 'Supports: Track, Album, Playlist, Artist URLs'; @@ -216,10 +216,10 @@ class AppLocalizationsHi extends AppLocalizations { 'Parallel downloads may trigger rate limiting'; @override - String get optionsExtensionStore => 'Extension Store'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => 'Show Store tab in navigation'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => 'Check for Updates'; @@ -296,7 +296,7 @@ class AppLocalizationsHi extends AppLocalizations { String get extensionsUninstall => 'Uninstall'; @override - String get storeTitle => 'Extension Store'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => 'Search extensions...'; @@ -1336,7 +1336,7 @@ class AppLocalizationsHi extends AppLocalizations { String get storeEmptyNoResults => 'No extensions found'; @override - String get extensionDefaultProvider => 'Default (Deezer/Spotify)'; + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Use built-in search'; @@ -2114,7 +2114,7 @@ class AppLocalizationsHi extends AppLocalizations { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -2395,7 +2395,8 @@ class AppLocalizationsHi extends AppLocalizations { String get trackConvertFormat => 'Convert Format'; @override - String get trackConvertFormatSubtitle => 'Convert to MP3 or Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart index 9ff2757..5407881 100644 --- a/lib/l10n/app_localizations_id.dart +++ b/lib/l10n/app_localizations_id.dart @@ -27,8 +27,7 @@ class AppLocalizationsId extends AppLocalizations { String get homeTitle => 'Beranda'; @override - String get homeSubtitle => - 'Tempel URL yang didukung atau cari berdasarkan nama'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => 'Mendukung: URL Track, Album, Playlist, Artis'; @@ -130,11 +129,11 @@ class AppLocalizationsId extends AppLocalizations { } @override - String get optionsDefaultSearchTab => 'Tab Pencarian Default'; + String get optionsDefaultSearchTab => 'Default Search Tab'; @override String get optionsDefaultSearchTabSubtitle => - 'Pilih tab yang dibuka lebih dulu untuk hasil pencarian baru.'; + 'Choose which tab opens first for new search results.'; @override String get optionsSwitchBack => @@ -220,10 +219,10 @@ class AppLocalizationsId extends AppLocalizations { 'Unduhan paralel dapat memicu pembatasan rate'; @override - String get optionsExtensionStore => 'Repo Ekstensi'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => 'Tampilkan tab Repo di navigasi'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => 'Periksa Pembaruan'; @@ -299,7 +298,7 @@ class AppLocalizationsId extends AppLocalizations { String get extensionsUninstall => 'Copot'; @override - String get storeTitle => 'Repo Ekstensi'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => 'Cari ekstensi...'; @@ -745,15 +744,15 @@ class AppLocalizationsId extends AppLocalizations { String get errorNoTracksFound => 'Tidak ada lagu ditemukan'; @override - String get errorUrlNotRecognized => 'Link tidak dikenali'; + String get errorUrlNotRecognized => 'Tautan tidak dikenali'; @override String get errorUrlNotRecognizedMessage => - 'Link ini tidak didukung. Pastikan URL benar dan ekstensi yang kompatibel sudah terpasang.'; + 'Tautan ini tidak didukung. Pastikan URL sudah benar dan ekstensi yang kompatibel telah terpasang.'; @override String get errorUrlFetchFailed => - 'Gagal memuat konten dari link ini. Silakan coba lagi.'; + 'Konten dari tautan ini gagal dimuat. Silakan coba lagi.'; @override String errorMissingExtensionSource(String item) { @@ -941,15 +940,15 @@ class AppLocalizationsId extends AppLocalizations { 'Jika lagu tidak tersedia di provider pertama, aplikasi akan otomatis mencoba yang berikutnya.'; @override - String get providerPriorityFallbackExtensionsTitle => 'Fallback Ekstensi'; + String get providerPriorityFallbackExtensionsTitle => 'Extension Fallback'; @override String get providerPriorityFallbackExtensionsDescription => - 'Pilih ekstensi unduhan terpasang mana yang boleh dipakai saat fallback otomatis. Provider bawaan tetap mengikuti urutan prioritas di atas.'; + 'Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.'; @override String get providerPriorityFallbackExtensionsHint => - 'Hanya ekstensi aktif dengan kemampuan download provider yang ditampilkan di sini.'; + 'Only enabled extensions with download-provider capability are listed here.'; @override String get providerBuiltIn => 'Bawaan'; @@ -1334,7 +1333,7 @@ class AppLocalizationsId extends AppLocalizations { String get storeNewRepoUrlLabel => 'New Repository URL'; @override - String get storeLoadError => 'Gagal memuat repo'; + String get storeLoadError => 'Failed to load repository'; @override String get storeEmptyNoExtensions => 'No extensions available'; @@ -1343,7 +1342,7 @@ class AppLocalizationsId extends AppLocalizations { String get storeEmptyNoResults => 'No extensions found'; @override - String get extensionDefaultProvider => 'Bawaan (Deezer/Spotify)'; + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Gunakan pencarian bawaan'; @@ -1449,7 +1448,7 @@ class AppLocalizationsId extends AppLocalizations { @override String get extensionsFallbackSubtitle => - 'Pilih ekstensi unduhan terpasang yang boleh dipakai saat fallback'; + 'Choose which installed download extensions can be used as fallback'; @override String get extensionsNoDownloadProvider => @@ -2124,7 +2123,7 @@ class AppLocalizationsId extends AppLocalizations { @override String get tutorialExtensionsTip1 => - 'Buka tab Repo untuk menemukan ekstensi yang berguna'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -2375,25 +2374,25 @@ class AppLocalizationsId extends AppLocalizations { String get trackReEnrichFfmpegFailed => 'FFmpeg metadata embed failed'; @override - String get queueFlacAction => 'Antrekan FLAC'; + String get queueFlacAction => 'Queue FLAC'; @override String queueFlacConfirmMessage(int count) { - return 'Cari kecocokan online untuk track yang dipilih lalu antrekan download FLAC.\n\nFile yang sudah ada tidak akan diubah atau dihapus.\n\nHanya kecocokan dengan keyakinan tinggi yang akan diantrikan otomatis.\n\n$count dipilih'; + return 'Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n$count selected'; } @override String queueFlacFindingProgress(int current, int total) { - return 'Mencari kecocokan FLAC... ($current/$total)'; + return 'Finding FLAC matches... ($current/$total)'; } @override String get queueFlacNoReliableMatches => - 'Tidak ada kecocokan online yang cukup meyakinkan untuk pilihan ini'; + 'No reliable online matches found for the selection'; @override String queueFlacQueuedWithSkipped(int addedCount, int skippedCount) { - return 'Menambahkan $addedCount track ke antrean, melewati $skippedCount'; + return 'Added $addedCount tracks to queue, skipped $skippedCount'; } @override @@ -2406,7 +2405,7 @@ class AppLocalizationsId extends AppLocalizations { @override String get trackConvertFormatSubtitle => - 'Konversi ke MP3, Opus, ALAC, atau FLAC'; + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; @@ -2434,12 +2433,12 @@ class AppLocalizationsId extends AppLocalizations { String sourceFormat, String targetFormat, ) { - return 'Konversi dari $sourceFormat ke $targetFormat? (Lossless — tanpa kehilangan kualitas)\n\nFile asli akan dihapus setelah konversi.'; + return 'Convert from $sourceFormat to $targetFormat? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.'; } @override String get trackConvertLosslessHint => - 'Konversi lossless — tanpa kehilangan kualitas'; + 'Lossless conversion — no quality loss'; @override String get trackConvertConverting => 'Converting audio...'; @@ -2893,19 +2892,19 @@ class AppLocalizationsId extends AppLocalizations { @override String get downloadCreatePlaylistSourceFolder => - 'Buat folder sumber playlist'; + 'Create playlist source folder'; @override String get downloadCreatePlaylistSourceFolderEnabled => - 'Unduhan dari playlist memakai Playlist/ lalu struktur folder normal Anda.'; + 'Playlist downloads use Playlist/ plus your normal folder structure.'; @override String get downloadCreatePlaylistSourceFolderDisabled => - 'Unduhan dari playlist hanya memakai struktur folder normal.'; + 'Playlist downloads use the normal folder structure only.'; @override String get downloadCreatePlaylistSourceFolderRedundant => - 'Mode Berdasarkan Playlist sudah menaruh unduhan ke dalam folder playlist.'; + 'By Playlist already places downloads inside a playlist folder.'; @override String get downloadSongLinkRegion => 'SongLink Region'; diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index baa3777..030e46e 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -21,13 +21,13 @@ class AppLocalizationsJa extends AppLocalizations { String get navSettings => '設定'; @override - String get navStore => 'ストア'; + String get navStore => 'Repo'; @override String get homeTitle => 'ホーム'; @override - String get homeSubtitle => 'Spotify のリンクを貼り付けるか、名前で検索します'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => 'サポート: トラック、アルバム、プレイリスト、アーティスト、URL'; @@ -214,10 +214,10 @@ class AppLocalizationsJa extends AppLocalizations { 'Parallel downloads may trigger rate limiting'; @override - String get optionsExtensionStore => '拡張ストア'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => 'ナビゲーションにストアタブを表示'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => '更新を確認'; @@ -293,7 +293,7 @@ class AppLocalizationsJa extends AppLocalizations { String get extensionsUninstall => 'アンインストール'; @override - String get storeTitle => '拡張ストア'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => '拡張を検索...'; @@ -1330,7 +1330,7 @@ class AppLocalizationsJa extends AppLocalizations { String get storeEmptyNoResults => 'No extensions found'; @override - String get extensionDefaultProvider => 'デフォルト (Deezer/Spotify)'; + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => '内蔵の検索を使用する'; @@ -2101,7 +2101,7 @@ class AppLocalizationsJa extends AppLocalizations { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -2382,7 +2382,8 @@ class AppLocalizationsJa extends AppLocalizations { String get trackConvertFormat => '変換の形式'; @override - String get trackConvertFormatSubtitle => 'MP3 または Opus に変換'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'オーディオを変換'; diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index b7f0100..7168341 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -21,13 +21,13 @@ class AppLocalizationsKo extends AppLocalizations { String get navSettings => 'Settings'; @override - String get navStore => 'Store'; + String get navStore => 'Repo'; @override String get homeTitle => 'Home'; @override - String get homeSubtitle => 'Spotify URL을 붙여 넣거나 검색'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => '지원 항목: 트랙, 앨범, 플레이리스트, 아티스트 URLs'; @@ -209,10 +209,10 @@ class AppLocalizationsKo extends AppLocalizations { String get optionsConcurrentWarning => '동시에 다수의 음반을 다운로드하면 속도 제한이 발생할 수 있습니다'; @override - String get optionsExtensionStore => '확장 기능 스토어'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => '탐색 메뉴에 스토어 탭 표시'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => '업데이트 확인'; @@ -286,7 +286,7 @@ class AppLocalizationsKo extends AppLocalizations { String get extensionsUninstall => '삭제'; @override - String get storeTitle => '확장 기능 스토어'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => '확장 기능 검색'; @@ -1316,7 +1316,7 @@ class AppLocalizationsKo extends AppLocalizations { String get storeEmptyNoResults => 'No extensions found'; @override - String get extensionDefaultProvider => 'Default (Deezer/Spotify)'; + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Use built-in search'; @@ -2094,7 +2094,7 @@ class AppLocalizationsKo extends AppLocalizations { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -2375,7 +2375,8 @@ class AppLocalizationsKo extends AppLocalizations { String get trackConvertFormat => 'Convert Format'; @override - String get trackConvertFormatSubtitle => 'Convert to MP3 or Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index d89b315..7f82b11 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -21,13 +21,13 @@ class AppLocalizationsNl extends AppLocalizations { String get navSettings => 'Settings'; @override - String get navStore => 'Store'; + String get navStore => 'Repo'; @override String get homeTitle => 'Home'; @override - String get homeSubtitle => 'Paste a Spotify link or search by name'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => 'Supports: Track, Album, Playlist, Artist URLs'; @@ -216,10 +216,10 @@ class AppLocalizationsNl extends AppLocalizations { 'Parallel downloaden kan leiden tot rate-limiting'; @override - String get optionsExtensionStore => 'Extension Store'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => 'Show Store tab in navigation'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => 'Check for Updates'; @@ -296,7 +296,7 @@ class AppLocalizationsNl extends AppLocalizations { String get extensionsUninstall => 'Uninstall'; @override - String get storeTitle => 'Extension Store'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => 'Search extensions...'; @@ -1336,7 +1336,7 @@ class AppLocalizationsNl extends AppLocalizations { String get storeEmptyNoResults => 'No extensions found'; @override - String get extensionDefaultProvider => 'Default (Deezer/Spotify)'; + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Use built-in search'; @@ -2114,7 +2114,7 @@ class AppLocalizationsNl extends AppLocalizations { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -2395,7 +2395,8 @@ class AppLocalizationsNl extends AppLocalizations { String get trackConvertFormat => 'Convert Format'; @override - String get trackConvertFormatSubtitle => 'Convert to MP3 or Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index cd81ead..65283f0 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -3436,13 +3436,13 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get navSettings => 'Configurações'; @override - String get navStore => 'Loja'; + String get navStore => 'Repo'; @override String get homeTitle => 'Início'; @override - String get homeSubtitle => 'Cole um link do Spotify ou procure por nome'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => @@ -3491,6 +3491,13 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get downloadFilenameFormat => 'Formato do Nome do Arquivo'; + @override + String get downloadSingleFilenameFormat => 'Single Filename Format'; + + @override + String get downloadSingleFilenameFormatDescription => + 'Filename pattern for singles and EPs. Uses the same tags as the album format.'; + @override String get downloadFolderOrganization => 'Organização de Pastas'; @@ -3537,6 +3544,13 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { return 'Usando a extensão: $extensionName'; } + @override + String get optionsDefaultSearchTab => 'Default Search Tab'; + + @override + String get optionsDefaultSearchTabSubtitle => + 'Choose which tab opens first for new search results.'; + @override String get optionsSwitchBack => 'Toque no Deezer ou Spotify para alternar de volta da extensão'; @@ -3573,6 +3587,38 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get optionsMaxQualityCoverSubtitle => 'Baixar capa do álbum com a mais alta resolução'; + @override + String get optionsReplayGain => 'ReplayGain'; + + @override + String get optionsReplayGainSubtitleOn => + 'Scan loudness and embed ReplayGain tags (EBU R128)'; + + @override + String get optionsReplayGainSubtitleOff => + 'Disabled: no loudness normalization tags'; + + @override + String get optionsArtistTagMode => 'Artist Tag Mode'; + + @override + String get optionsArtistTagModeDescription => + 'Choose how multiple artists are written into embedded tags.'; + + @override + String get optionsArtistTagModeJoined => 'Single joined value'; + + @override + String get optionsArtistTagModeJoinedSubtitle => + 'Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.'; + + @override + String get optionsArtistTagModeSplitVorbis => 'Split tags for FLAC/Opus'; + + @override + String get optionsArtistTagModeSplitVorbisSubtitle => + 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; + @override String get optionsConcurrentDownloads => 'Downloads Simultâneos'; @@ -3589,11 +3635,10 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { 'Downloads simultâneos podem causar um limite da taxa (ratelimit)'; @override - String get optionsExtensionStore => 'Loja de Extensões'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => - 'Mostrar aba da Loja na navegação'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => 'Procurar Atualizações'; @@ -3672,7 +3717,7 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get extensionsUninstall => 'Desinstalar'; @override - String get storeTitle => 'Loja de Extensões'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => 'Pesquisar extensões...'; @@ -3953,6 +3998,9 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get dialogImport => 'Importar'; + @override + String get dialogDownload => 'Download'; + @override String get dialogDiscard => 'Descartar'; @@ -4185,6 +4233,36 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get searchPlaylists => 'Playlists'; + @override + String get searchSortTitle => 'Sort Results'; + + @override + String get searchSortDefault => 'Default'; + + @override + String get searchSortTitleAZ => 'Title (A-Z)'; + + @override + String get searchSortTitleZA => 'Title (Z-A)'; + + @override + String get searchSortArtistAZ => 'Artist (A-Z)'; + + @override + String get searchSortArtistZA => 'Artist (Z-A)'; + + @override + String get searchSortDurationShort => 'Duration (Shortest)'; + + @override + String get searchSortDurationLong => 'Duration (Longest)'; + + @override + String get searchSortDateOldest => 'Release Date (Oldest)'; + + @override + String get searchSortDateNewest => 'Release Date (Newest)'; + @override String get tooltipPlay => 'Reproduzir'; @@ -4284,6 +4362,17 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get providerPriorityInfo => 'Se uma faixa não estiver disponível no primeiro provedor, o aplicativo irá tentar automaticamente a próxima.'; + @override + String get providerPriorityFallbackExtensionsTitle => 'Extension Fallback'; + + @override + String get providerPriorityFallbackExtensionsDescription => + 'Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.'; + + @override + String get providerPriorityFallbackExtensionsHint => + 'Only enabled extensions with download-provider capability are listed here.'; + @override String get providerBuiltIn => 'Embutido'; @@ -4563,6 +4652,12 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get trackLyricsNotAvailable => 'Letra não disponível para esta faixa'; + @override + String get trackLyricsNotInFile => 'No lyrics found in this file'; + + @override + String get trackFetchOnlineLyrics => 'Fetch from Online'; + @override String get trackLyricsTimeout => 'A solicitação expirou. Tente novamente mais tarde.'; @@ -4632,7 +4727,48 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get storeClearFilters => 'Limpar filtros'; @override - String get extensionDefaultProvider => 'Padrão (Deezer/Spotify)'; + String get storeAddRepoTitle => 'Add Extension Repository'; + + @override + String get storeAddRepoDescription => + 'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.'; + + @override + String get storeRepoUrlLabel => 'Repository URL'; + + @override + String get storeRepoUrlHint => 'https://github.com/user/repo'; + + @override + String get storeRepoUrlHelper => + 'e.g. https://github.com/user/extensions-repo'; + + @override + String get storeAddRepoButton => 'Add Repository'; + + @override + String get storeChangeRepoTooltip => 'Change repository'; + + @override + String get storeRepoDialogTitle => 'Extension Repository'; + + @override + String get storeRepoDialogCurrent => 'Current repository:'; + + @override + String get storeNewRepoUrlLabel => 'New Repository URL'; + + @override + String get storeLoadError => 'Failed to load repository'; + + @override + String get storeEmptyNoExtensions => 'No extensions available'; + + @override + String get storeEmptyNoResults => 'No extensions found'; + + @override + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Usar pesquisa integrada'; @@ -4734,6 +4870,13 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get extensionsDownloadPrioritySubtitle => 'Definir ordem do serviço de download'; + @override + String get extensionsFallbackTitle => 'Fallback Extensions'; + + @override + String get extensionsFallbackSubtitle => + 'Choose which installed download extensions can be used as fallback'; + @override String get extensionsNoDownloadProvider => 'Nenhuma extensão com provedor de download'; @@ -4784,6 +4927,38 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get qualityHiResFlacMaxSubtitle => '24-bit / até 192kHz'; + @override + String get downloadLossy320 => 'Lossy 320kbps'; + + @override + String get downloadLossyFormat => 'Lossy Format'; + + @override + String get downloadLossy320Format => 'Lossy 320kbps Format'; + + @override + String get downloadLossy320FormatDesc => + 'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.'; + + @override + String get downloadLossyMp3 => 'MP3 320kbps'; + + @override + String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track'; + + @override + String get downloadLossyOpus256 => 'Opus 256kbps'; + + @override + String get downloadLossyOpus256Subtitle => + 'Best quality Opus, ~8MB per track'; + + @override + String get downloadLossyOpus128 => 'Opus 128kbps'; + + @override + String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track'; + @override String get qualityNote => 'A qualidade real depende da faixa que estiver disponível no serviço'; @@ -4886,6 +5061,13 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get albumFolderArtistAlbumSinglesSubtitle => 'Artista/Álbum/ e Artista/Singles/'; + @override + String get albumFolderArtistAlbumFlat => 'Artist / Album (Singles flat)'; + + @override + String get albumFolderArtistAlbumFlatSubtitle => + 'Artist/Album/ and Artist/song.flac'; + @override String get downloadedAlbumDeleteSelected => 'Apagar Selecionados'; @@ -5081,6 +5263,25 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get libraryShowDuplicateIndicatorSubtitle => 'Show when searching for existing tracks'; + @override + String get libraryAutoScan => 'Auto Scan'; + + @override + String get libraryAutoScanSubtitle => + 'Automatically scan your library for new files'; + + @override + String get libraryAutoScanOff => 'Off'; + + @override + String get libraryAutoScanOnOpen => 'Every app open'; + + @override + String get libraryAutoScanDaily => 'Daily'; + + @override + String get libraryAutoScanWeekly => 'Weekly'; + @override String get libraryActions => 'Actions'; @@ -5131,6 +5332,17 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { return '$_temp0'; } + @override + String libraryFilesUnit(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'files', + one: 'file', + ); + return '$_temp0'; + } + @override String libraryLastScanned(String time) { return 'Last scanned: $time'; @@ -5142,6 +5354,9 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get libraryScanning => 'Scanning...'; + @override + String get libraryScanFinalizing => 'Finalizing library...'; + @override String libraryScanProgress(String progress, int total) { return '$progress% of $total files'; @@ -5210,6 +5425,24 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get libraryFilterFormat => 'Format'; + @override + String get libraryFilterMetadata => 'Metadata'; + + @override + String get libraryFilterMetadataComplete => 'Complete metadata'; + + @override + String get libraryFilterMetadataMissingAny => 'Missing any metadata'; + + @override + String get libraryFilterMetadataMissingYear => 'Missing year'; + + @override + String get libraryFilterMetadataMissingGenre => 'Missing genre'; + + @override + String get libraryFilterMetadataMissingAlbumArtist => 'Missing album artist'; + @override String get libraryFilterSort => 'Sort'; @@ -5219,6 +5452,18 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get libraryFilterSortOldest => 'Oldest'; + @override + String get libraryFilterSortAlbumAsc => 'Album (A-Z)'; + + @override + String get libraryFilterSortAlbumDesc => 'Album (Z-A)'; + + @override + String get libraryFilterSortGenreAsc => 'Genre (A-Z)'; + + @override + String get libraryFilterSortGenreDesc => 'Genre (Z-A)'; + @override String get timeJustNow => 'Just now'; @@ -5305,7 +5550,7 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -5503,6 +5748,30 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get trackReEnrichOnlineSubtitle => 'Search metadata online and embed into file'; + @override + String get trackReEnrichFieldsTitle => 'Fields to update'; + + @override + String get trackReEnrichFieldCover => 'Cover Art'; + + @override + String get trackReEnrichFieldLyrics => 'Lyrics'; + + @override + String get trackReEnrichFieldBasicTags => 'Album, Album Artist'; + + @override + String get trackReEnrichFieldTrackInfo => 'Track & Disc Number'; + + @override + String get trackReEnrichFieldReleaseInfo => 'Date & ISRC'; + + @override + String get trackReEnrichFieldExtra => 'Genre, Label, Copyright'; + + @override + String get trackReEnrichSelectAll => 'Select All'; + @override String get trackEditMetadata => 'Edit Metadata'; @@ -5531,6 +5800,28 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get trackReEnrichFfmpegFailed => 'FFmpeg metadata embed failed'; + @override + String get queueFlacAction => 'Queue FLAC'; + + @override + String queueFlacConfirmMessage(int count) { + return 'Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n$count selected'; + } + + @override + String queueFlacFindingProgress(int current, int total) { + return 'Finding FLAC matches... ($current/$total)'; + } + + @override + String get queueFlacNoReliableMatches => + 'No reliable online matches found for the selection'; + + @override + String queueFlacQueuedWithSkipped(int addedCount, int skippedCount) { + return 'Added $addedCount tracks to queue, skipped $skippedCount'; + } + @override String trackSaveFailed(String error) { return 'Failed: $error'; @@ -5540,7 +5831,8 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get trackConvertFormat => 'Convert Format'; @override - String get trackConvertFormatSubtitle => 'Convert to MP3 or Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; @@ -5563,6 +5855,18 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { return 'Convert from $sourceFormat to $targetFormat at $bitrate?\n\nThe original file will be deleted after conversion.'; } + @override + String trackConvertConfirmMessageLossless( + String sourceFormat, + String targetFormat, + ) { + return 'Convert from $sourceFormat to $targetFormat? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.'; + } + + @override + String get trackConvertLosslessHint => + 'Lossless conversion — no quality loss'; + @override String get trackConvertConverting => 'Converting audio...'; @@ -5816,6 +6120,17 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { return 'Convert $count $_temp0 to $format at $bitrate?\n\nOriginal files will be deleted after conversion.'; } + @override + String selectionBatchConvertConfirmMessageLossless(int count, String format) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Convert $count $_temp0 to $format? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.'; + } + @override String selectionBatchConvertProgress(int current, int total) { return 'Converting $current of $total...'; @@ -5838,4 +6153,704 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { @override String get downloadUseAlbumArtistForFoldersTrackSubtitle => 'Artist folders use Track Artist only'; + + @override + String get lyricsProvidersTitle => 'Lyrics Providers'; + + @override + String get lyricsProvidersDescription => + 'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.'; + + @override + String get lyricsProvidersInfoText => + 'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.'; + + @override + String lyricsProvidersEnabledSection(int count) { + return 'Enabled ($count)'; + } + + @override + String lyricsProvidersDisabledSection(int count) { + return 'Disabled ($count)'; + } + + @override + String get lyricsProvidersAtLeastOne => + 'At least one provider must remain enabled'; + + @override + String get lyricsProvidersSaved => 'Lyrics provider priority saved'; + + @override + String get lyricsProvidersDiscardContent => + 'You have unsaved changes that will be lost.'; + + @override + String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database'; + + @override + String get lyricsProviderNeteaseDesc => + 'NetEase Cloud Music (good for Asian songs)'; + + @override + String get lyricsProviderMusixmatchDesc => + 'Largest lyrics database (multi-language)'; + + @override + String get lyricsProviderAppleMusicDesc => + 'Word-by-word synced lyrics (via proxy)'; + + @override + String get lyricsProviderQqMusicDesc => + 'QQ Music (good for Chinese songs, via proxy)'; + + @override + String get lyricsProviderExtensionDesc => 'Extension provider'; + + @override + String get safMigrationTitle => 'Storage Update Required'; + + @override + String get safMigrationMessage1 => + 'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.'; + + @override + String get safMigrationMessage2 => + 'Please select your download folder again to switch to the new storage system.'; + + @override + String get safMigrationSuccess => 'Download folder updated to SAF mode'; + + @override + String get settingsDonate => 'Donate'; + + @override + String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development'; + + @override + String get tooltipLoveAll => 'Love All'; + + @override + String get tooltipAddToPlaylist => 'Add to Playlist'; + + @override + String snackbarRemovedTracksFromLoved(int count) { + return 'Removed $count tracks from Loved'; + } + + @override + String snackbarAddedTracksToLoved(int count) { + return 'Added $count tracks to Loved'; + } + + @override + String get dialogDownloadAllTitle => 'Download All'; + + @override + String dialogDownloadAllMessage(int count) { + return 'Download $count tracks?'; + } + + @override + String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs'; + + @override + String get homeGoToAlbum => 'Go to Album'; + + @override + String get homeAlbumInfoUnavailable => 'Album info not available'; + + @override + String get snackbarLoadingCueSheet => 'Loading CUE sheet...'; + + @override + String get snackbarMetadataSaved => 'Metadata saved successfully'; + + @override + String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics'; + + @override + String get snackbarFailedToWriteStorage => 'Failed to write back to storage'; + + @override + String snackbarError(String error) { + return 'Error: $error'; + } + + @override + String get snackbarNoActionDefined => 'No action defined for this button'; + + @override + String get noTracksFoundForAlbum => 'No tracks found for this album'; + + @override + String get downloadLocationSubtitle => + 'Choose storage mode for downloaded files.'; + + @override + String get storageModeAppFolder => 'App folder (non-SAF)'; + + @override + String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path'; + + @override + String get storageModeSaf => 'SAF folder'; + + @override + String get storageModeSafSubtitle => + 'Pick folder via Android Storage Access Framework'; + + @override + String get downloadFilenameDescription => + 'Customize how your files are named.'; + + @override + String get downloadFilenameInsertTag => 'Tap to insert tag:'; + + @override + String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders'; + + @override + String get downloadSeparateSinglesDisabled => 'All files in same structure'; + + @override + String get downloadArtistNameFilters => 'Artist Name Filters'; + + @override + String get downloadCreatePlaylistSourceFolder => + 'Create playlist source folder'; + + @override + String get downloadCreatePlaylistSourceFolderEnabled => + 'Playlist downloads use Playlist/ plus your normal folder structure.'; + + @override + String get downloadCreatePlaylistSourceFolderDisabled => + 'Playlist downloads use the normal folder structure only.'; + + @override + String get downloadCreatePlaylistSourceFolderRedundant => + 'By Playlist already places downloads inside a playlist folder.'; + + @override + String get downloadSongLinkRegion => 'SongLink Region'; + + @override + String get downloadNetworkCompatibilityMode => 'Network compatibility mode'; + + @override + String get downloadNetworkCompatibilityModeEnabled => + 'Enabled: try HTTP + accept invalid TLS certificates (unsafe)'; + + @override + String get downloadNetworkCompatibilityModeDisabled => + 'Off: strict HTTPS certificate validation (recommended)'; + + @override + String get downloadSelectServiceToEnable => + 'Select a built-in service to enable'; + + @override + String get downloadSelectTidalQobuz => + 'Select Tidal or Qobuz above to configure quality'; + + @override + String get downloadEmbedLyricsDisabled => + 'Disabled while Embed Metadata is turned off'; + + @override + String get downloadNeteaseIncludeTranslation => + 'Netease: Include Translation'; + + @override + String get downloadNeteaseIncludeTranslationEnabled => + 'Append translated lyrics when available'; + + @override + String get downloadNeteaseIncludeTranslationDisabled => + 'Use original lyrics only'; + + @override + String get downloadNeteaseIncludeRomanization => + 'Netease: Include Romanization'; + + @override + String get downloadNeteaseIncludeRomanizationEnabled => + 'Append romanized lyrics when available'; + + @override + String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled'; + + @override + String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word'; + + @override + String get downloadAppleQqMultiPersonEnabled => + 'Enable v1/v2 speaker and [bg:] tags'; + + @override + String get downloadAppleQqMultiPersonDisabled => + 'Simplified word-by-word formatting'; + + @override + String get downloadMusixmatchLanguage => 'Musixmatch Language'; + + @override + String get downloadMusixmatchLanguageAuto => 'Auto (original)'; + + @override + String get downloadFilterContributing => + 'Filter contributing artists in Album Artist'; + + @override + String get downloadFilterContributingEnabled => + 'Album Artist metadata uses primary artist only'; + + @override + String get downloadFilterContributingDisabled => + 'Keep full Album Artist metadata value'; + + @override + String get downloadProvidersNoneEnabled => 'None enabled'; + + @override + String get downloadMusixmatchLanguageCode => 'Language code'; + + @override + String get downloadMusixmatchLanguageHint => 'auto / en / es / ja'; + + @override + String get downloadMusixmatchLanguageDesc => + 'Set preferred language code (example: en, es, ja). Leave empty for auto.'; + + @override + String get downloadMusixmatchAuto => 'Auto'; + + @override + String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data'; + + @override + String get downloadNetworkWifiOnlySubtitle => + 'Pause downloads on mobile data'; + + @override + String get downloadSongLinkRegionDesc => + 'Used as userCountry for SongLink API lookup.'; + + @override + String get snackbarUnsupportedAudioFormat => 'Unsupported audio format'; + + @override + String get cacheRefresh => 'Refresh'; + + @override + String dialogDownloadPlaylistsMessage(int trackCount, int playlistCount) { + String _temp0 = intl.Intl.pluralLogic( + trackCount, + locale: localeName, + other: 'tracks', + one: 'track', + ); + String _temp1 = intl.Intl.pluralLogic( + playlistCount, + locale: localeName, + other: 'playlists', + one: 'playlist', + ); + return 'Download $trackCount $_temp0 from $playlistCount $_temp1?'; + } + + @override + String bulkDownloadPlaylistsButton(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'playlists', + one: 'playlist', + ); + return 'Download $count $_temp0'; + } + + @override + String get bulkDownloadSelectPlaylists => 'Select playlists to download'; + + @override + String get snackbarSelectedPlaylistsEmpty => + 'Selected playlists have no tracks'; + + @override + String playlistsCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count playlists', + one: '1 playlist', + ); + return '$_temp0'; + } + + @override + String get editMetadataAutoFill => 'Auto-fill from online'; + + @override + String get editMetadataAutoFillDesc => + 'Select fields to fill automatically from online metadata'; + + @override + String get editMetadataAutoFillFetch => 'Fetch & Fill'; + + @override + String get editMetadataAutoFillSearching => 'Searching online...'; + + @override + String get editMetadataAutoFillNoResults => + 'No matching metadata found online'; + + @override + String editMetadataAutoFillDone(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'fields', + one: 'field', + ); + return 'Filled $count $_temp0 from online metadata'; + } + + @override + String get editMetadataAutoFillNoneSelected => + 'Select at least one field to auto-fill'; + + @override + String get editMetadataFieldTitle => 'Title'; + + @override + String get editMetadataFieldArtist => 'Artist'; + + @override + String get editMetadataFieldAlbum => 'Album'; + + @override + String get editMetadataFieldAlbumArtist => 'Album Artist'; + + @override + String get editMetadataFieldDate => 'Date'; + + @override + String get editMetadataFieldTrackNum => 'Track #'; + + @override + String get editMetadataFieldDiscNum => 'Disc #'; + + @override + String get editMetadataFieldGenre => 'Genre'; + + @override + String get editMetadataFieldIsrc => 'ISRC'; + + @override + String get editMetadataFieldLabel => 'Label'; + + @override + String get editMetadataFieldCopyright => 'Copyright'; + + @override + String get editMetadataFieldCover => 'Cover Art'; + + @override + String get editMetadataSelectAll => 'All'; + + @override + String get editMetadataSelectEmpty => 'Empty only'; + + @override + String queueDownloadingCount(int count) { + return 'Downloading ($count)'; + } + + @override + String get queueDownloadedHeader => 'Downloaded'; + + @override + String get queueFilteringIndicator => 'Filtering...'; + + @override + String queueTrackCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count tracks', + one: '1 track', + ); + return '$_temp0'; + } + + @override + String queueAlbumCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count albums', + one: '1 album', + ); + return '$_temp0'; + } + + @override + String get queueEmptyAlbums => 'No album downloads'; + + @override + String get queueEmptyAlbumsSubtitle => + 'Download multiple tracks from an album to see them here'; + + @override + String get queueEmptySingles => 'No single downloads'; + + @override + String get queueEmptySinglesSubtitle => + 'Single track downloads will appear here'; + + @override + String get queueEmptyHistory => 'No download history'; + + @override + String get queueEmptyHistorySubtitle => 'Downloaded tracks will appear here'; + + @override + String get selectionAllPlaylistsSelected => 'All playlists selected'; + + @override + String get selectionTapPlaylistsToSelect => 'Tap playlists to select'; + + @override + String get selectionSelectPlaylistsToDelete => 'Select playlists to delete'; + + @override + String get audioAnalysisTitle => 'Audio Quality Analysis'; + + @override + String get audioAnalysisDescription => + 'Verify lossless quality with spectrum analysis'; + + @override + String get audioAnalysisAnalyzing => 'Analyzing audio...'; + + @override + String get audioAnalysisSampleRate => 'Sample Rate'; + + @override + String get audioAnalysisBitDepth => 'Bit Depth'; + + @override + String get audioAnalysisChannels => 'Channels'; + + @override + String get audioAnalysisDuration => 'Duration'; + + @override + String get audioAnalysisNyquist => 'Nyquist'; + + @override + String get audioAnalysisFileSize => 'Size'; + + @override + String get audioAnalysisDynamicRange => 'Dynamic Range'; + + @override + String get audioAnalysisPeak => 'Peak'; + + @override + String get audioAnalysisRms => 'RMS'; + + @override + String get audioAnalysisSamples => 'Samples'; + + @override + String extensionsSearchWith(String providerName) { + return 'Search with $providerName'; + } + + @override + String get extensionsHomeFeedProvider => 'Home Feed Provider'; + + @override + String get extensionsHomeFeedDescription => + 'Choose which extension provides the home feed on the main screen'; + + @override + String get extensionsHomeFeedAuto => 'Auto'; + + @override + String get extensionsHomeFeedAutoSubtitle => + 'Automatically select the best available'; + + @override + String extensionsHomeFeedUse(String extensionName) { + return 'Use $extensionName home feed'; + } + + @override + String get extensionsNoHomeFeedExtensions => 'No extensions with home feed'; + + @override + String get sortAlphaAsc => 'A-Z'; + + @override + String get sortAlphaDesc => 'Z-A'; + + @override + String get cancelDownloadTitle => 'Cancel download?'; + + @override + String cancelDownloadContent(String trackName) { + return 'This will cancel the active download for \"$trackName\".'; + } + + @override + String get cancelDownloadKeep => 'Keep'; + + @override + String get metadataSaveFailedFfmpeg => 'Failed to save metadata via FFmpeg'; + + @override + String get metadataSaveFailedStorage => + 'Failed to write metadata back to storage'; + + @override + String snackbarFolderPickerFailed(String error) { + return 'Failed to open folder picker: $error'; + } + + @override + String get errorLoadAlbum => 'Failed to load album'; + + @override + String get errorLoadPlaylist => 'Failed to load playlist'; + + @override + String get errorLoadArtist => 'Failed to load artist'; + + @override + String get notifChannelDownloadName => 'Download Progress'; + + @override + String get notifChannelDownloadDesc => 'Shows download progress for tracks'; + + @override + String get notifChannelLibraryScanName => 'Library Scan'; + + @override + String get notifChannelLibraryScanDesc => 'Shows local library scan progress'; + + @override + String notifDownloadingTrack(String trackName) { + return 'Downloading $trackName'; + } + + @override + String notifFinalizingTrack(String trackName) { + return 'Finalizing $trackName'; + } + + @override + String get notifEmbeddingMetadata => 'Embedding metadata...'; + + @override + String notifAlreadyInLibraryCount(int completed, int total) { + return 'Already in Library ($completed/$total)'; + } + + @override + String get notifAlreadyInLibrary => 'Already in Library'; + + @override + String notifDownloadCompleteCount(int completed, int total) { + return 'Download Complete ($completed/$total)'; + } + + @override + String get notifDownloadComplete => 'Download Complete'; + + @override + String notifDownloadsFinished(int completed, int failed) { + return 'Downloads Finished ($completed done, $failed failed)'; + } + + @override + String get notifAllDownloadsComplete => 'All Downloads Complete'; + + @override + String notifTracksDownloadedSuccess(int count) { + return '$count tracks downloaded successfully'; + } + + @override + String get notifScanningLibrary => 'Scanning local library'; + + @override + String notifLibraryScanProgressWithTotal( + int scanned, + int total, + int percentage, + ) { + return '$scanned/$total files • $percentage%'; + } + + @override + String notifLibraryScanProgressNoTotal(int scanned, int percentage) { + return '$scanned files scanned • $percentage%'; + } + + @override + String get notifLibraryScanComplete => 'Library scan complete'; + + @override + String notifLibraryScanCompleteBody(int count) { + return '$count tracks indexed'; + } + + @override + String notifLibraryScanExcluded(int count) { + return '$count excluded'; + } + + @override + String notifLibraryScanErrors(int count) { + return '$count errors'; + } + + @override + String get notifLibraryScanFailed => 'Library scan failed'; + + @override + String get notifLibraryScanCancelled => 'Library scan cancelled'; + + @override + String get notifLibraryScanStopped => 'Scan stopped before completion.'; + + @override + String notifDownloadingUpdate(String version) { + return 'Downloading SpotiFLAC v$version'; + } + + @override + String notifUpdateProgress(String received, String total, int percentage) { + return '$received / $total MB • $percentage%'; + } + + @override + String get notifUpdateReady => 'Update Ready'; + + @override + String notifUpdateReadyBody(String version) { + return 'SpotiFLAC v$version downloaded. Tap to install.'; + } + + @override + String get notifUpdateFailed => 'Update Failed'; + + @override + String get notifUpdateFailedBody => + 'Could not download update. Try again later.'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 73c69db..13ed10e 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -21,13 +21,13 @@ class AppLocalizationsRu extends AppLocalizations { String get navSettings => 'Настройки'; @override - String get navStore => 'Магазин'; + String get navStore => 'Repo'; @override String get homeTitle => 'Главная'; @override - String get homeSubtitle => 'Вставьте ссылку Spotify или ищите по названию'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => @@ -221,11 +221,10 @@ class AppLocalizationsRu extends AppLocalizations { 'Параллельные загрузки могут вызвать ограничение скорости'; @override - String get optionsExtensionStore => 'Магазин расширений'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => - 'Показывать вкладку Магазин в гл. меню'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => 'Проверить обновления'; @@ -302,7 +301,7 @@ class AppLocalizationsRu extends AppLocalizations { String get extensionsUninstall => 'Удалить'; @override - String get storeTitle => 'Магазин расширений'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => 'Поиск расширений...'; @@ -636,9 +635,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: 'треков', + one: 'трек', many: 'треков', few: 'трека', - one: 'трек', ); return 'Удалить $count $_temp0 из истории?\n\nЭто также удалит файлы из хранилища.'; } @@ -691,9 +690,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: 'треков', + one: 'трек', many: 'треков', few: 'трека', - one: 'трек', ); return 'Удалено $count $_temp0'; } @@ -1161,9 +1160,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: '$count треков', + one: '1 трек', many: '$count треков', few: '$count трека', - one: '$count трек', ); return '$_temp0'; } @@ -1357,7 +1356,7 @@ class AppLocalizationsRu extends AppLocalizations { String get storeEmptyNoResults => 'No extensions found'; @override - String get extensionDefaultProvider => 'По умолчанию (Deezer/Spotify)'; + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => @@ -1670,9 +1669,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: 'треков', + one: 'трек', many: 'треков', few: 'трека', - one: 'трек', ); return 'Удалить $count $_temp0 из этого альбома?\n\nЭто также удалит файлы из хранилища.'; } @@ -1694,9 +1693,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: 'треков', + one: 'трек', many: 'треков', few: 'трека', - one: 'трек', ); return 'Удалить $count $_temp0'; } @@ -1927,9 +1926,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: 'треков', + one: 'трек', many: 'треков', few: 'трека', - one: 'трек', ); return '$_temp0'; } @@ -2083,9 +2082,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: '$count минут', + one: '1 минуту', many: '$count минут', few: '$count минуты', - one: '$count минуту', ); return '$_temp0 назад'; } @@ -2096,9 +2095,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: '$count часов', + one: '1 час', many: '$count часов', few: '$count часа', - one: '$count час', ); return '$_temp0 назад'; } @@ -2164,7 +2163,7 @@ class AppLocalizationsRu extends AppLocalizations { @override String get tutorialExtensionsTip1 => - 'Просмотрите вкладку Магазина, чтобы найти полезные расширения'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -2448,7 +2447,8 @@ class AppLocalizationsRu extends AppLocalizations { String get trackConvertFormat => 'Переконвертировать формат'; @override - String get trackConvertFormatSubtitle => 'Конвертировать в MP3 или Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Конвертировать аудио'; @@ -2579,9 +2579,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: '$count треков', + one: '1 трек', many: '$count треков', few: '$count трека', - one: '$count трек', ); return '$_temp0'; } @@ -2698,9 +2698,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: 'треков', + one: 'трек', many: 'треков', few: 'трека', - one: 'трек', ); return 'Отправить $count $_temp0'; } @@ -2715,9 +2715,9 @@ class AppLocalizationsRu extends AppLocalizations { count, locale: localeName, other: 'треков', + one: 'трек', many: 'треков', few: 'трека', - one: 'трек', ); return 'Конвертировать $count $_temp0'; } diff --git a/lib/l10n/app_localizations_tr.dart b/lib/l10n/app_localizations_tr.dart index eda8599..7e5ed92 100644 --- a/lib/l10n/app_localizations_tr.dart +++ b/lib/l10n/app_localizations_tr.dart @@ -12,30 +12,30 @@ class AppLocalizationsTr extends AppLocalizations { String get appName => 'SpotiFLAC'; @override - String get navHome => 'Ana Sayfa'; + String get navHome => 'Ana sayfa'; @override - String get navLibrary => 'Kitaplık'; + String get navLibrary => 'Kitaplığın'; @override String get navSettings => 'Ayarlar'; @override - String get navStore => 'Mağaza'; + String get navStore => 'Depo'; @override - String get homeTitle => 'Ana Sayfa'; + String get homeTitle => 'Ana sayfa'; @override String get homeSubtitle => - 'Bir Spotify bağlantısı yapıştırın veya şarkı arayın'; + 'Desteklenen bir URL yapıştırın veya isme göre arayın'; @override String get homeSupports => - 'Desteklenenler: Şarkı, Albüm, Çalma Listesi, Sanatçı bağlantıları'; + 'Desteklenen linkler: Şarkı, Albüm, Çalma Listesi, Sanatçı linkleri'; @override - String get homeRecent => 'Son Arananlar'; + String get homeRecent => 'En son'; @override String get historyFilterAll => 'Tümü'; @@ -47,7 +47,7 @@ class AppLocalizationsTr extends AppLocalizations { String get historyFilterSingles => 'Single\'lar'; @override - String get historySearchHint => 'Geçmişte ara...'; + String get historySearchHint => 'Arama geçmişi...'; @override String get settingsTitle => 'Ayarlar'; @@ -72,20 +72,20 @@ class AppLocalizationsTr extends AppLocalizations { @override String get downloadAskQualitySubtitle => - 'Her indirmede kalite seçme ekranını göster'; + 'Her indirmeden önce kalite seçim ekranını göster'; @override - String get downloadFilenameFormat => 'Dosya Adı Formatı'; + String get downloadFilenameFormat => 'Dosya adı formatı'; @override - String get downloadSingleFilenameFormat => 'Single Filename Format'; + String get downloadSingleFilenameFormat => 'Single Dosya Adı Formatı'; @override String get downloadSingleFilenameFormatDescription => - 'Filename pattern for singles and EPs. Uses the same tags as the album format.'; + 'Single ve EP\'ler için dosya adı örneği. Albüm formatıyla aynı etiketleri kullanır.'; @override - String get downloadFolderOrganization => 'Klasör Düzeni Seçimi'; + String get downloadFolderOrganization => 'Dosya Organizasyonu'; @override String get appearanceTitle => 'Görünüm'; @@ -100,14 +100,14 @@ class AppLocalizationsTr extends AppLocalizations { String get appearanceThemeDark => 'Koyu'; @override - String get appearanceDynamicColor => 'Dinamik Renkler'; + String get appearanceDynamicColor => 'Dinamik Renk'; @override String get appearanceDynamicColorSubtitle => - 'Uygulama renklerini duvar kağıdınızdan alır'; + 'Duvar kağıdının renklerini kullan'; @override - String get appearanceHistoryView => 'Geçmiş Görünümü'; + String get appearanceHistoryView => 'Geçmiş Düzeni'; @override String get appearanceHistoryViewList => 'Liste'; @@ -119,15 +119,15 @@ class AppLocalizationsTr extends AppLocalizations { String get optionsTitle => 'Seçenekler'; @override - String get optionsPrimaryProvider => 'Ana Sağlayıcı'; + String get optionsPrimaryProvider => 'Ana Kaynek'; @override String get optionsPrimaryProviderSubtitle => - 'Şarkı adıyla arama yaparken kullanılacak servis.'; + 'Şarkı ismi aratılırken kullanılan kaynak.'; @override String optionsUsingExtension(String extensionName) { - return 'Şu anki eklenti: $extensionName'; + return 'Kullanılan eklenti: $extensionName'; } @override @@ -139,77 +139,77 @@ class AppLocalizationsTr extends AppLocalizations { @override String get optionsSwitchBack => - 'Eklentiden çıkıp varsayılana dönmek için Deezer veya Spotify\'a dokunun'; + 'Dahili kaynaklara dönmek için Deezer veya Spotify\'a tıkla'; @override - String get optionsAutoFallback => 'Otomatik Geçiş'; + String get optionsAutoFallback => 'Diğerlerini dene'; @override String get optionsAutoFallbackSubtitle => - 'İndirme başarısız olursa otomatik olarak diğer servisleri dener'; + 'İndirme başarısız olursa diğer hizmetleri dene'; @override - String get optionsUseExtensionProviders => 'Eklenti Sağlayıcılarını Kullan'; + String get optionsUseExtensionProviders => 'Eklenti sağlayıcılarını kullan'; @override - String get optionsUseExtensionProvidersOn => - 'İndirme için önce eklentiler denenecek'; + String get optionsUseExtensionProvidersOn => 'Eklentiler ilk denenecek'; @override String get optionsUseExtensionProvidersOff => - 'Sadece yerleşik sağlayıcılar kullanılıyor'; + 'Sadece dahili sağlayıcıları kullan'; @override - String get optionsEmbedLyrics => 'Şarkı Sözlerini Gömer'; + String get optionsEmbedLyrics => 'Şarkı Sözlerini Göm'; @override String get optionsEmbedLyricsSubtitle => - 'Senkronize şarkı sözlerini FLAC dosyalarının içine gömer'; + 'Senkronize şarkı sözlerini FLAC dosyalarına göm'; @override - String get optionsMaxQualityCover => 'En Yüksek Kalite Albüm Kapağı'; + String get optionsMaxQualityCover => 'En Yüksek Kapak Kalitesi'; @override String get optionsMaxQualityCoverSubtitle => - 'Albüm kapağını bulunabilen en yüksek çözünürlükte indirir'; + 'En yüksek kalitedeki albüm kapaklarını indir'; @override String get optionsReplayGain => 'ReplayGain'; @override String get optionsReplayGainSubtitleOn => - 'Scan loudness and embed ReplayGain tags (EBU R128)'; + 'Ses yüksekliğini tara ve ReplayGain etiketlerini göm (EBU R128)'; @override String get optionsReplayGainSubtitleOff => - 'Disabled: no loudness normalization tags'; + 'Devre dışı: Ses normalleştirme etiketi yok'; @override - String get optionsArtistTagMode => 'Artist Tag Mode'; + String get optionsArtistTagMode => 'Sanatçı Etiketi Modu'; @override String get optionsArtistTagModeDescription => - 'Choose how multiple artists are written into embedded tags.'; + 'Birden fazla sanatçının gömülü etiketlere nasıl yazılacağını seçin.'; @override - String get optionsArtistTagModeJoined => 'Single joined value'; + String get optionsArtistTagModeJoined => 'Birleşik tek değer'; @override String get optionsArtistTagModeJoinedSubtitle => - 'Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.'; + 'Maksimum oynatıcı uyumluluğu için \'Sanatçı A, Sanatçı B\' şeklinde tek bir SANATÇI değeri yazın.'; @override - String get optionsArtistTagModeSplitVorbis => 'Split tags for FLAC/Opus'; + String get optionsArtistTagModeSplitVorbis => + 'FLAC/Opus için ayrılmış etiketler'; @override String get optionsArtistTagModeSplitVorbisSubtitle => - 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; + 'FLAC ve Opus için her sanatçıya ayrı bir etiket yazın; MP3 ve M4A birleşik kalır.'; @override - String get optionsConcurrentDownloads => 'Eşzamanlı İndirmeler'; + String get optionsConcurrentDownloads => 'Eş Zamanlı İndirmeler'; @override - String get optionsConcurrentSequential => 'Sırayla (Tek tek)'; + String get optionsConcurrentSequential => 'Sıralı (Birer birer)'; @override String optionsConcurrentParallel(int count) { @@ -218,81 +218,79 @@ class AppLocalizationsTr extends AppLocalizations { @override String get optionsConcurrentWarning => - 'Aynı anda çok fazla indirme yapmak kısıtlamaya takılmanıza neden olabilir'; + 'Aynı anda birden fazla indirme sınırlamaya takılabilir'; @override - String get optionsExtensionStore => 'Eklenti Mağazası'; + String get optionsExtensionStore => 'Eklenti Deposu'; @override String get optionsExtensionStoreSubtitle => - 'Gezinme çubuğunda Mağaza sekmesini göster'; + 'Gezinme menüsünde Depo sekmesini göster'; @override - String get optionsCheckUpdates => 'Güncellemeleri Kontrol Et'; + String get optionsCheckUpdates => 'Güncelleştirmeleri Denetle'; @override - String get optionsCheckUpdatesSubtitle => - 'Yeni bir sürüm çıktığında haber ver'; + String get optionsCheckUpdatesSubtitle => 'Yeni sürüm çıktığında bildir'; @override String get optionsUpdateChannel => 'Güncelleme Kanalı'; @override - String get optionsUpdateChannelStable => 'Sadece kararlı sürümler'; + String get optionsUpdateChannelStable => 'Sadece stabil sürümler'; @override - String get optionsUpdateChannelPreview => - 'Ön izleme (Beta) sürümlerini de al'; + String get optionsUpdateChannelPreview => 'Önizleme sürümlerini al'; @override String get optionsUpdateChannelWarning => - 'Beta sürümler hatalar içerebilir veya tamamlanmamış özellikler barındırabilir'; + 'Önizleme sürümleri hatalar veya tamamlanmamış özellikler içerebilir'; @override String get optionsClearHistory => 'İndirme Geçmişini Temizle'; @override String get optionsClearHistorySubtitle => - 'İndirilen tüm şarkıları geçmişten siler'; + 'İndirilen bütün şarkıları geçmişten temizle'; @override - String get optionsDetailedLogging => 'Detaylı Hata Ayıklama (Log)'; + String get optionsDetailedLogging => 'Detaylı Günlükleme'; @override - String get optionsDetailedLoggingOn => 'Arka planda detaylı kayıt tutuluyor'; + String get optionsDetailedLoggingOn => 'Detaylı günlük kayıt ediliyor'; @override - String get optionsDetailedLoggingOff => 'Hata bildirimi yapacaksanız açın'; + String get optionsDetailedLoggingOff => 'Hata bildirmek için aç'; @override - String get optionsSpotifyCredentials => 'Spotify API Kimlik Bilgileri'; + String get optionsSpotifyCredentials => 'Spotify Kimlik Bilgileri'; @override String optionsSpotifyCredentialsConfigured(String clientId) { - return 'İstemci Kimliği (Client ID): $clientId...'; + return 'Client ID: $clientId...'; } @override String get optionsSpotifyCredentialsRequired => - 'Gerekli - ayarlamak için dokunun'; + 'Zorunlu - değiştirmek için tıkla'; @override String get optionsSpotifyWarning => - 'Spotify, kendi API kimlik bilgilerinizi kullanmanızı gerektirir. developer.spotify.com adresinden ücretsiz alabilirsiniz.'; + 'Spotify\'ın senin API kimlik bilgilerine ihtiyacı var. Onları developer.spotify.com\'dan alabilirsin'; @override String get optionsSpotifyDeprecationWarning => - 'Spotify API\'sindeki değişiklikler nedeniyle Spotify araması 3 Mart 2026\'da kullanımdan kaldırılacak. Lütfen Deezer\'a geçin.'; + 'Spotify API değişiklikleri nedeniyle Spotify araması 3 Mart 2026 tarihinde kullanımdan kaldırılacaktır. Lütfen Deezer\'a geçiş yapın.'; @override String get extensionsTitle => 'Eklentiler'; @override - String get extensionsDisabled => 'Devre dışı'; + String get extensionsDisabled => 'Devre Dışı'; @override String extensionsVersion(String version) { - return 'Sürüm $version'; + return 'Versiyon $version'; } @override @@ -304,16 +302,16 @@ class AppLocalizationsTr extends AppLocalizations { String get extensionsUninstall => 'Kaldır'; @override - String get storeTitle => 'Eklenti Mağazası'; + String get storeTitle => 'Uzantı Deposu'; @override - String get storeSearch => 'Eklentilerde ara...'; + String get storeSearch => 'Eklenti ara...'; @override - String get storeInstall => 'Yükle'; + String get storeInstall => 'Kur'; @override - String get storeInstalled => 'Yüklü'; + String get storeInstalled => 'Kuruldu'; @override String get storeUpdate => 'Güncelle'; @@ -325,23 +323,23 @@ class AppLocalizationsTr extends AppLocalizations { String get aboutContributors => 'Katkıda Bulunanlar'; @override - String get aboutMobileDeveloper => 'Mobil sürüm geliştiricisi'; + String get aboutMobileDeveloper => 'Mobil versiyon geliştiricisi'; @override - String get aboutOriginalCreator => 'Orijinal SpotiFLAC\'ın yaratıcısı'; + String get aboutOriginalCreator => 'Orijinal SpotiFLAC\'ın kurucusu'; @override String get aboutLogoArtist => - 'Uygulamanın harika logosunu tasarlayan yetenekli sanatçı!'; + 'Uygulama logomuzu yaratmış yetenekli sanatçımız!'; @override String get aboutTranslators => 'Çevirmenler'; @override - String get aboutSpecialThanks => 'Özel Teşekkürler'; + String get aboutSpecialThanks => 'Özel teşekkür'; @override - String get aboutLinks => 'Bağlantılar'; + String get aboutLinks => 'Linkler'; @override String get aboutMobileSource => 'Mobil kaynak kodu'; @@ -357,14 +355,14 @@ class AppLocalizationsTr extends AppLocalizations { @override String get aboutReportIssueSubtitle => - 'Karşılaştığınız sorunları bize iletin'; + 'Karşılaştığın herhangi bir problemi bildir'; @override String get aboutFeatureRequest => 'Özellik isteği'; @override String get aboutFeatureRequestSubtitle => - 'Uygulama için yeni özellikler önerin'; + 'Uygulama için yeni özellikler isteyin'; @override String get aboutTelegramChannel => 'Telegram Kanalı'; @@ -373,49 +371,49 @@ class AppLocalizationsTr extends AppLocalizations { String get aboutTelegramChannelSubtitle => 'Duyurular ve güncellemeler'; @override - String get aboutTelegramChat => 'Telegram Topluluğu'; + String get aboutTelegramChat => 'Telegram Grubu'; @override - String get aboutTelegramChatSubtitle => 'Diğer kullanıcılarla sohbet edin'; + String get aboutTelegramChatSubtitle => 'Diğer kullanıcılarla sohbet et'; @override - String get aboutSocial => 'Sosyal Medya'; + String get aboutSocial => 'Sosyal ağlar'; @override - String get aboutApp => 'Uygulama Bilgisi'; + String get aboutApp => 'Uygulama'; @override - String get aboutVersion => 'Sürüm'; + String get aboutVersion => 'Versiyon'; @override String get aboutBinimumDesc => - 'QQDL ve HiFi API\'nin yaratıcısı. Bu API olmasaydı Tidal indirmeleri var olamazdı!'; + 'QQDL ve HiFi API\'ın kurucusu. Bu API olmadan, Tidal indirmeleri olmazdı!'; @override String get aboutSachinsenalDesc => - 'Orijinal HiFi projesinin kurucusu. Tidal entegrasyonunun temel taşı!'; + 'Orijinal HiFi projesi kurucusu. Tidal entegrasyonun temeli!'; @override String get aboutSjdonadoDesc => - 'I Don\'t Have Spotify (IDHS) projesinin yaratıcısı. Günü kurtaran bağlantı çözümleyicimiz!'; + 'I Don\'t Have Spotify (IDHS) yaratıcısı. Günü kurtaran yedek bağlantı çözücü!'; @override String get aboutDabMusic => 'DAB Music'; @override String get aboutDabMusicDesc => - 'En iyi Qobuz yayın API\'si. Hi-Res indirmeler onlar olmadan mümkün olamazdı!'; + 'En iyi Qobuz streaming API\'ı. Yüksek kalite indirmeler bunun sayesinde!'; @override String get aboutSpotiSaver => 'SpotiSaver'; @override String get aboutSpotiSaverDesc => - 'Tidal Hi-Res FLAC altyapısı. Kayıpsız ses deneyiminin kilit parçası!'; + 'Tidal Hi-Res FLAC akış uç noktaları. Kayıpsız ses yapbozunun kilit bir parçası!'; @override String get aboutAppDescription => - 'Spotify şarkılarını Tidal ve Qobuz üzerinden kayıpsız kalitede indirin.'; + 'Spotify parçalarını Tidal ve Qobuz aracılığıyla kayıpsız kalitede indirin.'; @override String get artistAlbums => 'Albümler'; @@ -435,7 +433,7 @@ class AppLocalizationsTr extends AppLocalizations { } @override - String get trackMetadataService => 'Sağlayıcı'; + String get trackMetadataService => 'Hizmet'; @override String get trackMetadataPlay => 'Oynat'; @@ -453,35 +451,35 @@ class AppLocalizationsTr extends AppLocalizations { String get setupSkip => 'Şimdilik atla'; @override - String get setupStorageAccessRequired => 'Depolama İzni Gerekli'; + String get setupStorageAccessRequired => 'Depolama Erişimi Gerekli'; @override String get setupStorageAccessMessageAndroid11 => - 'Android 11 ve üzeri, müzikleri seçtiğiniz klasöre kaydedebilmek için \'Tüm dosyalara erişim\' izni gerektirir.'; + 'Android 11 ve sonrasında şarkıların seçili klasörünüze kaydedilebilmesi için \"Bütün dosyalara eriş\" iznine ihtiyaç var.'; @override String get setupOpenSettings => 'Ayarları Aç'; @override String get setupPermissionDeniedMessage => - 'İzin reddedildi. Devam etmek için lütfen gerekli izinleri verin.'; + 'İzin reddedildi. Devam etmek için lütfen bütün izinleri verin.'; @override String setupPermissionRequired(String permissionType) { - return '$permissionType İzni Gerekli'; + return '$permissionType İzni Zorunlu'; } @override String setupPermissionRequiredMessage(String permissionType) { - return 'En iyi deneyim için $permissionType iznine ihtiyacımız var. Bunu daha sonra Ayarlar\'dan değiştirebilirsiniz.'; + return 'En iyi deneyim için $permissionType izni zorunludur. Bunu ayarlardan daha sonra değiştirebilirsiniz.'; } @override - String get setupUseDefaultFolder => 'Varsayılan Klasör Kullanılsın mı?'; + String get setupUseDefaultFolder => 'Varsayılan Klasörü Kullan?'; @override String get setupNoFolderSelected => - 'Hiçbir klasör seçilmedi. İndirilenler için cihazınızdaki varsayılan Müzik klasörü kullanılsın mı?'; + 'Klasör seçilmedi. Varsayılan \"Music\" klasörünü kullanmak ister misiniz?'; @override String get setupUseDefault => 'Varsayılanı Kullan'; @@ -491,33 +489,31 @@ class AppLocalizationsTr extends AppLocalizations { @override String get setupDownloadLocationIosMessage => - 'iOS\'te indirilen dosyalar uygulamanın Belgeler klasörüne kaydedilir. Bunlara Dosyalar uygulaması üzerinden erişebilirsiniz.'; + 'iOS\'ta indirilenler uygulamanın \"Documents\" dosyasına kaydedilir. Onlara Dosyalar uygulamasından erişebilirsiniz.'; @override - String get setupAppDocumentsFolder => 'Uygulama Belgeleri Klasörü'; + String get setupAppDocumentsFolder => 'Uygulama Belgeler Klasörü'; @override String get setupAppDocumentsFolderSubtitle => - 'Önerilen - Dosyalar uygulamasıyla erişilebilir'; + 'Tavsiye edilen - Dosyalar uygulamasından erişilebilir'; @override String get setupChooseFromFiles => 'Dosyalar\'dan Seç'; @override - String get setupChooseFromFilesSubtitle => - 'iCloud veya başka bir konum seçin'; + String get setupChooseFromFilesSubtitle => 'iCloud veya başka konum seç'; @override String get setupIosEmptyFolderWarning => - 'iOS Kısıtlaması: Boş klasörler seçilemez. Lütfen içinde en az bir dosya olan bir klasör seçin.'; + 'iOS\'un sınırlaması: Boş klasörler seçilemiyor. İçinde en az bir dosya bulunan bir klasör seçin.'; @override String get setupIcloudNotSupported => - 'iCloud Drive desteklenmiyor. Lütfen uygulamanın Belgeler klasörünü kullanın.'; + 'iCloud Drive desteklenmiyor. Lütfen uygulama Belgeler klasörünü kullanın.'; @override - String get setupDownloadInFlac => - 'Spotify müziklerini FLAC formatında indirin'; + String get setupDownloadInFlac => 'Spotify şarkılarını FLAC olarak indirin'; @override String get setupStorageGranted => 'Depolama İzni Verildi!'; @@ -527,43 +523,43 @@ class AppLocalizationsTr extends AppLocalizations { @override String get setupStorageDescription => - 'İndirdiğiniz şarkıları kaydedebilmemiz için SpotiFLAC\'ın depolama iznine ihtiyacı var.'; + 'SpotiFLAC\'ın şarkılarınızı kaydetmek için depolama iznine ihtiyacı var.'; @override String get setupNotificationGranted => 'Bildirim İzni Verildi!'; @override - String get setupNotificationEnable => 'Bildirimleri Aç'; + String get setupNotificationEnable => 'Bildirimleri Etkinleştir'; @override - String get setupFolderChoose => 'İndirme Klasörü Seç'; + String get setupFolderChoose => 'İndirilecek Klasörü Seç'; @override String get setupFolderDescription => - 'İndirilen şarkıların nereye kaydedileceğini seçin.'; + 'İndirdiğin şarkıların kaydedileceği klasörü seç.'; @override String get setupSelectFolder => 'Klasör Seç'; @override - String get setupEnableNotifications => 'Bildirimleri Aç'; + String get setupEnableNotifications => 'Bildirimleri Etkinleştir'; @override String get setupNotificationBackgroundDescription => - 'İndirme durumları ve tamamlanan şarkılar hakkında anında bildirim alın. Bu, uygulama arka plandayken süreci takip etmenizi kolaylaştırır.'; + 'İndirmelerin durumu hakkında bildirim al. Bunu açmak uygulama arka plandayken indirmelerinizi takip etmenizi sağlar.'; @override String get setupSkipForNow => 'Şimdilik atla'; @override - String get setupNext => 'İleri'; + String get setupNext => 'Sıradaki'; @override - String get setupGetStarted => 'Hadi Başlayalım'; + String get setupGetStarted => 'Başla'; @override String get setupAllowAccessToManageFiles => - 'Lütfen sonraki ekranda \"Tüm dosyaları yönetme erişimine izin ver\" seçeneğini açın.'; + 'Lütfen bir sonraki ekranda \"Bütün dosyalara eriş\" iznini sağlayın.'; @override String get dialogCancel => 'İptal'; @@ -575,35 +571,35 @@ class AppLocalizationsTr extends AppLocalizations { String get dialogDelete => 'Sil'; @override - String get dialogRetry => 'Yeniden Dene'; + String get dialogRetry => 'Yeniden dene'; @override String get dialogClear => 'Temizle'; @override - String get dialogDone => 'Bitti'; + String get dialogDone => 'Tamamlandı'; @override - String get dialogImport => 'İçe Aktar'; + String get dialogImport => 'İçe aktar'; @override String get dialogDownload => 'İndir'; @override - String get dialogDiscard => 'Değişiklikleri Sil'; + String get dialogDiscard => 'Vazgeç'; @override String get dialogRemove => 'Kaldır'; @override - String get dialogUninstall => 'Sil'; + String get dialogUninstall => 'Kaldır'; @override - String get dialogDiscardChanges => 'Değişiklikler İptal Edilsin mi?'; + String get dialogDiscardChanges => 'Değişiklikleri İptal Et?'; @override String get dialogUnsavedChanges => - 'Kaydedilmemiş değişiklikleriniz var. Çıkmak istediğinize emin misiniz?'; + 'Kaydedilmeyen değişiklikler mevcut. Bu değişiklikleri iptal etmek istiyor musunuz?'; @override String get dialogClearAll => 'Tümünü Temizle'; @@ -613,14 +609,14 @@ class AppLocalizationsTr extends AppLocalizations { @override String get dialogRemoveExtensionMessage => - 'Bu eklentiyi kaldırmak istediğinize emin misiniz? Bu işlem geri alınamaz.'; + 'Bu eklentiyi kaldırmak istediğine emin misin? Bu işlem geri alınamaz.'; @override - String get dialogUninstallExtension => 'Eklentiyi Sil?'; + String get dialogUninstallExtension => 'Eklentiyi Kaldır?'; @override String dialogUninstallExtensionMessage(String extensionName) { - return '$extensionName eklentisini silmek istediğinize emin misiniz?'; + return '$extensionName eklentisini kaldırmak istediğine emin misin?'; } @override @@ -628,28 +624,28 @@ class AppLocalizationsTr extends AppLocalizations { @override String get dialogClearHistoryMessage => - 'Tüm indirme geçmişinizi silmek istediğinize emin misiniz? Bu işlem geri alınamaz.'; + 'Tüm indirme geçmişini temizlemek istediğinizden emin misiniz? Bu işlem geri alınamaz.'; @override - String get dialogDeleteSelectedTitle => 'Seçilenleri Sil'; + String get dialogDeleteSelectedTitle => 'Seçileni Sil'; @override String dialogDeleteSelectedMessage(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'şarkı', - one: 'şarkı', + other: 'şarkıyı', + one: 'şarkıyı', ); - return 'Geçmişten $count $_temp0 silinsin mi?\n\nBu işlem, indirilen dosyaları cihazınızdan da tamamen silecek.'; + return '$count $_temp0 geçmişten silmeye emin misiniz?\n\nBu işlem seçilenleri cihazınızdan da silecektir.'; } @override - String get dialogImportPlaylistTitle => 'Çalma Listesi İçe Aktar'; + String get dialogImportPlaylistTitle => 'Çalma listesini içe aktar'; @override String dialogImportPlaylistMessage(int count) { - return 'CSV dosyasında $count şarkı bulundu. İndirme sırasına eklensin mi?'; + return 'CSV\'de $count şarkı bulundu. İndirme kuyruğuna ekle?'; } @override @@ -659,17 +655,17 @@ class AppLocalizationsTr extends AppLocalizations { @override String snackbarAddedToQueue(String trackName) { - return '\"$trackName\" indirme sırasına eklendi'; + return '\"$trackName\" kuyruğa eklendi'; } @override String snackbarAddedTracksToQueue(int count) { - return '$count şarkı indirme sırasına eklendi'; + return '$count şarkı kuyruğa eklendi'; } @override String snackbarAlreadyDownloaded(String trackName) { - return '\"$trackName\" zaten inmiş durumda'; + return '\"$trackName\" zaten indirilmiş'; } @override @@ -681,10 +677,10 @@ class AppLocalizationsTr extends AppLocalizations { String get snackbarHistoryCleared => 'Geçmiş temizlendi'; @override - String get snackbarCredentialsSaved => 'API bilgileri kaydedildi'; + String get snackbarCredentialsSaved => 'Kimlik bilgileri kaydedildi'; @override - String get snackbarCredentialsCleared => 'API bilgileri silindi'; + String get snackbarCredentialsCleared => 'Kimlik bilgileri temizlendi'; @override String snackbarDeletedTracks(int count) { @@ -699,65 +695,65 @@ class AppLocalizationsTr extends AppLocalizations { @override String snackbarCannotOpenFile(String error) { - return 'Dosya açılamıyor: $error'; + return 'Dosya açılamadı: $error'; } @override String get snackbarFillAllFields => 'Lütfen tüm alanları doldurun'; @override - String get snackbarViewQueue => 'Sırayı Gör'; + String get snackbarViewQueue => 'Kuyruğu Görüntüle'; @override String snackbarUrlCopied(String platform) { - return '$platform bağlantısı panoya kopyalandı'; + return '$platform Bağlantı panoya kopyalandı'; } @override String get snackbarFileNotFound => 'Dosya bulunamadı'; @override - String get snackbarSelectExtFile => 'Lütfen bir .spotiflac-ext dosyası seçin'; + String get snackbarSelectExtFile => 'Lütfen .spotiflac-ext dosyasını seçin'; @override String get snackbarProviderPrioritySaved => 'Sağlayıcı önceliği kaydedildi'; @override String get snackbarMetadataProviderSaved => - 'Veri sağlayıcı önceliği kaydedildi'; + 'Meta veri sağlayıcı önceliği kaydedildi'; @override String snackbarExtensionInstalled(String extensionName) { - return '$extensionName başarıyla yüklendi.'; + return '$extensionName yüklendi.'; } @override String snackbarExtensionUpdated(String extensionName) { - return '$extensionName başarıyla güncellendi.'; + return '$extensionName güncellendi.'; } @override - String get snackbarFailedToInstall => 'Eklenti yüklenemedi'; + String get snackbarFailedToInstall => 'Eklenti yüklenirken hata oluştu'; @override - String get snackbarFailedToUpdate => 'Eklenti güncellenemedi'; + String get snackbarFailedToUpdate => 'Eklenti güncellenirken hata oluştu'; @override - String get errorRateLimited => 'Hız Sınırına Takıldınız'; + String get errorRateLimited => 'Aşırı istek gönderildi'; @override String get errorRateLimitedMessage => - 'Çok fazla istek gönderdiniz. Yeniden arama yapmadan önce lütfen biraz bekleyin.'; + 'Çok fazla istek. Lütfen arama yapmadan önce biraz bekleyin.'; @override - String get errorNoTracksFound => 'Şarkı bulunamadı'; + String get errorNoTracksFound => 'Parça bulunamadı'; @override - String get errorUrlNotRecognized => 'Bağlantı algılanamadı'; + String get errorUrlNotRecognized => 'Bağlantı tanınamadı'; @override String get errorUrlNotRecognizedMessage => - 'Bu bağlantı desteklenmiyor. Bağlantının doğru olduğundan ve gerekli eklentinin yüklü olduğundan emin olun.'; + 'Bu bağlantı desteklenmiyor. URL\'nin doğru olduğundan ve uyumlu bir uzantının yüklü olduğundan emin olun.'; @override String get errorUrlFetchFailed => @@ -765,29 +761,29 @@ class AppLocalizationsTr extends AppLocalizations { @override String errorMissingExtensionSource(String item) { - return '$item yüklenemiyor: Eklenti kaynağı eksik'; + return '$item yüklenemedi: Eksik eklenti kaynağı'; } @override String get actionPause => 'Duraklat'; @override - String get actionResume => 'Devam Et'; + String get actionResume => 'Devam et'; @override - String get actionCancel => 'İptal'; + String get actionCancel => 'Vazgeç'; @override String get actionSelectAll => 'Tümünü Seç'; @override - String get actionDeselect => 'Seçimi Kaldır'; + String get actionDeselect => 'Seçimi kaldır'; @override - String get actionRemoveCredentials => 'API Bilgilerini Sil'; + String get actionRemoveCredentials => 'Özellikleri kaldır'; @override - String get actionSaveCredentials => 'API Bilgilerini Kaydet'; + String get actionSaveCredentials => 'Özellikleri kaydet'; @override String selectionSelected(int count) { @@ -795,18 +791,18 @@ class AppLocalizationsTr extends AppLocalizations { } @override - String get selectionAllSelected => 'Tüm şarkılar seçildi'; + String get selectionAllSelected => 'Tüm parçalar seçildi'; @override - String get selectionSelectToDelete => 'Silinecek şarkıları seçin'; + String get selectionSelectToDelete => 'Silinecek parçaları seçin'; @override String progressFetchingMetadata(int current, int total) { - return 'Veriler alınıyor... $current/$total'; + return 'Meta verileri alınıyor... $current/$total'; } @override - String get progressReadingCsv => 'CSV dosyası okunuyor...'; + String get progressReadingCsv => 'CSV okunuyor...'; @override String get searchSongs => 'Şarkılar'; @@ -827,10 +823,10 @@ class AppLocalizationsTr extends AppLocalizations { String get searchSortDefault => 'Varsayılan'; @override - String get searchSortTitleAZ => 'Şarkı Adı (A-Z)'; + String get searchSortTitleAZ => 'Başlık (A-Z)'; @override - String get searchSortTitleZA => 'Şarkı Adı (Z-A)'; + String get searchSortTitleZA => 'Başlık (Z-A)'; @override String get searchSortArtistAZ => 'Sanatçı (A-Z)'; @@ -839,39 +835,39 @@ class AppLocalizationsTr extends AppLocalizations { String get searchSortArtistZA => 'Sanatçı (Z-A)'; @override - String get searchSortDurationShort => 'Süre (Önce kısalar)'; + String get searchSortDurationShort => 'Süre (en kısa)'; @override - String get searchSortDurationLong => 'Süre (Önce uzunlar)'; + String get searchSortDurationLong => 'Süre (en uzun)'; @override - String get searchSortDateOldest => 'Çıkış Tarihi (Önce eskiler)'; + String get searchSortDateOldest => 'Yayın Tarihi (En eski)'; @override - String get searchSortDateNewest => 'Çıkış Tarihi (Önce yeniler)'; + String get searchSortDateNewest => 'Yayın Tarihi (En yeni)'; @override String get tooltipPlay => 'Oynat'; @override - String get filenameFormat => 'Dosya Adı Formatı'; + String get filenameFormat => 'Dosya adı formatı'; @override String get filenameShowAdvancedTags => 'Gelişmiş etiketleri göster'; @override String get filenameShowAdvancedTagsDescription => - 'Boşluk doldurma ve tarih formatları için gelişmiş dosya adı etiketlerini açar'; + 'Parça numarası tamamlama ve tarih desenleri için biçimlendirilmiş etiketleri etkinleştir'; @override - String get folderOrganizationNone => 'Düzen yok'; + String get folderOrganizationNone => 'Organizasyon yok'; @override String get folderOrganizationByPlaylist => 'Çalma Listesine Göre'; @override String get folderOrganizationByPlaylistSubtitle => - 'Her çalma listesi için ayrı bir klasör oluşturur'; + 'Her çalma listesi için ayrı klasör'; @override String get folderOrganizationByArtist => 'Sanatçıya Göre'; @@ -880,48 +876,47 @@ class AppLocalizationsTr extends AppLocalizations { String get folderOrganizationByAlbum => 'Albüme Göre'; @override - String get folderOrganizationByArtistAlbum => 'Sanatçı / Albüm'; + String get folderOrganizationByArtistAlbum => 'Sanatçı/Albüm'; @override String get folderOrganizationDescription => - 'İndirilen dosyaları klasörlere düzenler'; + 'İndirilenleri klasörlerle organize et'; @override String get folderOrganizationNoneSubtitle => - 'Tüm dosyalar tek bir klasöre atılır'; + 'Her şey indirilen dosyasına kaydedilecek'; @override String get folderOrganizationByArtistSubtitle => - 'Her sanatçı için ayrı klasör oluşturur'; + 'Her sanatçı için ayrı klasör'; @override - String get folderOrganizationByAlbumSubtitle => - 'Her albüm için ayrı klasör oluşturur'; + String get folderOrganizationByAlbumSubtitle => 'Her albüm için ayrı klasör'; @override String get folderOrganizationByArtistAlbumSubtitle => - 'İç içe Sanatçı ve Albüm klasörleri oluşturur'; + 'Sanatçı klasörlerinin içinde Albüm klasörleri'; @override - String get updateAvailable => 'Güncelleme Var'; + String get updateAvailable => 'Güncelleme Mevcut'; @override String get updateLater => 'Daha Sonra'; @override - String get updateStartingDownload => 'İndirme başlatılıyor...'; + String get updateStartingDownload => 'İndirme başlıyor...'; @override String get updateDownloadFailed => 'İndirme başarısız'; @override - String get updateFailedMessage => 'Güncelleme dosyası indirilemedi'; + String get updateFailedMessage => 'Güncelleme indirilemedi'; @override - String get updateNewVersionReady => 'Uygulamanın yeni bir sürümü hazır'; + String get updateNewVersionReady => 'Yeni bir sürüm hazır'; @override - String get updateCurrent => 'Mevcut'; + String get updateCurrent => 'Şimdiki'; @override String get updateNew => 'Yeni'; @@ -930,73 +925,73 @@ class AppLocalizationsTr extends AppLocalizations { String get updateDownloading => 'İndiriliyor...'; @override - String get updateWhatsNew => 'Neler Yeni?'; + String get updateWhatsNew => 'Yenilikler'; @override - String get updateDownloadInstall => 'İndir ve Yükle'; + String get updateDownloadInstall => 'İndir & Yükle'; @override - String get updateDontRemind => 'Bir daha hatırlatma'; + String get updateDontRemind => 'Bir daha sorma'; @override - String get providerPriorityTitle => 'Sağlayıcı Önceliği'; + String get providerPriorityTitle => 'İndirme hizmetleri öncelik sırası'; @override String get providerPriorityDescription => - 'İndirme sağlayıcılarını sürükleyip sıralayın. Uygulama, şarkıları indirirken sağlayıcıları yukarıdan aşağıya doğru dener.'; + 'İndirme hizmetlerini sıralamak için kaydır. Uygulama şarkı indirirken hizmetleri yukarıdan aşağıya doğru deneyecektir.'; @override String get providerPriorityInfo => - 'Bir şarkı ilk sağlayıcıda bulunamazsa, uygulama otomatik olarak listedeki bir sonrakini dener.'; + 'Eğer bir şarkı ilk hizmette mevcut değilse uygulama otomatik olarak bir sonrakini deneyecektir.'; @override - String get providerPriorityFallbackExtensionsTitle => 'Extension Fallback'; + String get providerPriorityFallbackExtensionsTitle => 'Uzantı Yedeği'; @override String get providerPriorityFallbackExtensionsDescription => - 'Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.'; + 'Otomatik yedekleme sırasında hangi yüklü indirme uzantılarının kullanılabileceğini seçin. Yerleşik sağlayıcılar hâlâ yukarıdaki öncelik sırasını takip eder.'; @override String get providerPriorityFallbackExtensionsHint => - 'Only enabled extensions with download-provider capability are listed here.'; + 'Burada yalnızca indirme sağlayıcısı yeteneğine sahip olan ve etkinleştirilmiş uzantılar listelenir.'; @override - String get providerBuiltIn => 'Yerleşik'; + String get providerBuiltIn => 'Dahili'; @override String get providerExtension => 'Eklenti'; @override - String get metadataProviderPriorityTitle => 'Arama Kaynağı Önceliği'; + String get metadataProviderPriorityTitle => 'Meta Veri Önceliği'; @override String get metadataProviderPriorityDescription => - 'Arama kaynaklarını sürükleyip sıralayın. Uygulama, şarkı ararken ve veri çekerken kaynakları yukarıdan aşağıya doğru dener.'; + 'Meta veri sağlayıcılarını yeniden sıralamak için sürükleyin. Uygulama, parça ararken ve meta verileri alırken sağlayıcıları yukarıdan aşağıya doğru deneyecektir.'; @override String get metadataProviderPriorityInfo => - 'Deezer\'da hız sınırı yoktur, bu yüzden ana kaynak olarak kullanılması tavsiye edilir. Spotify, çok fazla istekte bulunduğunuzda kısıtlama yapabilir.'; + 'Deezer\'da istek sınırı yoktur ve birincil olarak önerilir. Spotify, çok sayıda istekten sonra hız sınırlaması uygulayabilir.'; @override - String get metadataNoRateLimits => 'Hız sınırı yok'; + String get metadataNoRateLimits => 'İstek sınırı yok'; @override - String get metadataMayRateLimit => 'Hız sınırı yapabilir'; + String get metadataMayRateLimit => 'Hız sınırlaması uygulanabilir'; @override - String get logTitle => 'Hata Kayıtları (Log)'; + String get logTitle => 'Kayıtlar'; @override String get logCopied => 'Kayıtlar panoya kopyalandı'; @override - String get logSearchHint => 'Kayıtlarda ara...'; + String get logSearchHint => 'Kayıtları Ara...'; @override String get logFilterLevel => 'Seviye'; @override - String get logFilterSection => 'Filtrele'; + String get logFilterSection => 'Filtre'; @override String get logShareLogs => 'Kayıtları paylaş'; @@ -1005,21 +1000,21 @@ class AppLocalizationsTr extends AppLocalizations { String get logClearLogs => 'Kayıtları temizle'; @override - String get logClearLogsTitle => 'Kayıtları Temizle'; + String get logClearLogsTitle => 'Kayıtları temizle'; @override String get logClearLogsMessage => - 'Tüm hata kayıtlarını silmek istediğinize emin misiniz?'; + 'Tüm kayıtları temizlemek istediğinize emin misiniz?'; @override - String get logFilterBySeverity => 'Önem derecesine göre filtrele'; + String get logFilterBySeverity => 'Günlükleri önem derecesine göre filtrele'; @override String get logNoLogsYet => 'Henüz kayıt yok'; @override String get logNoLogsYetSubtitle => - 'Uygulamayı kullandıkça teknik kayıtlar burada görünecek'; + 'Uygulamayı kullandıkça günlükler burada görünecektir'; @override String logEntriesFiltered(int count) { @@ -1032,20 +1027,20 @@ class AppLocalizationsTr extends AppLocalizations { } @override - String get credentialsTitle => 'Spotify API Bilgileri'; + String get credentialsTitle => 'Spotify Kimlik Bilgileri'; @override String get credentialsDescription => - 'Kendi Spotify uygulamanızın kota limitlerini kullanmak için İstemci Kimliği (Client ID) ve Gizli Anahtarınızı (Client Secret) girin.'; + 'Kendi Spotify uygulama kotanızı kullanmak için Client ID ve Secret girin.'; @override - String get credentialsClientId => 'Client ID (İstemci Kimliği)'; + String get credentialsClientId => 'Client ID'; @override String get credentialsClientIdHint => 'Client ID yapıştır'; @override - String get credentialsClientSecret => 'Client Secret (Gizli Anahtar)'; + String get credentialsClientSecret => 'Client Secret'; @override String get credentialsClientSecretHint => 'Client Secret yapıştır'; @@ -1054,13 +1049,13 @@ class AppLocalizationsTr extends AppLocalizations { String get channelStable => 'Kararlı'; @override - String get channelPreview => 'Beta (Ön İzleme)'; + String get channelPreview => 'Önizleme'; @override String get sectionSearchSource => 'Arama Kaynağı'; @override - String get sectionDownload => 'İndirme'; + String get sectionDownload => 'İndir'; @override String get sectionPerformance => 'Performans'; @@ -1069,13 +1064,13 @@ class AppLocalizationsTr extends AppLocalizations { String get sectionApp => 'Uygulama'; @override - String get sectionData => 'Veri Yönetimi'; + String get sectionData => 'Veri'; @override - String get sectionDebug => 'Hata Ayıklama'; + String get sectionDebug => 'Hata ayıklama'; @override - String get sectionService => 'Servisler'; + String get sectionService => 'Servis'; @override String get sectionAudioQuality => 'Ses Kalitesi'; @@ -1084,44 +1079,44 @@ class AppLocalizationsTr extends AppLocalizations { String get sectionFileSettings => 'Dosya Ayarları'; @override - String get sectionLyrics => 'Şarkı Sözleri'; + String get sectionLyrics => 'Şarkı sözleri'; @override - String get lyricsMode => 'Şarkı Sözü Formatı'; + String get lyricsMode => 'Şarkı Sözü Modu'; @override String get lyricsModeDescription => - 'Şarkı sözlerinin nasıl kaydedileceğini seçin'; + 'Şarkı sözlerinin indirmelerinizle birlikte nasıl kaydedileceğini seçin'; @override String get lyricsModeEmbed => 'Dosyaya göm'; @override String get lyricsModeEmbedSubtitle => - 'Şarkı sözleri FLAC dosyasının içine işlenir'; + 'Şarkı sözleri FLAC meta verilerinin içinde saklanır'; @override String get lyricsModeExternal => 'Harici .lrc dosyası'; @override String get lyricsModeExternalSubtitle => - 'Bazı müzik çalarlar için şarkının yanına ayrı bir .lrc dosyası açar'; + 'Samsung Music gibi oynatıcılar için ayrı .lrc dosyası'; @override String get lyricsModeBoth => 'Her ikisi de'; @override String get lyricsModeBothSubtitle => - 'Hem dosyaya gömer hem de .lrc dosyası olarak kaydeder'; + 'Hem göm hem de .lrc dosyası olarak kaydet'; @override - String get sectionColor => 'Renkler'; + String get sectionColor => 'Renk'; @override String get sectionTheme => 'Tema'; @override - String get sectionLayout => 'Tasarım'; + String get sectionLayout => 'Düzen'; @override String get sectionLanguage => 'Dil'; @@ -1130,29 +1125,27 @@ class AppLocalizationsTr extends AppLocalizations { String get appearanceLanguage => 'Uygulama Dili'; @override - String get settingsAppearanceSubtitle => 'Temalar, renkler, görünümler'; + String get settingsAppearanceSubtitle => 'Tema, renkler, görünüm'; @override - String get settingsDownloadSubtitle => - 'İndirme servisi, ses kalitesi, dosya adı düzeni'; + String get settingsDownloadSubtitle => 'Servis, kalite, dosya adı formatı'; @override String get settingsOptionsSubtitle => - 'İndirme limitleri, şarkı sözleri, güncellemeler'; + 'Yedekleme, sözler, kapak resmi, güncellemeler'; @override - String get settingsExtensionsSubtitle => - 'Yeni müzik kaynakları ve eklentileri yönetin'; + String get settingsExtensionsSubtitle => 'İndirme sağlayıcılarını yönet'; @override String get settingsLogsSubtitle => - 'Sorun tespiti için uygulama kayıtlarına göz atın'; + 'Hata ayıklama için uygulama günlüklerini görüntüle'; @override String get loadingSharedLink => 'Paylaşılan bağlantı yükleniyor...'; @override - String get pressBackAgainToExit => 'Çıkmak için tekrar geri dokunun'; + String get pressBackAgainToExit => 'Çıkmak için tekrar geri basın'; @override String downloadAllCount(int count) { @@ -1164,8 +1157,8 @@ class AppLocalizationsTr extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: '$count şarkı', - one: '1 şarkı', + other: '$count parça', + one: '1 parça', ); return '$_temp0'; } @@ -1174,37 +1167,37 @@ class AppLocalizationsTr extends AppLocalizations { String get trackCopyFilePath => 'Dosya yolunu kopyala'; @override - String get trackRemoveFromDevice => 'Cihazdan sil'; + String get trackRemoveFromDevice => 'Cihazdan kaldır'; @override - String get trackLoadLyrics => 'Sözleri Yükle'; + String get trackLoadLyrics => 'Şarkı Sözlerini Yükle'; @override - String get trackMetadata => 'Şarkı Künyesi'; + String get trackMetadata => 'Meta Veri'; @override String get trackFileInfo => 'Dosya Bilgisi'; @override - String get trackLyrics => 'Sözler'; + String get trackLyrics => 'Şarkı Sözleri'; @override String get trackFileNotFound => 'Dosya bulunamadı'; @override - String get trackOpenInDeezer => 'Deezer\'da Aç'; + String get trackOpenInDeezer => 'Deezer\'da aç'; @override - String get trackOpenInSpotify => 'Spotify\'da Aç'; + String get trackOpenInSpotify => 'Spotify\'da aç'; @override - String get trackTrackName => 'Şarkı Adı'; + String get trackTrackName => 'Parça adı'; @override String get trackArtist => 'Sanatçı'; @override - String get trackAlbumArtist => 'Albüm Sanatçısı'; + String get trackAlbumArtist => 'Albüm sanatçısı'; @override String get trackAlbum => 'Albüm'; @@ -1222,57 +1215,57 @@ class AppLocalizationsTr extends AppLocalizations { String get trackAudioQuality => 'Ses kalitesi'; @override - String get trackReleaseDate => 'Çıkış tarihi'; + String get trackReleaseDate => 'Yayın tarihi'; @override String get trackGenre => 'Tür'; @override - String get trackLabel => 'Plak Şirketi'; + String get trackLabel => 'Etiket / Müzik Şirketi'; @override String get trackCopyright => 'Telif Hakkı'; @override - String get trackDownloaded => 'İndirilme tarihi'; + String get trackDownloaded => 'İndirildi'; @override - String get trackCopyLyrics => 'Sözleri kopyala'; + String get trackCopyLyrics => 'Şarkı sözlerini kopyala'; @override - String get trackLyricsNotAvailable => 'Bu şarkının sözleri bulunamadı'; + String get trackLyricsNotAvailable => 'Bu parça için şarkı sözü mevcut değil'; @override - String get trackLyricsNotInFile => 'No lyrics found in this file'; + String get trackLyricsNotInFile => 'Bu dosyada şarkı sözü bulunamadı'; @override - String get trackFetchOnlineLyrics => 'Fetch from Online'; + String get trackFetchOnlineLyrics => 'İnternetten Getir'; @override String get trackLyricsTimeout => - 'Zaman aşımına uğradı. Lütfen daha sonra tekrar deneyin.'; + 'İstek zaman aşımına uğradı. Daha sonra tekrar deneyin.'; @override String get trackLyricsLoadFailed => 'Şarkı sözleri yüklenemedi'; @override - String get trackEmbedLyrics => 'Şarkı Sözlerini Gömer'; + String get trackEmbedLyrics => 'Şarkı Sözlerini Göm'; @override - String get trackLyricsEmbedded => 'Şarkı sözleri dosyaya başarıyla eklendi'; + String get trackLyricsEmbedded => 'Şarkı sözleri başarıyla gömüldü'; @override - String get trackInstrumental => 'Enstrümantal parça (Sözsüz)'; + String get trackInstrumental => 'Enstrümantal parça'; @override String get trackCopiedToClipboard => 'Panoya kopyalandı'; @override - String get trackDeleteConfirmTitle => 'Cihazdan silinsin mi?'; + String get trackDeleteConfirmTitle => 'Cihazdan kaldırılsın mı?'; @override String get trackDeleteConfirmMessage => - 'Bu işlem indirdiğiniz dosyayı tamamen silecek ve geçmişinizden kaldıracak.'; + 'Bu işlem, indirilen dosyayı kalıcı olarak silecek ve geçmişinizden kaldıracaktır.'; @override String get dateToday => 'Bugün'; @@ -1299,16 +1292,16 @@ class AppLocalizationsTr extends AppLocalizations { String get storeFilterAll => 'Tümü'; @override - String get storeFilterMetadata => 'Şarkı Verisi'; + String get storeFilterMetadata => 'Meta Veri'; @override - String get storeFilterDownload => 'İndirme'; + String get storeFilterDownload => 'İndir'; @override - String get storeFilterUtility => 'Araçlar'; + String get storeFilterUtility => 'Araç'; @override - String get storeFilterLyrics => 'Şarkı Sözü'; + String get storeFilterLyrics => 'Şarkı Sözleri'; @override String get storeFilterIntegration => 'Entegrasyon'; @@ -1317,82 +1310,81 @@ class AppLocalizationsTr extends AppLocalizations { String get storeClearFilters => 'Filtreleri temizle'; @override - String get storeAddRepoTitle => 'Eklenti Deposu (Repository) Ekle'; + String get storeAddRepoTitle => 'Uzantı Deposu Ekle'; @override String get storeAddRepoDescription => - 'Eklentilere göz atmak ve yüklemek için içinde registry.json dosyası olan bir GitHub depo bağlantısı girin.'; + 'Uzantılara göz atmak ve yüklemek için registry.json dosyası içeren bir GitHub depo URL\'si girin.'; @override - String get storeRepoUrlLabel => 'Depo Bağlantısı (URL)'; + String get storeRepoUrlLabel => 'Depo URL\'si'; @override - String get storeRepoUrlHint => 'https://github.com/kullaniciadi/depo'; + String get storeRepoUrlHint => 'https://github.com/user/repo'; @override String get storeRepoUrlHelper => - 'Örn: https://github.com/spoti/extensions-repo'; + 'örn. https://github.com/user/extensions-repo'; @override - String get storeAddRepoButton => 'Depoyu Ekle'; + String get storeAddRepoButton => 'Depo Ekle'; @override String get storeChangeRepoTooltip => 'Depoyu değiştir'; @override - String get storeRepoDialogTitle => 'Eklenti Deposu'; + String get storeRepoDialogTitle => 'Uzantı Deposu'; @override String get storeRepoDialogCurrent => 'Mevcut depo:'; @override - String get storeNewRepoUrlLabel => 'Yeni Depo Bağlantısı'; + String get storeNewRepoUrlLabel => 'Yeni Depo URL\'si'; @override - String get storeLoadError => 'Mağaza yüklenemedi'; + String get storeLoadError => 'Depo yüklenemedi'; @override - String get storeEmptyNoExtensions => 'Kullanılabilir eklenti yok'; + String get storeEmptyNoExtensions => 'Uygun uzantı yok'; @override - String get storeEmptyNoResults => 'Aramanıza uygun eklenti bulunamadı'; + String get storeEmptyNoResults => 'Uzantı bulunamadı'; @override String get extensionDefaultProvider => 'Varsayılan (Deezer)'; @override - String get extensionDefaultProviderSubtitle => - 'Uygulamanın kendi aramasını kullan'; + String get extensionDefaultProviderSubtitle => 'Yerleşik aramayı kullan'; @override - String get extensionAuthor => 'Geliştirici'; + String get extensionAuthor => 'Oluşturan'; @override - String get extensionId => 'Kimlik (ID)'; + String get extensionId => 'ID'; @override String get extensionError => 'Hata'; @override - String get extensionCapabilities => 'Yetenekler'; + String get extensionCapabilities => 'Özellikler'; @override - String get extensionMetadataProvider => 'Şarkı Verisi (Metadata) Kaynağı'; + String get extensionMetadataProvider => 'Meta Veri Sağlayıcı'; @override - String get extensionDownloadProvider => 'İndirme Sağlayıcısı'; + String get extensionDownloadProvider => 'İndirme Sağlayıcı'; @override - String get extensionLyricsProvider => 'Şarkı Sözü Sağlayıcısı'; + String get extensionLyricsProvider => 'Şarkı Sözü Sağlayıcı'; @override - String get extensionUrlHandler => 'Bağlantı Okuyucu'; + String get extensionUrlHandler => 'URL İşleyici'; @override String get extensionQualityOptions => 'Kalite Seçenekleri'; @override - String get extensionPostProcessingHooks => 'İndirme Sonrası İşlemler'; + String get extensionPostProcessingHooks => 'Son İşlem Kancaları'; @override String get extensionPermissions => 'İzinler'; @@ -1401,103 +1393,102 @@ class AppLocalizationsTr extends AppLocalizations { String get extensionSettings => 'Ayarlar'; @override - String get extensionRemoveButton => 'Eklentiyi Kaldır'; + String get extensionRemoveButton => 'Uzantıyı Kaldır'; @override - String get extensionUpdated => 'Son Güncelleme'; + String get extensionUpdated => 'Güncellendi'; @override String get extensionMinAppVersion => 'Minimum Uygulama Sürümü'; @override - String get extensionCustomTrackMatching => 'Özel Eşleştirme Algoritması'; + String get extensionCustomTrackMatching => 'Özel Parça Eşleştirme'; @override - String get extensionPostProcessing => 'İşlem Sonrası Özellikleri'; + String get extensionPostProcessing => 'Son İşlem'; @override String extensionHooksAvailable(int count) { - return '$count özel kanca (hook) mevcut'; + return '$count kanca kullanılabilir'; } @override String extensionPatternsCount(int count) { - return '$count bağlantı kalıbı'; + return '$count desen'; } @override String extensionStrategy(String strategy) { - return 'Eşleştirme Stratejisi: $strategy'; + return 'Strateji: $strategy'; } @override String get extensionsProviderPrioritySection => 'Sağlayıcı Önceliği'; @override - String get extensionsInstalledSection => 'Yüklü Eklentiler'; + String get extensionsInstalledSection => 'Kurulu uzantılar'; @override - String get extensionsNoExtensions => 'Henüz eklenti yüklenmemiş'; + String get extensionsNoExtensions => 'Hiçbir eklenti kurulmamış'; @override String get extensionsNoExtensionsSubtitle => - 'Yeni müzik kaynakları eklemek için .spotiflac-ext dosyalarını yükleyin'; + 'Yeni sağlayıcılar eklemek için .spotiflac-ext dosyalarını yükleyin'; @override - String get extensionsInstallButton => 'Eklenti Yükle'; + String get extensionsInstallButton => 'Uzantı Yükle'; @override String get extensionsInfoTip => - 'Eklentiler yeni veri ve indirme kaynakları ekleyebilir. Lütfen eklentileri sadece güvendiğiniz kaynaklardan yükleyin.'; + 'Uzantılar yeni meta veri ve indirme sağlayıcıları ekleyebilir. Yalnızca güvenilir kaynaklardan gelen uzantıları yükleyin.'; @override - String get extensionsInstalledSuccess => 'Eklenti başarıyla yüklendi'; + String get extensionsInstalledSuccess => 'Uzantı başarıyla yüklendi'; @override String get extensionsDownloadPriority => 'İndirme Önceliği'; @override String get extensionsDownloadPrioritySubtitle => - 'İndirme servislerinin deneneceği sırayı belirleyin'; + 'İndirme servisi sırasını ayarla'; @override - String get extensionsFallbackTitle => 'Fallback Extensions'; + String get extensionsFallbackTitle => 'Yedekleme Uzantıları'; @override String get extensionsFallbackSubtitle => - 'Choose which installed download extensions can be used as fallback'; + 'Hangi yüklü indirme uzantılarının yedekleme olarak kullanılabileceğini seçin'; @override String get extensionsNoDownloadProvider => - 'İndirme sağlayıcısı barındıran bir eklenti yok'; + 'İndirme sağlayıcısı olan uzantı yok'; @override - String get extensionsMetadataPriority => 'Arama Kaynağı Önceliği'; + String get extensionsMetadataPriority => 'Meta Veri Önceliği'; @override String get extensionsMetadataPrioritySubtitle => - 'Arama ve veri kaynaklarının sırasını belirleyin'; + 'Arama ve meta veri kaynağı sırasını ayarla'; @override String get extensionsNoMetadataProvider => - 'Şarkı verisi (metadata) barındıran bir eklenti yok'; + 'Meta veri sağlayıcısı içeren uzantı bulunamadı'; @override - String get extensionsSearchProvider => 'Arama Servisi'; + String get extensionsSearchProvider => 'Arama Sağlayıcısı'; @override - String get extensionsNoCustomSearch => - 'Özel arama özelliği olan bir eklenti yok'; + String get extensionsNoCustomSearch => 'Özel arama içeren uzantı bulunamadı'; @override String get extensionsSearchProviderDescription => - 'Şarkı aramak için kullanılacak servisi seçin'; + 'Parça aramak için hangi servisin kullanılacağını seçin'; @override String get extensionsCustomSearch => 'Özel arama'; @override - String get extensionsErrorLoading => 'Eklenti yüklenirken hata oluştu'; + String get extensionsErrorLoading => 'Uzantı yüklenirken hata oluştu'; @override String get qualityFlacLossless => 'FLAC Kayıpsız'; @@ -1506,121 +1497,122 @@ class AppLocalizationsTr extends AppLocalizations { String get qualityFlacLosslessSubtitle => '16-bit / 44.1kHz'; @override - String get qualityHiResFlac => 'Hi-Res FLAC (Yüksek Çözünürlüklü)'; + String get qualityHiResFlac => 'Hi-Res FLAC'; @override String get qualityHiResFlacSubtitle => '24-bit / 96kHz\'e kadar'; @override - String get qualityHiResFlacMax => 'Hi-Res FLAC Maksimum'; + String get qualityHiResFlacMax => 'Hi-Res FLAC Max'; @override String get qualityHiResFlacMaxSubtitle => '24-bit / 192kHz\'e kadar'; @override - String get downloadLossy320 => 'Kayıplı (Lossy) 320kbps'; + String get downloadLossy320 => 'Kayıplı 320kbps'; @override - String get downloadLossyFormat => 'Kayıplı Formatı'; + String get downloadLossyFormat => 'Kayıplı Format'; @override - String get downloadLossy320Format => 'Kayıplı (Lossy) 320kbps Formatı'; + String get downloadLossy320Format => 'Kayıplı 320kbps Formatı'; @override String get downloadLossy320FormatDesc => - 'Tidal\'dan 320kbps kalitesinde indirirken kullanılacak formatı seçin. Orijinal AAC yayını seçtiğiniz formata dönüştürülecektir.'; + 'Tidal 320kbps kayıplı indirmeler için çıktı formatını seçin. Orijinal AAC akışı seçtiğiniz formata dönüştürülecektir.'; @override String get downloadLossyMp3 => 'MP3 320kbps'; @override - String get downloadLossyMp3Subtitle => 'En iyi uyumluluk, şarkı başı ~10MB'; + String get downloadLossyMp3Subtitle => + 'En iyi uyumluluk, parça başına ~10 Mb'; @override String get downloadLossyOpus256 => 'Opus 256kbps'; @override String get downloadLossyOpus256Subtitle => - 'En iyi Opus kalitesi, şarkı başı ~8MB'; + 'En iyi Opus kalitesi, parça başına ~8 Mb'; @override String get downloadLossyOpus128 => 'Opus 128kbps'; @override - String get downloadLossyOpus128Subtitle => 'En küçük boyut, şarkı başı ~4MB'; + String get downloadLossyOpus128Subtitle => + 'En küçük boyut, parça başına ~4 Mb'; @override String get qualityNote => - 'Gerçek kalite, şarkının serviste hangi kalitede bulunduğuna bağlıdır.'; + 'Gerçek kalite, parçanın servisteki uygunluğuna bağlıdır'; @override String get downloadAskBeforeDownload => 'İndirmeden Önce Sor'; @override - String get downloadDirectory => 'İndirme Klasörü'; + String get downloadDirectory => 'İndirme Dizini'; @override - String get downloadSeparateSinglesFolder => 'Single\'ları Ayrı Klasöre Koy'; + String get downloadSeparateSinglesFolder => 'Ayrı Single Klasörü'; @override - String get downloadAlbumFolderStructure => 'Albüm Klasörü Düzeni'; + String get downloadAlbumFolderStructure => 'Albüm Klasör Yapısı'; @override String get downloadUseAlbumArtistForFolders => - 'Klasörler için Albüm Sanatçısını Kullan'; + 'Klasörler için Albüm Sanatçısı\'nı kullan'; @override String get downloadUsePrimaryArtistOnly => - 'Klasörlerde Sadece Ana Sanatçı (Düetleri Gizle)'; + 'Klasörler için yalnızca birincil sanatçıyı kullan'; @override String get downloadUsePrimaryArtistOnlyEnabled => - 'Konuk sanatçılar klasör adından silinir (Örn: Justin Bieber, Quavo → Justin Bieber)'; + 'Düet sanatçıları klasör adından kaldırılır (örn. Justin Bieber, Quavo → Justin Bieber)'; @override String get downloadUsePrimaryArtistOnlyDisabled => - 'Klasör adına tüm sanatçılar yazılır'; + 'Klasör adı için tam sanatçı dizesi kullanılır'; @override - String get downloadSelectQuality => 'Kaliteyi Seçin'; + String get downloadSelectQuality => 'Kalite seçin'; @override - String get downloadFrom => 'İndirme Kaynağı:'; + String get downloadFrom => 'İndirme Kaynağı'; @override - String get appearanceAmoledDark => 'AMOLED Koyu (Tam Siyah)'; + String get appearanceAmoledDark => 'AMOLED Koyu'; @override - String get appearanceAmoledDarkSubtitle => - 'Tamamen siyah arka plan (OLED ekranlar için)'; + String get appearanceAmoledDarkSubtitle => 'Saf siyah arka plan'; @override String get queueClearAll => 'Tümünü Temizle'; @override String get queueClearAllMessage => - 'Tüm indirme sırasını temizlemek istediğinize emin misiniz?'; + 'Tüm indirmeleri temizlemek istediğinizden emin misiniz?'; @override String get settingsAutoExportFailed => - 'Başarısız İndirmeleri Otomatik Dışa Aktar'; + 'Başarısız indirmeleri otomatik dışa aktar'; @override String get settingsAutoExportFailedSubtitle => - 'İndirilemeyen şarkıların listesini TXT dosyası olarak kaydeder'; + 'Başarısız indirmeleri otomatik olarak TXT dosyasına kaydet'; @override - String get settingsDownloadNetwork => 'İndirme İçin Kullanılacak Ağ'; + String get settingsDownloadNetwork => 'İndirme Ağı'; @override - String get settingsDownloadNetworkAny => 'Wi-Fi + Mobil Veri'; + String get settingsDownloadNetworkAny => 'WiFi + Mobil Veri'; @override - String get settingsDownloadNetworkWifiOnly => 'Sadece Wi-Fi'; + String get settingsDownloadNetworkWifiOnly => 'Yalnızca WiFi'; @override String get settingsDownloadNetworkSubtitle => - 'Sadece Wi-Fi seçildiğinde, mobil verideyken indirmeler otomatik duraklatılır.'; + 'İndirmeler için hangi ağın kullanılacağını seçin. Yalnızca WiFi olarak ayarlandığında, mobil veriye geçildiğinde indirmeler duraklatılır.'; @override String get albumFolderArtistAlbum => 'Sanatçı / Albüm'; @@ -1637,7 +1629,7 @@ class AppLocalizationsTr extends AppLocalizations { 'Albümler/Sanatçı Adı/[2005] Albüm Adı/'; @override - String get albumFolderAlbumOnly => 'Sadece Albüm'; + String get albumFolderAlbumOnly => 'Yalnızca Albüm'; @override String get albumFolderAlbumOnlySubtitle => 'Albümler/Albüm Adı/'; @@ -1649,19 +1641,19 @@ class AppLocalizationsTr extends AppLocalizations { String get albumFolderYearAlbumSubtitle => 'Albümler/[2005] Albüm Adı/'; @override - String get albumFolderArtistAlbumSingles => 'Sanatçı / Albüm + Single\'lar'; + String get albumFolderArtistAlbumSingles => 'Sanatçı / Albüm + Singlelar'; @override String get albumFolderArtistAlbumSinglesSubtitle => - 'Sanatçı/Albüm/ ve Sanatçı/Single\'lar/'; + 'Sanatçı/Albüm/ ve Sanatçı/Singlelar/'; @override String get albumFolderArtistAlbumFlat => - 'Sanatçı / Albüm (Single\'lar ayrı klasörsüz)'; + 'Sanatçı / Albüm (Singlelar alt klasörsüz)'; @override String get albumFolderArtistAlbumFlatSubtitle => - 'Sanatçı/Albüm/ ve Sanatçı/sarki.flac'; + 'Sanatçı/Albüm/ ve Sanatçı/şarkı.flac'; @override String get downloadedAlbumDeleteSelected => 'Seçilenleri Sil'; @@ -1671,10 +1663,10 @@ class AppLocalizationsTr extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'şarkı', - one: 'şarkı', + other: 'parça', + one: 'parça', ); - return 'Bu albümden $count $_temp0 silinsin mi?\n\nBu işlem, dosyaları cihazınızdan da tamamen silecek.'; + return 'Bu albümden $count $_temp0 parça silinsin mi?\n\nBu işlem dosyaları depolama alanından da kalıcı olarak silecektir.'; } @override @@ -1683,24 +1675,24 @@ class AppLocalizationsTr extends AppLocalizations { } @override - String get downloadedAlbumAllSelected => 'Tüm şarkılar seçildi'; + String get downloadedAlbumAllSelected => 'Tüm parçalar seçildi'; @override - String get downloadedAlbumTapToSelect => 'Seçmek için şarkılara dokunun'; + String get downloadedAlbumTapToSelect => 'Seçmek için parçalara dokunun'; @override String downloadedAlbumDeleteCount(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'Şarkıyı', - one: 'Şarkıyı', + other: 'parçayı', + one: 'parçayı', ); - return '$count $_temp0 Sil'; + return '$count $_temp0 sil'; } @override - String get downloadedAlbumSelectToDelete => 'Silinecek şarkıları seçin'; + String get downloadedAlbumSelectToDelete => 'Silinecek parçaları seçin'; @override String downloadedAlbumDiscHeader(int discNumber) { @@ -1720,7 +1712,7 @@ class AppLocalizationsTr extends AppLocalizations { String get recentTypePlaylist => 'Çalma Listesi'; @override - String get recentEmpty => 'Henüz yeni bir arama yok'; + String get recentEmpty => 'Henüz son kullanılan öğe yok'; @override String get recentShowAllDownloads => 'Tüm İndirmeleri Göster'; @@ -1731,30 +1723,30 @@ class AppLocalizationsTr extends AppLocalizations { } @override - String get discographyDownload => 'Tüm Diskografiyi İndir'; + String get discographyDownload => 'Diskografiyi İndir'; @override String get discographyDownloadAll => 'Tümünü İndir'; @override String discographyDownloadAllSubtitle(int count, int albumCount) { - return '$albumCount albüm/single üzerinden toplam $count şarkı'; + return '$albumCount yayından $count parça'; } @override - String get discographyAlbumsOnly => 'Sadece Albümler'; + String get discographyAlbumsOnly => 'Yalnızca Albümler'; @override String discographyAlbumsOnlySubtitle(int count, int albumCount) { - return '$albumCount albümden toplam $count şarkı'; + return '$albumCount albümden $count parça'; } @override - String get discographySinglesOnly => 'Sadece Single\'lar ve EP\'ler'; + String get discographySinglesOnly => 'Yalnızca Single\'lar ve EP\'ler'; @override String discographySinglesOnlySubtitle(int count, int albumCount) { - return '$albumCount single üzerinden toplam $count şarkı'; + return '$albumCount tekliden $count parça'; } @override @@ -1762,14 +1754,14 @@ class AppLocalizationsTr extends AppLocalizations { @override String get discographySelectAlbumsSubtitle => - 'İstediğiniz albümleri veya single\'ları kendiniz seçin'; + 'Belirli albümleri veya single\'ları seçin'; @override - String get discographyFetchingTracks => 'Şarkılar alınıyor...'; + String get discographyFetchingTracks => 'Parçalar getiriliyor...'; @override String discographyFetchingAlbum(int current, int total) { - return 'Alınıyor: $current / $total...'; + return '$total üzerinden $current getiriliyor...'; } @override @@ -1782,19 +1774,19 @@ class AppLocalizationsTr extends AppLocalizations { @override String discographyAddedToQueue(int count) { - return '$count şarkı indirme sırasına eklendi'; + return '$count parça kuyruğa eklendi'; } @override String discographySkippedDownloaded(int added, int skipped) { - return '$added şarkı eklendi, zaten inmiş olan $skipped şarkı atlandı'; + return '$added eklendi, $skipped zaten indirilmiş'; } @override - String get discographyNoAlbums => 'Bu sanatçıya ait albüm bulunamadı'; + String get discographyNoAlbums => 'Kullanılabilir albüm yok'; @override - String get discographyFailedToFetch => 'Bazı albümler yüklenemedi'; + String get discographyFailedToFetch => 'Bazı albümler getirilemedi'; @override String get sectionStorageAccess => 'Depolama Erişimi'; @@ -1803,38 +1795,37 @@ class AppLocalizationsTr extends AppLocalizations { String get allFilesAccess => 'Tüm Dosyalara Erişim'; @override - String get allFilesAccessEnabledSubtitle => - 'Cihazdaki herhangi bir klasöre yazabilir'; + String get allFilesAccessEnabledSubtitle => 'Herhangi bir klasöre yazabilir'; @override String get allFilesAccessDisabledSubtitle => - 'Sadece medya klasörleriyle sınırlı'; + 'Yalnızca medya klasörleriyle sınırlı'; @override String get allFilesAccessDescription => - 'Özel klasörlere kaydederken yazma hatası alıyorsanız bunu açın. Android 13 ve sonrasında bazı klasörlere erişim varsayılan olarak kısıtlanmıştır.'; + 'Özel klasörlere kaydederken yazma hatalarıyla karşılaşırsanız bunu etkinleştirin. Android 13 ve üzeri, varsayılan olarak belirli dizinlere erişimi kısıtlar.'; @override String get allFilesAccessDeniedMessage => - 'İzin reddedildi. Lütfen sistem ayarlarından \'Tüm dosyalara erişim\' iznini manuel olarak verin.'; + 'İzin reddedildi. Lütfen sistem ayarlarından \'Tüm dosyalara erişim\' iznini manuel olarak etkinleştirin.'; @override String get allFilesAccessDisabledMessage => - 'Tüm Dosyalara Erişim devre dışı. Uygulama sınırlı depolama izniyle çalışacak.'; + 'Tüm Dosyalara Erişim devre dışı bırakıldı. Uygulama kısıtlı depolama erişimi kullanacak.'; @override String get settingsLocalLibrary => 'Yerel Kitaplık'; @override String get settingsLocalLibrarySubtitle => - 'Telefonunuzdaki müzikleri tarayıp kopyaları bulun'; + 'Müziği tara ve kopyaları tespit et'; @override - String get settingsCache => 'Önbellek ve Depolama'; + String get settingsCache => 'Depolama ve Önbellek'; @override String get settingsCacheSubtitle => - 'Boyutu görüntüleyin ve gereksiz dosyaları temizleyin'; + 'Boyutu görüntüle ve önbelleğe alınmış verileri temizle'; @override String get libraryTitle => 'Yerel Kitaplık'; @@ -1843,91 +1834,90 @@ class AppLocalizationsTr extends AppLocalizations { String get libraryScanSettings => 'Tarama Ayarları'; @override - String get libraryEnableLocalLibrary => 'Yerel Kitaplık Taramasını Aç'; + String get libraryEnableLocalLibrary => 'Yerel Kitaplığı Etkinleştir'; @override String get libraryEnableLocalLibrarySubtitle => - 'İndirme yaparken elinizde olan şarkıları takip eder'; + 'Mevcut müziğinizi tarayın ve takip edin'; @override - String get libraryFolder => 'Taranacak Klasör'; + String get libraryFolder => 'Kitaplık Klasörü'; @override String get libraryFolderHint => 'Klasör seçmek için dokunun'; @override - String get libraryShowDuplicateIndicator => 'Kopya İndikatörünü Göster'; + String get libraryShowDuplicateIndicator => 'Kopya Belirtecini Göster'; @override String get libraryShowDuplicateIndicatorSubtitle => - 'Zaten indirmiş olduğunuz şarkıların yanında belirteç gösterir'; + 'Mevcut parçalar aranırken göster'; @override String get libraryAutoScan => 'Otomatik Tarama'; @override String get libraryAutoScanSubtitle => - 'Cihazınıza yeni eklenen müzikleri otomatik olarak bulur'; + 'Kitaplığınızı yeni dosyalar için otomatik olarak tarayın'; @override String get libraryAutoScanOff => 'Kapalı'; @override - String get libraryAutoScanOnOpen => 'Uygulama her açıldığında'; + String get libraryAutoScanOnOpen => 'Her uygulama açılışında'; @override - String get libraryAutoScanDaily => 'Günde bir'; + String get libraryAutoScanDaily => 'Günlük'; @override - String get libraryAutoScanWeekly => 'Haftada bir'; + String get libraryAutoScanWeekly => 'Haftalık'; @override - String get libraryActions => 'İşlemler'; + String get libraryActions => 'Eylemler'; @override String get libraryScan => 'Kitaplığı Tara'; @override - String get libraryScanSubtitle => 'Klasördeki müzik dosyalarını tarar'; + String get libraryScanSubtitle => 'Ses dosyaları için tara'; @override - String get libraryScanSelectFolderFirst => - 'Lütfen önce taranacak bir klasör seçin'; + String get libraryScanSelectFolderFirst => 'Önce bir klasör seçin'; @override String get libraryCleanupMissingFiles => 'Eksik Dosyaları Temizle'; @override String get libraryCleanupMissingFilesSubtitle => - 'Artık cihazınızda olmayan dosyaların kayıtlarını kaldırır'; + 'Eski dosya kalıntılarını temizleyin'; @override - String get libraryClear => 'Kitaplığı Temizle'; + String get libraryClear => 'Kitaplığı temizle'; @override - String get libraryClearSubtitle => 'Taranmış tüm şarkı kayıtlarını sıfırlar'; + String get libraryClearSubtitle => 'Taranan tüm parçaları sil'; @override - String get libraryClearConfirmTitle => 'Kitaplık Temizlensin mi?'; + String get libraryClearConfirmTitle => 'Kütüphaneyi temizle'; @override String get libraryClearConfirmMessage => - 'Uygulamanın kaydettiği tüm taranmış şarkı verileri silinecek. (Gerçek müzik dosyalarınız SİLİNMEYECEK).'; + 'Bu işlem, kitaplığınızdaki tüm taranmış parçaları siler. Asıl müzik dosyalarınız silinmez.'; @override - String get libraryAbout => 'Yerel Kitaplık Hakkında'; + String get libraryAbout => 'Yerel Kütüphane Hakkında'; @override String get libraryAboutDescription => - 'İndirme yaparken kopyaları (zaten inmiş olanları) tespit etmek için mevcut müzik arşivinizi tarar. FLAC, M4A, MP3, Opus ve OGG formatlarını destekler. Bilgiler şarkı dosyalarının kendi etiketlerinden (ID3 tag vb.) okunur.'; + 'İndirme işlemi sırasında mevcut müzik koleksiyonunuzu tarayarak yinelenen dosyaları tespit eder. FLAC, M4A, MP3, Opus ve OGG formatlarını destekler. Varsa, meta veriler dosya etiketlerinden okunur.'; @override String libraryTracksUnit(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'şarkı', - one: 'şarkı', + other: 'tracks', + one: 'track', ); return '$_temp0'; } @@ -1945,82 +1935,82 @@ class AppLocalizationsTr extends AppLocalizations { @override String libraryLastScanned(String time) { - return 'Son tarama: $time'; + return 'Last scanned: $time'; } @override - String get libraryLastScannedNever => 'Hiç taranmadı'; + String get libraryLastScannedNever => 'Never'; @override - String get libraryScanning => 'Taranıyor...'; + String get libraryScanning => 'Scanning...'; @override String get libraryScanFinalizing => 'Finalizing library...'; @override String libraryScanProgress(String progress, int total) { - return '%$progress (Toplam $total dosya)'; + return '$progress% of $total files'; } @override - String get libraryInLibrary => 'Cihazda Var'; + String get libraryInLibrary => 'In Library'; @override String libraryRemovedMissingFiles(int count) { - return 'Cihazda olmayan $count dosyanın kaydı temizlendi'; + return 'Removed $count missing files from library'; } @override - String get libraryCleared => 'Kitaplık kayıtları temizlendi'; + String get libraryCleared => 'Library cleared'; @override - String get libraryStorageAccessRequired => 'Depolama İzni Gerekli'; + String get libraryStorageAccessRequired => 'Storage Access Required'; @override String get libraryStorageAccessMessage => - 'Müzik kitaplığınızı taramak için SpotiFLAC\'ın depolama iznine ihtiyacı var. Lütfen ayarlardan izin verin.'; + 'SpotiFLAC needs storage access to scan your music library. Please grant permission in settings.'; @override - String get libraryFolderNotExist => 'Seçilen klasör artık mevcut değil'; + String get libraryFolderNotExist => 'Selected folder does not exist'; @override - String get librarySourceDownloaded => 'İndirildi'; + String get librarySourceDownloaded => 'Downloaded'; @override - String get librarySourceLocal => 'Cihazdan'; + String get librarySourceLocal => 'Local'; @override - String get libraryFilterAll => 'Tümü'; + String get libraryFilterAll => 'All'; @override - String get libraryFilterDownloaded => 'Uygulama İle İndirilenler'; + String get libraryFilterDownloaded => 'Downloaded'; @override - String get libraryFilterLocal => 'Yerel Dosyalar'; + String get libraryFilterLocal => 'Local'; @override String get libraryFilterTitle => 'Filtreler'; @override - String get libraryFilterReset => 'Sıfırla'; + String get libraryFilterReset => 'Reset'; @override - String get libraryFilterApply => 'Uygula'; + String get libraryFilterApply => 'Apply'; @override - String get libraryFilterSource => 'Kaynak'; + String get libraryFilterSource => 'Source'; @override - String get libraryFilterQuality => 'Kalite'; + String get libraryFilterQuality => 'Quality'; @override - String get libraryFilterQualityHiRes => 'Hi-Res (24-bit)'; + String get libraryFilterQualityHiRes => 'Hi-Res (24bit)'; @override - String get libraryFilterQualityCD => 'CD Kalitesi (16-bit)'; + String get libraryFilterQualityCD => 'CD (16bit)'; @override - String get libraryFilterQualityLossy => 'Kayıplı (Lossy)'; + String get libraryFilterQualityLossy => 'Lossy'; @override String get libraryFilterFormat => 'Format'; @@ -2044,13 +2034,13 @@ class AppLocalizationsTr extends AppLocalizations { String get libraryFilterMetadataMissingAlbumArtist => 'Missing album artist'; @override - String get libraryFilterSort => 'Sıralama'; + String get libraryFilterSort => 'Sort'; @override - String get libraryFilterSortLatest => 'En Yeniler'; + String get libraryFilterSortLatest => 'Latest'; @override - String get libraryFilterSortOldest => 'En Eskiler'; + String get libraryFilterSortOldest => 'Oldest'; @override String get libraryFilterSortAlbumAsc => 'Album (A-Z)'; @@ -2065,15 +2055,15 @@ class AppLocalizationsTr extends AppLocalizations { String get libraryFilterSortGenreDesc => 'Genre (Z-A)'; @override - String get timeJustNow => 'Az önce'; + String get timeJustNow => 'Just now'; @override String timeMinutesAgo(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: '$count dakika önce', - one: '1 dakika önce', + other: '$count minutes ago', + one: '1 minute ago', ); return '$_temp0'; } @@ -2083,202 +2073,199 @@ class AppLocalizationsTr extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: '$count saat önce', - one: '1 saat önce', + other: '$count hours ago', + one: '1 hour ago', ); return '$_temp0'; } @override - String get tutorialWelcomeTitle => 'SpotiFLAC\'a Hoş Geldiniz!'; + String get tutorialWelcomeTitle => 'Welcome to SpotiFLAC!'; @override String get tutorialWelcomeDesc => - 'En sevdiğiniz müzikleri kayıpsız kalitede nasıl indireceğinizi öğrenelim. Bu kısa rehber size temelleri gösterecek.'; + 'En sevdiğiniz müzikleri kayıpsız kalitede nasıl indirebileceğinizi öğrenelim. Bu kısa eğitim size temel bilgileri gösterecek.'; @override String get tutorialWelcomeTip1 => - 'Müzikleri bulmak için bir Spotify ya da Deezer bağlantısı yapıştırabilir veya adıyla arayabilirsiniz'; + 'Spotify, Deezer\'dan müzik indirin veya desteklenen herhangi bir URL\'yi yapıştırın'; @override String get tutorialWelcomeTip2 => - 'Şarkıları Tidal, Qobuz veya Deezer altyapısıyla en yüksek kalitede (FLAC) indirin'; + 'Tidal, Qobuz veya Deezer\'dan FLAC kalitesinde ses alın'; @override String get tutorialWelcomeTip3 => - 'Albüm kapağı, şarkı sözleri ve tüm şarkı verileri dosyanın içine otomatik olarak gömülür'; + 'Otomatik meta veri, kapak resmi ve şarkı sözü gömme'; @override - String get tutorialSearchTitle => 'Müzik Bulmak Çok Kolay'; + String get tutorialSearchTitle => 'Müzik Bulma'; @override String get tutorialSearchDesc => - 'İstediğiniz müzikleri bulmanın iki basit yolu var.'; + 'İndirmek istediğiniz müziği bulmanın iki kolay yolu vardır.'; @override - String get tutorialDownloadTitle => 'Müzikleri İndirme'; + String get tutorialDownloadTitle => 'Müzik İndirme'; @override String get tutorialDownloadDesc => - 'Şarkıları indirmek hızlı ve pürüzsüzdür. İşte süreç böyle işliyor:'; + 'Müzik indirmek basit ve hızlıdır. İşte nasıl çalıştığı.'; @override - String get tutorialLibraryTitle => 'Kişisel Kitaplığınız'; + String get tutorialLibraryTitle => 'Kitaplığınız'; @override String get tutorialLibraryDesc => - 'İndirdiğiniz tüm müzikler Kitaplık sekmesinde düzenli bir şekilde tutulur.'; + 'İndirdiğiniz tüm müzikler Kitaplık sekmesinde düzenlenir.'; @override String get tutorialLibraryTip1 => - 'İndirme ilerlemenizi ve sırayı Kitaplık sekmesinden takip edin'; + 'Kitaplık sekmesinden indirme ilerlemesini ve kuyruğu görüntüleyin'; @override String get tutorialLibraryTip2 => - 'İndirdiğiniz şarkıyı favori müzik çalarınızda açmak için üzerine dokunun'; + 'Müzik çalarınızla oynatmak için herhangi bir parçaya dokunun'; @override String get tutorialLibraryTip3 => - 'Daha rahat göz atmak için liste ve ızgara görünümleri arasında geçiş yapın'; + 'Daha iyi göz atmak için liste ve ızgara görünümü arasında geçiş yapın'; @override - String get tutorialExtensionsTitle => 'Eklentilerle Güçlendirin'; + String get tutorialExtensionsTitle => 'Uzantılar'; @override String get tutorialExtensionsDesc => - 'Topluluğun geliştirdiği eklentilerle uygulamanın sınırlarını aşın.'; + 'Topluluk uzantılarıyla uygulamanın yeteneklerini artırın.'; @override String get tutorialExtensionsTip1 => - 'İlginizi çekebilecek eklentileri keşfetmek için Mağaza sekmesine göz atın'; + 'Faydalı uzantıları keşfetmek için Depo sekmesine göz atın'; @override String get tutorialExtensionsTip2 => - 'Uygulamaya yepyeni indirme ve arama kaynakları ekleyin'; + 'Yeni indirme sağlayıcıları veya arama kaynakları ekleyin'; @override String get tutorialExtensionsTip3 => - 'Farklı şarkı sözü sağlayıcıları ve yepyeni özellikler kazanın'; + 'Şarkı sözleri, gelişmiş meta veriler ve daha fazla özellik edinin'; @override - String get tutorialSettingsTitle => 'Deneyiminizi Kişiselleştirin'; + String get tutorialSettingsTitle => 'Deneyiminizi Özelleştirin'; @override String get tutorialSettingsDesc => - 'Uygulamanın nasıl davranacağını Ayarlar menüsünden zevkinize göre özelleştirin.'; + 'Uygulamayı Ayarlar\'dan tercihlerinize göre kişiselleştirin.'; @override String get tutorialSettingsTip1 => - 'İndirme konumunu ve klasörleme biçimini değiştirin'; + 'İndirme konumunu ve klasör düzenini değiştirin'; @override String get tutorialSettingsTip2 => - 'Varsayılan ses kalitesini ve indirme formatınızı belirleyin'; + 'Varsayılan ses kalitesi ve format tercihlerini ayarlayın'; @override - String get tutorialSettingsTip3 => - 'Temayı, renkleri ve uygulamanın görünümünü ayarlayın'; + String get tutorialSettingsTip3 => 'Customize app theme and appearance'; @override String get tutorialReadyMessage => - 'İşte bu kadar! Artık favori müziklerinizi indirmeye hazırsınız.'; + 'You\'re all set! Start downloading your favorite music now.'; @override - String get libraryForceFullScan => 'Tam Taramaya Zorla'; + String get libraryForceFullScan => 'Force Full Scan'; @override - String get libraryForceFullScanSubtitle => - 'Önbelleği yoksayarak klasördeki tüm dosyaları baştan tarar'; + String get libraryForceFullScanSubtitle => 'Rescan all files, ignoring cache'; @override - String get cleanupOrphanedDownloads => 'Geçersiz İndirmeleri Temizle'; + String get cleanupOrphanedDownloads => 'Cleanup Orphaned Downloads'; @override String get cleanupOrphanedDownloadsSubtitle => - 'Cihazdan silinmiş dosyalara ait eski geçmiş kayıtlarını kaldırır'; + 'Remove history entries for files that no longer exist'; @override String cleanupOrphanedDownloadsResult(int count) { - return 'Geçmişten $count geçersiz kayıt kaldırıldı'; + return 'Removed $count orphaned entries from history'; } @override - String get cleanupOrphanedDownloadsNone => - 'Temizlenecek geçersiz kayıt bulunamadı'; + String get cleanupOrphanedDownloadsNone => 'No orphaned entries found'; @override - String get cacheTitle => 'Önbellek ve Depolama'; + String get cacheTitle => 'Storage & Cache'; @override - String get cacheSummaryTitle => 'Önbellek Özeti'; + String get cacheSummaryTitle => 'Cache overview'; @override String get cacheSummarySubtitle => - 'Önbelleği temizlemek indirdiğiniz müzik dosyalarını SİLMEZ.'; + 'Clearing cache will not remove downloaded music files.'; @override String cacheEstimatedTotal(String size) { - return 'Tahmini önbellek kullanımı: $size'; + return 'Estimated cache usage: $size'; } @override - String get cacheSectionStorage => 'Önbelleğe Alınan Veriler'; + String get cacheSectionStorage => 'Cached Data'; @override - String get cacheSectionMaintenance => 'Bakım ve Temizlik'; + String get cacheSectionMaintenance => 'Maintenance'; @override - String get cacheAppDirectory => 'Uygulama Önbelleği'; + String get cacheAppDirectory => 'App cache directory'; @override String get cacheAppDirectoryDesc => - 'İnternet yanıtları, küçük resimler ve uygulamanın tuttuğu geçici dosyalar.'; + 'HTTP responses, WebView data, and other temporary app data.'; @override - String get cacheTempDirectory => 'Geçici Klasör'; + String get cacheTempDirectory => 'Temporary directory'; @override String get cacheTempDirectoryDesc => - 'İndirme ve ses dönüştürme işlemleri sırasında oluşan artık dosyalar.'; + 'Temporary files from downloads and audio conversion.'; @override - String get cacheCoverImage => 'Kapak Resmi Önbelleği'; + String get cacheCoverImage => 'Cover image cache'; @override String get cacheCoverImageDesc => - 'Önceden yüklenmiş albüm kapakları. Silinirse tekrar görüntülediğinizde yeniden indirilir.'; + 'Downloaded album and track cover art. Will re-download when viewed.'; @override - String get cacheLibraryCover => 'Kitaplık Kapağı Önbelleği'; + String get cacheLibraryCover => 'Library cover cache'; @override String get cacheLibraryCoverDesc => - 'Yerel müzik dosyalarınızdan çıkarılmış kapaklar. Silinirse sonraki taramada yeniden oluşturulur.'; + 'Cover art extracted from local music files. Will re-extract on next scan.'; @override - String get cacheExploreFeed => 'Keşfet Akışı Önbelleği'; + String get cacheExploreFeed => 'Explore feed cache'; @override String get cacheExploreFeedDesc => - 'Keşfet sekmesindeki (yeni çıkanlar vb.) içerikler. Silerseniz sayfayı açtığınızda yenilenir.'; + 'Explore tab content (new releases, trending). Will refresh on next visit.'; @override - String get cacheTrackLookup => 'Şarkı Kimliği Önbelleği'; + String get cacheTrackLookup => 'Track lookup cache'; @override String get cacheTrackLookupDesc => - 'Spotify/Deezer ID eşleşmeleri. Temizlerseniz ilk birkaç aramanız biraz yavaşlayabilir.'; + 'Spotify/Deezer track ID lookups. Clearing may slow next few searches.'; @override String get cacheCleanupUnusedDesc => - 'Artık cihazınızda var olmayan dosyaların geçmiş kayıtlarını ve kitaplık verilerini temizler.'; + 'Remove orphaned download history and library entries for missing files.'; @override - String get cacheNoData => 'Veri yok'; + String get cacheNoData => 'No cached data'; @override String cacheSizeWithFiles(String size, int count) { - return '$size ($count dosya)'; + return '$size in $count files'; } @override @@ -2288,70 +2275,68 @@ class AppLocalizationsTr extends AppLocalizations { @override String cacheEntries(int count) { - return '$count kayıt'; + return '$count entries'; } @override String cacheClearSuccess(String target) { - return 'Temizlendi: $target'; + return 'Cleared: $target'; } @override - String get cacheClearConfirmTitle => 'Önbelleği Temizle?'; + String get cacheClearConfirmTitle => 'Clear cache?'; @override String cacheClearConfirmMessage(String target) { - return 'Sadece \"$target\" için olan önbellek silinecek. İndirdiğiniz hiçbir müzik dosyasına dokunulmayacak.'; + return 'This will clear cached data for $target. Downloaded music files will not be deleted.'; } @override - String get cacheClearAllConfirmTitle => 'Tüm Önbelleği Temizle?'; + String get cacheClearAllConfirmTitle => 'Clear all cache?'; @override String get cacheClearAllConfirmMessage => - 'Bu sayfadaki tüm önbellek kategorileri temizlenecek. İndirdiğiniz müzik dosyaları kesinlikle SİLİNMEYECEK.'; + 'This will clear all cache categories on this page. Downloaded music files will not be deleted.'; @override - String get cacheClearAll => 'Tüm Önbelleği Temizle'; + String get cacheClearAll => 'Clear all cache'; @override - String get cacheCleanupUnused => 'Gereksiz Dosyaları Temizle'; + String get cacheCleanupUnused => 'Cleanup unused data'; @override String get cacheCleanupUnusedSubtitle => - 'Cihazda olmayan dosyalara ait geçmiş ve kitaplık kayıtlarını kaldırır'; + 'Remove orphaned download history and missing library entries'; @override String cacheCleanupResult(int downloadCount, int libraryCount) { - return 'Temizlik Bitti: $downloadCount geçersiz geçmiş, $libraryCount eksik kitaplık kaydı kaldırıldı'; + return 'Cleanup completed: $downloadCount orphaned downloads, $libraryCount missing library entries'; } @override - String get cacheRefreshStats => 'Boyutları Yenile'; + String get cacheRefreshStats => 'Refresh stats'; @override - String get trackSaveCoverArt => 'Albüm Kapağını Kaydet'; + String get trackSaveCoverArt => 'Save Cover Art'; @override - String get trackSaveCoverArtSubtitle => - 'Albüm kapağını resim (.jpg) dosyası olarak dışa aktar'; + String get trackSaveCoverArtSubtitle => 'Save album art as .jpg file'; @override - String get trackSaveLyrics => 'Şarkı Sözlerini Kaydet (.lrc)'; + String get trackSaveLyrics => 'Save Lyrics (.lrc)'; @override - String get trackSaveLyricsSubtitle => - 'Şarkı sözlerini çekip .lrc dosyası olarak kaydeder'; + String get trackSaveLyricsSubtitle => 'Fetch and save lyrics as .lrc file'; @override - String get trackSaveLyricsProgress => 'Şarkı sözleri kaydediliyor...'; + String get trackSaveLyricsProgress => 'Saving lyrics...'; @override - String get trackReEnrich => 'Bilgileri İnternetten Güncelle (Re-enrich)'; + String get trackReEnrich => 'Re-enrich'; @override String get trackReEnrichOnlineSubtitle => - 'İnternetten şarkı verilerini (metadata) bulup dosyaya yeniden işler'; + 'Search metadata online and embed into file'; @override String get trackReEnrichFieldsTitle => 'Fields to update'; @@ -2378,82 +2363,78 @@ class AppLocalizationsTr extends AppLocalizations { String get trackReEnrichSelectAll => 'Select All'; @override - String get trackEditMetadata => 'Şarkı Bilgilerini Düzenle'; + String get trackEditMetadata => 'Edit Metadata'; @override String trackCoverSaved(String fileName) { - return 'Kapak resmi \"$fileName\" adıyla kaydedildi'; + return 'Cover art saved to $fileName'; } @override - String get trackCoverNoSource => 'Geçerli bir kapak resmi kaynağı bulunamadı'; + String get trackCoverNoSource => 'No cover art source available'; @override String trackLyricsSaved(String fileName) { - return 'Sözler \"$fileName\" adıyla kaydedildi'; + return 'Lyrics saved to $fileName'; } @override - String get trackReEnrichProgress => - 'Şarkı bilgileri (metadata) güncelleniyor...'; + String get trackReEnrichProgress => 'Re-enriching metadata...'; @override - String get trackReEnrichSearching => - 'İnternette şarkı bilgisi (metadata) aranıyor...'; + String get trackReEnrichSearching => 'Searching metadata online...'; @override - String get trackReEnrichSuccess => - 'Şarkı bilgileri dosyaya başarıyla işlendi'; + String get trackReEnrichSuccess => 'Metadata re-enriched successfully'; @override - String get trackReEnrichFfmpegFailed => - 'Sözleri (veya verileri) dosyaya yazarken hata oluştu'; + String get trackReEnrichFfmpegFailed => 'FFmpeg metadata embed failed'; @override - String get queueFlacAction => 'Bunu FLAC Olarak İndir'; + String get queueFlacAction => 'Queue FLAC'; @override String queueFlacConfirmMessage(int count) { - return 'Seçilen şarkılar için internette FLAC eşleşmesi aranacak ve indirme sırasına eklenecek.\n\nMevcut dosyalarınıza dokunulmayacak veya silinmeyecek.\n\nSadece yüksek oranda eşleşenler otomatik olarak sıraya eklenir.\n\n$count şarkı seçildi'; + return 'Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n$count selected'; } @override String queueFlacFindingProgress(int current, int total) { - return 'FLAC eşleşmeleri aranıyor... ($current/$total)'; + return 'Finding FLAC matches... ($current/$total)'; } @override String get queueFlacNoReliableMatches => - 'Seçiminiz için internette güvenilir bir eşleşme bulunamadı'; + 'No reliable online matches found for the selection'; @override String queueFlacQueuedWithSkipped(int addedCount, int skippedCount) { - return '$addedCount şarkı sıraya eklendi, $skippedCount şarkı eşleşmediği için atlandı'; + return 'Added $addedCount tracks to queue, skipped $skippedCount'; } @override String trackSaveFailed(String error) { - return 'İşlem başarısız: $error'; + return 'Failed: $error'; } @override - String get trackConvertFormat => 'Ses Formatını Dönüştür'; + String get trackConvertFormat => 'Convert Format'; @override String get trackConvertFormatSubtitle => - 'Dosyayı MP3, Opus, ALAC veya FLAC formatına çevirin'; + 'Convert to MP3, Opus, ALAC, or FLAC'; @override - String get trackConvertTitle => 'Sesi Dönüştür'; + String get trackConvertTitle => 'Convert Audio'; @override - String get trackConvertTargetFormat => 'Hedef Format'; + String get trackConvertTargetFormat => 'Target Format'; @override - String get trackConvertBitrate => 'Bit Hızı (Kalite)'; + String get trackConvertBitrate => 'Bitrate'; @override - String get trackConvertConfirmTitle => 'Dönüşümü Onayla'; + String get trackConvertConfirmTitle => 'Confirm Conversion'; @override String trackConvertConfirmMessage( @@ -2461,7 +2442,7 @@ class AppLocalizationsTr extends AppLocalizations { String targetFormat, String bitrate, ) { - return '$sourceFormat formatından $targetFormat formatına ($bitrate) dönüştürülsün mü?\n\nDönüşüm bittikten sonra orijinal dosya tamamen silinecektir.'; + return 'Convert from $sourceFormat to $targetFormat at $bitrate?\n\nThe original file will be deleted after conversion.'; } @override @@ -2469,254 +2450,250 @@ class AppLocalizationsTr extends AppLocalizations { String sourceFormat, String targetFormat, ) { - return '$sourceFormat formatından $targetFormat formatına dönüştürülsün mü? (Kayıpsız format, kalite kaybı yaşanmaz)\n\nDönüşüm bittikten sonra orijinal dosya tamamen silinecektir.'; + return 'Convert from $sourceFormat to $targetFormat? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.'; } @override String get trackConvertLosslessHint => - 'Kayıpsız bir formata dönüştürülüyor (Kalite düşüşü olmaz)'; + 'Lossless conversion — no quality loss'; @override - String get trackConvertConverting => 'Ses dönüştürülüyor...'; + String get trackConvertConverting => 'Converting audio...'; @override String trackConvertSuccess(String format) { - return 'Dosya başarıyla $format formatına çevrildi'; + return 'Converted to $format successfully'; } @override - String get trackConvertFailed => 'Dönüşüm işlemi başarısız oldu'; + String get trackConvertFailed => 'Conversion failed'; @override - String get cueSplitTitle => 'CUE Dosyasını Parçalara Böl'; + String get cueSplitTitle => 'Split CUE Sheet'; @override - String get cueSplitSubtitle => - 'Tek parça olan CUE+FLAC dosyasını ayrı şarkılara böler'; + String get cueSplitSubtitle => 'Split CUE+FLAC into individual tracks'; @override String cueSplitAlbum(String album) { - return 'Albüm: $album'; + return 'Album: $album'; } @override String cueSplitArtist(String artist) { - return 'Sanatçı: $artist'; + return 'Artist: $artist'; } @override String cueSplitTrackCount(int count) { - return '$count şarkı var'; + return '$count tracks'; } @override - String get cueSplitConfirmTitle => 'CUE Dosyasını Böl'; + String get cueSplitConfirmTitle => 'Split CUE Album'; @override String cueSplitConfirmMessage(String album, int count) { - return '\"$album\" albümünü $count ayrı FLAC dosyasına bölmek istiyor musunuz?\n\nYeni dosyalar orijinal dosyanın bulunduğu klasöre kaydedilecektir.'; + return 'Split \"$album\" into $count individual FLAC files?\n\nFiles will be saved to the same directory.'; } @override String cueSplitSplitting(int current, int total) { - return 'CUE dosyası ayrıştırılıyor... ($current/$total)'; + return 'Splitting CUE sheet... ($current/$total)'; } @override String cueSplitSuccess(int count) { - return 'Dosya başarıyla $count şarkıya bölündü'; + return 'Split into $count tracks successfully'; } @override - String get cueSplitFailed => 'CUE bölme işlemi başarısız'; + String get cueSplitFailed => 'CUE split failed'; @override - String get cueSplitNoAudioFile => - 'Bu CUE ile eşleşen bir ses dosyası bulunamadı'; + String get cueSplitNoAudioFile => 'Audio file not found for this CUE sheet'; @override - String get cueSplitButton => 'Şarkılara Böl'; + String get cueSplitButton => 'Split into Tracks'; @override - String get actionCreate => 'Oluştur'; + String get actionCreate => 'Create'; @override - String get collectionFoldersTitle => 'Klasörlerim'; + String get collectionFoldersTitle => 'My folders'; @override - String get collectionWishlist => 'İstek Listesi'; + String get collectionWishlist => 'Wishlist'; @override - String get collectionLoved => 'Favoriler'; + String get collectionLoved => 'Loved'; @override - String get collectionPlaylists => 'Çalma Listeleri'; + String get collectionPlaylists => 'Playlists'; @override - String get collectionPlaylist => 'Çalma Listesi'; + String get collectionPlaylist => 'Playlist'; @override - String get collectionAddToPlaylist => 'Çalma listesine ekle'; + String get collectionAddToPlaylist => 'Add to playlist'; @override - String get collectionCreatePlaylist => 'Yeni çalma listesi oluştur'; + String get collectionCreatePlaylist => 'Create playlist'; @override - String get collectionNoPlaylistsYet => 'Henüz listeniz yok'; + String get collectionNoPlaylistsYet => 'No playlists yet'; @override String get collectionNoPlaylistsSubtitle => - 'Müziklerinizi kategorize etmek için bir çalma listesi oluşturun'; + 'Create a playlist to start categorizing tracks'; @override String collectionPlaylistTracks(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: '$count şarkı', - one: '1 şarkı', + other: '$count tracks', + one: '1 track', ); return '$_temp0'; } @override String collectionAddedToPlaylist(String playlistName) { - return '\"$playlistName\" listesine eklendi'; + return 'Added to \"$playlistName\"'; } @override String collectionAlreadyInPlaylist(String playlistName) { - return 'Zaten \"$playlistName\" listesinde var'; + return 'Already in \"$playlistName\"'; } @override - String get collectionPlaylistCreated => 'Çalma listesi oluşturuldu'; + String get collectionPlaylistCreated => 'Playlist created'; @override - String get collectionPlaylistNameHint => 'Çalma listesi adı'; + String get collectionPlaylistNameHint => 'Playlist name'; @override - String get collectionPlaylistNameRequired => - 'Lütfen liste için bir isim girin'; + String get collectionPlaylistNameRequired => 'Playlist name is required'; @override - String get collectionRenamePlaylist => 'Yeniden adlandır'; + String get collectionRenamePlaylist => 'Rename playlist'; @override - String get collectionDeletePlaylist => 'Listeyi sil'; + String get collectionDeletePlaylist => 'Delete playlist'; @override String collectionDeletePlaylistMessage(String playlistName) { - return '\"$playlistName\" listesini ve içindeki tüm şarkıları silmek istiyor musunuz?'; + return 'Delete \"$playlistName\" and all tracks inside it?'; } @override - String get collectionPlaylistDeleted => 'Çalma listesi silindi'; + String get collectionPlaylistDeleted => 'Playlist deleted'; @override - String get collectionPlaylistRenamed => 'Çalma listesi adı değiştirildi'; + String get collectionPlaylistRenamed => 'Playlist renamed'; @override - String get collectionWishlistEmptyTitle => 'İstek Listeniz boş'; + String get collectionWishlistEmptyTitle => 'Wishlist is empty'; @override String get collectionWishlistEmptySubtitle => - 'Daha sonra indirmek istediğiniz şarkıların yanındaki (+) simgesine dokunun'; + 'Tap + on tracks to save what you want to download later'; @override - String get collectionLovedEmptyTitle => 'Favori klasörünüz boş'; + String get collectionLovedEmptyTitle => 'Loved folder is empty'; @override String get collectionLovedEmptySubtitle => - 'Sevdiğiniz şarkıları burada toplamak için kalp ikonuna dokunun'; + 'Tap love on tracks to keep your favorites'; @override - String get collectionPlaylistEmptyTitle => 'Bu çalma listesi boş'; + String get collectionPlaylistEmptyTitle => 'Playlist is empty'; @override String get collectionPlaylistEmptySubtitle => - 'Buraya eklemek için istediğiniz şarkının üzerindeki (+) butonuna basılı tutun'; + 'Long-press + on any track to add it here'; @override - String get collectionRemoveFromPlaylist => 'Çalma listesinden çıkar'; + String get collectionRemoveFromPlaylist => 'Remove from playlist'; @override - String get collectionRemoveFromFolder => 'Klasörden çıkar'; + String get collectionRemoveFromFolder => 'Remove from folder'; @override String collectionRemoved(String trackName) { - return '\"$trackName\" listeden çıkarıldı'; + return '\"$trackName\" removed'; } @override String collectionAddedToLoved(String trackName) { - return '\"$trackName\" Favoriler klasörüne eklendi'; + return '\"$trackName\" added to Loved'; } @override String collectionRemovedFromLoved(String trackName) { - return '\"$trackName\" Favorilerinizden çıkarıldı'; + return '\"$trackName\" removed from Loved'; } @override String collectionAddedToWishlist(String trackName) { - return '\"$trackName\" İstek Listenize eklendi'; + return '\"$trackName\" added to Wishlist'; } @override String collectionRemovedFromWishlist(String trackName) { - return '\"$trackName\" İstek Listenizden çıkarıldı'; + return '\"$trackName\" removed from Wishlist'; } @override - String get trackOptionAddToLoved => 'Favorilere Ekle'; + String get trackOptionAddToLoved => 'Add to Loved'; @override - String get trackOptionRemoveFromLoved => 'Favorilerden Çıkar'; + String get trackOptionRemoveFromLoved => 'Remove from Loved'; @override - String get trackOptionAddToWishlist => 'İstek Listesine Ekle'; + String get trackOptionAddToWishlist => 'Add to Wishlist'; @override - String get trackOptionRemoveFromWishlist => 'İstek Listesinden Çıkar'; + String get trackOptionRemoveFromWishlist => 'Remove from Wishlist'; @override - String get collectionPlaylistChangeCover => 'Kapak resmini değiştir'; + String get collectionPlaylistChangeCover => 'Change cover image'; @override - String get collectionPlaylistRemoveCover => 'Kapak resmini kaldır'; + String get collectionPlaylistRemoveCover => 'Remove cover image'; @override String selectionShareCount(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'şarkıyı', - one: 'şarkıyı', + other: 'tracks', + one: 'track', ); - return '$count $_temp0 paylaş'; + return 'Share $count $_temp0'; } @override - String get selectionShareNoFiles => 'Paylaşılabilir bir dosya bulunamadı'; + String get selectionShareNoFiles => 'No shareable files found'; @override String selectionConvertCount(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'şarkıyı', - one: 'şarkıyı', + other: 'tracks', + one: 'track', ); - return '$count $_temp0 dönüştür'; + return 'Convert $count $_temp0'; } @override - String get selectionConvertNoConvertible => - 'Dönüştürülebilir formatta bir şarkı seçilmedi'; + String get selectionConvertNoConvertible => 'No convertible tracks selected'; @override - String get selectionBatchConvertConfirmTitle => 'Toplu Dönüştürme'; + String get selectionBatchConvertConfirmTitle => 'Batch Convert'; @override String selectionBatchConvertConfirmMessage( @@ -2727,10 +2704,10 @@ class AppLocalizationsTr extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'şarkıyı', - one: 'şarkıyı', + other: 'tracks', + one: 'track', ); - return '$count $_temp0 $format formatına ($bitrate) dönüştürmek istiyor musunuz?\n\nDönüşüm işlemi bittikten sonra orijinal dosyalar tamamen silinecektir.'; + return 'Convert $count $_temp0 to $format at $bitrate?\n\nOriginal files will be deleted after conversion.'; } @override @@ -2738,345 +2715,340 @@ class AppLocalizationsTr extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'şarkıyı', - one: 'şarkıyı', + other: 'tracks', + one: 'track', ); - return '$count $_temp0 $format formatına dönüştürmek istiyor musunuz? (Kayıpsız işlem — kalite kaybı olmaz)\n\nDönüşüm işlemi bittikten sonra orijinal dosyalar tamamen silinecektir.'; + return 'Convert $count $_temp0 to $format? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.'; } @override String selectionBatchConvertProgress(int current, int total) { - return 'Dönüştürülüyor: $current / $total...'; + return 'Converting $current of $total...'; } @override String selectionBatchConvertSuccess(int success, int total, String format) { - return '$total şarkıdan $success tanesi $format formatına dönüştürüldü'; + return 'Converted $success of $total tracks to $format'; } @override String downloadedAlbumDownloadedCount(int count) { - return '$count tanesi indirildi'; + return '$count downloaded'; } @override String get downloadUseAlbumArtistForFoldersAlbumSubtitle => - 'Sanatçı klasörleri için Albüm Sanatçısı adı kullanılır'; + 'Artist folders use Album Artist when available'; @override String get downloadUseAlbumArtistForFoldersTrackSubtitle => - 'Sanatçı klasörleri için sadece Şarkı Sanatçısı adı kullanılır'; + 'Artist folders use Track Artist only'; @override - String get lyricsProvidersTitle => 'Şarkı Sözü Sağlayıcıları'; + String get lyricsProvidersTitle => 'Lyrics Providers'; @override String get lyricsProvidersDescription => - 'Şarkı sözü kaynaklarını açıp kapatın veya sıralamalarını değiştirin. Uygulama sözleri bulana kadar sağlayıcıları yukarıdan aşağıya doğru sırayla dener.'; + 'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.'; @override String get lyricsProvidersInfoText => - 'Mağazadan yüklediğiniz eklentiler her zaman varsayılan yerleşik sağlayıcılardan önce çalışır. En az bir sağlayıcı her zaman açık kalmalıdır.'; + 'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.'; @override String lyricsProvidersEnabledSection(int count) { - return 'Açık ($count)'; + return 'Enabled ($count)'; } @override String lyricsProvidersDisabledSection(int count) { - return 'Kapalı ($count)'; + return 'Disabled ($count)'; } @override String get lyricsProvidersAtLeastOne => - 'En az bir sağlayıcı her zaman açık kalmalıdır'; + 'At least one provider must remain enabled'; @override - String get lyricsProvidersSaved => - 'Şarkı sözü sağlayıcılarının sıralaması kaydedildi'; + String get lyricsProvidersSaved => 'Lyrics provider priority saved'; @override String get lyricsProvidersDiscardContent => - 'Kaydedilmemiş değişiklikleriniz iptal edilecek.'; + 'You have unsaved changes that will be lost.'; @override - String get lyricsProviderLrclibDesc => - 'Açık kaynaklı, senkronize şarkı sözü veritabanı'; + String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database'; @override String get lyricsProviderNeteaseDesc => - 'NetEase Cloud Music (Özellikle Asya müzikleri için ideal)'; + 'NetEase Cloud Music (good for Asian songs)'; @override String get lyricsProviderMusixmatchDesc => - 'En geniş şarkı sözü arşivi (Çok dilli)'; + 'Largest lyrics database (multi-language)'; @override String get lyricsProviderAppleMusicDesc => - 'Kelime kelime akan senkronize sözler (Proxy üzerinden)'; + 'Word-by-word synced lyrics (via proxy)'; @override String get lyricsProviderQqMusicDesc => - 'QQ Music (Özellikle Çince şarkılar için, Proxy üzerinden)'; + 'QQ Music (good for Chinese songs, via proxy)'; @override - String get lyricsProviderExtensionDesc => 'Eklenti ile sağlanan kaynak'; + String get lyricsProviderExtensionDesc => 'Extension provider'; @override - String get safMigrationTitle => 'Depolama Sistem Güncellemesi'; + String get safMigrationTitle => 'Storage Update Required'; @override String get safMigrationMessage1 => - 'SpotiFLAC artık indirme işlemleri için Android\'in yeni Depolama Erişim Çerçevesi\'ni (SAF) kullanıyor. Bu sayede Android 10 ve üzeri sürümlerdeki \"izin reddedildi\" hataları ortadan kalkıyor.'; + 'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.'; @override String get safMigrationMessage2 => - 'Yeni depolama sistemine geçiş yapmak için lütfen indirme klasörünüzü tekrar seçin.'; + 'Please select your download folder again to switch to the new storage system.'; @override - String get safMigrationSuccess => - 'İndirme klasörü başarıyla yeni (SAF) moda geçirildi'; + String get safMigrationSuccess => 'Download folder updated to SAF mode'; @override - String get settingsDonate => 'Bağış Yap'; + String get settingsDonate => 'Donate'; @override - String get settingsDonateSubtitle => - 'SpotiFLAC-Mobile gelişimine destek olun'; + String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development'; @override - String get tooltipLoveAll => 'Tümünü Favorilere Ekle'; + String get tooltipLoveAll => 'Love All'; @override - String get tooltipAddToPlaylist => 'Çalma Listesine Ekle'; + String get tooltipAddToPlaylist => 'Add to Playlist'; @override String snackbarRemovedTracksFromLoved(int count) { - return '$count şarkı Favoriler\'den çıkarıldı'; + return 'Removed $count tracks from Loved'; } @override String snackbarAddedTracksToLoved(int count) { - return '$count şarkı Favoriler\'e eklendi'; + return 'Added $count tracks to Loved'; } @override - String get dialogDownloadAllTitle => 'Tümünü İndir'; + String get dialogDownloadAllTitle => 'Download All'; @override String dialogDownloadAllMessage(int count) { - return 'Bu listedeki $count şarkı indirilsin mi?'; + return 'Download $count tracks?'; } @override - String get homeSkipAlreadyDownloaded => 'Daha önce inmiş olan şarkıları atla'; + String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs'; @override - String get homeGoToAlbum => 'Albüme Git'; + String get homeGoToAlbum => 'Go to Album'; @override - String get homeAlbumInfoUnavailable => 'Albüm bilgisine ulaşılamıyor'; + String get homeAlbumInfoUnavailable => 'Album info not available'; @override - String get snackbarLoadingCueSheet => 'CUE dosyası yükleniyor...'; + String get snackbarLoadingCueSheet => 'Loading CUE sheet...'; @override - String get snackbarMetadataSaved => - 'Şarkı verileri dosyaya başarıyla kaydedildi'; + String get snackbarMetadataSaved => 'Metadata saved successfully'; @override - String get snackbarFailedToEmbedLyrics => 'Şarkı sözleri dosyaya eklenemedi'; + String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics'; @override - String get snackbarFailedToWriteStorage => - 'Değişiklikler asıl dosyaya yazılamadı'; + String get snackbarFailedToWriteStorage => 'Failed to write back to storage'; @override String snackbarError(String error) { - return 'Hata: $error'; + return 'Error: $error'; } @override - String get snackbarNoActionDefined => - 'Bu buton için henüz bir işlev tanımlanmamış'; + String get snackbarNoActionDefined => 'No action defined for this button'; @override - String get noTracksFoundForAlbum => 'Bu albümün içinde hiç şarkı bulunamadı'; + String get noTracksFoundForAlbum => 'No tracks found for this album'; @override String get downloadLocationSubtitle => - 'İndirdiğiniz dosyaların cihazınızda nasıl tutulacağını seçin.'; + 'Choose storage mode for downloaded files.'; @override - String get storageModeAppFolder => 'Uygulama Klasörü'; + String get storageModeAppFolder => 'App folder (non-SAF)'; @override - String get storageModeAppFolderSubtitle => - 'Telefonunuzdaki varsayılan Müzik klasörünü kullanır'; + String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path'; @override - String get storageModeSaf => 'SAF ile Özel Klasör (Önerilen)'; + String get storageModeSaf => 'SAF folder'; @override String get storageModeSafSubtitle => - 'Android dosya seçicisi ile cihazınızdan dilediğiniz klasörü seçin'; + 'Pick folder via Android Storage Access Framework'; @override String get downloadFilenameDescription => - 'Şarkıların cihazınızda hangi dosya adıyla kaydedileceğini özelleştirin.'; + 'Customize how your files are named.'; @override - String get downloadFilenameInsertTag => 'Eklemek için dokunun:'; + String get downloadFilenameInsertTag => 'Tap to insert tag:'; @override - String get downloadSeparateSinglesEnabled => - 'Sanatçı klasörünün içinde Single\'ları ayrı bir klasöre ayırır'; + String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders'; @override - String get downloadSeparateSinglesDisabled => - 'Single\'lar ile albümler aynı yerde durur'; + String get downloadSeparateSinglesDisabled => 'All files in same structure'; @override - String get downloadArtistNameFilters => 'Sanatçı Adı Filtreleri'; + String get downloadArtistNameFilters => 'Artist Name Filters'; @override String get downloadCreatePlaylistSourceFolder => - 'Çalma Listeleri İçin Ana Klasör Oluştur'; + 'Create playlist source folder'; @override String get downloadCreatePlaylistSourceFolderEnabled => - 'Çalma listesi indirildiğinde en dışa \'Çalma Listesi Adı\' isimli bir klasör oluşturur ve içini normal düzeninize göre dizer.'; + 'Playlist downloads use Playlist/ plus your normal folder structure.'; @override String get downloadCreatePlaylistSourceFolderDisabled => - 'Çalma listesindeki şarkılar da diğerleri gibi doğrudan albüm ve sanatçı klasörlerinize atılır.'; + 'Playlist downloads use the normal folder structure only.'; @override String get downloadCreatePlaylistSourceFolderRedundant => - 'Klasör Düzeni zaten \'Çalma Listesine Göre\' ayarlı olduğu için bu seçenek pasiftir.'; + 'By Playlist already places downloads inside a playlist folder.'; @override - String get downloadSongLinkRegion => 'SongLink Arama Bölgesi'; + String get downloadSongLinkRegion => 'SongLink Region'; @override - String get downloadNetworkCompatibilityMode => 'Ağ Uyumluluk Modu'; + String get downloadNetworkCompatibilityMode => 'Network compatibility mode'; @override String get downloadNetworkCompatibilityModeEnabled => - 'Açık: Bağlantı HTTP ile denenir ve geçersiz sertifikalar kabul edilir (Güvensiz ama çözümleyici)'; + 'Enabled: try HTTP + accept invalid TLS certificates (unsafe)'; @override String get downloadNetworkCompatibilityModeDisabled => - 'Kapalı: Katı HTTPS kuralları uygulanır (Önerilen)'; + 'Off: strict HTTPS certificate validation (recommended)'; @override String get downloadSelectServiceToEnable => - 'Seçenekleri açmak için yerleşik bir sağlayıcı seçin'; + 'Select a built-in service to enable'; @override String get downloadSelectTidalQobuz => - 'Kaliteyi ayarlamak için lütfen yukarıdan Tidal veya Qobuz seçin'; + 'Select Tidal or Qobuz above to configure quality'; @override String get downloadEmbedLyricsDisabled => - 'Şarkı Verilerini Dosyaya Gömme ayarı kapalıyken kullanılamaz'; + 'Disabled while Embed Metadata is turned off'; @override String get downloadNeteaseIncludeTranslation => - 'Netease: Çevirileri Dahil Et'; + 'Netease: Include Translation'; @override String get downloadNeteaseIncludeTranslationEnabled => - 'Varsa, orijinal sözlere çevirilerini ekler'; + 'Append translated lyrics when available'; @override String get downloadNeteaseIncludeTranslationDisabled => - 'Sadece şarkının kendi sözleri kullanılır'; + 'Use original lyrics only'; @override String get downloadNeteaseIncludeRomanization => - 'Netease: Okunuşları (Romanizasyon) Dahil Et'; + 'Netease: Include Romanization'; @override String get downloadNeteaseIncludeRomanizationEnabled => - 'Varsa, Asya şarkıları için Latin alfabesi okunuşlarını ekler'; + 'Append romanized lyrics when available'; @override - String get downloadNeteaseIncludeRomanizationDisabled => 'Kapalı'; + String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled'; @override - String get downloadAppleQqMultiPerson => - 'Apple/QQ: Çoklu Sanatçı Düzeni (Kelime kelime akan sözler)'; + String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word'; @override String get downloadAppleQqMultiPersonEnabled => - 'Gelişmiş v1/v2 ve arka plan [bg:] etiketlerini açık tutar'; + 'Enable v1/v2 speaker and [bg:] tags'; @override String get downloadAppleQqMultiPersonDisabled => - 'Standart kelime kelime senkronizasyon kullanır'; + 'Simplified word-by-word formatting'; @override - String get downloadMusixmatchLanguage => 'Musixmatch Tercih Edilen Dil'; + String get downloadMusixmatchLanguage => 'Musixmatch Language'; @override - String get downloadMusixmatchLanguageAuto => 'Otomatik (Orijinal Dil)'; + String get downloadMusixmatchLanguageAuto => 'Auto (original)'; @override String get downloadFilterContributing => - 'Albüm Sanatçısı etiketinde konuk sanatçıları filtrele'; + 'Filter contributing artists in Album Artist'; @override String get downloadFilterContributingEnabled => - 'Albüm Sanatçısı verisinde sadece ana sanatçı ismi tutulur'; + 'Album Artist metadata uses primary artist only'; @override String get downloadFilterContributingDisabled => - 'Tüm sanatçı isimlerini olduğu gibi korur'; + 'Keep full Album Artist metadata value'; @override - String get downloadProvidersNoneEnabled => 'Hiçbir sağlayıcı açık değil'; + String get downloadProvidersNoneEnabled => 'None enabled'; @override - String get downloadMusixmatchLanguageCode => 'Dil Kodu'; + String get downloadMusixmatchLanguageCode => 'Language code'; @override - String get downloadMusixmatchLanguageHint => 'auto / tr / en / es'; + String get downloadMusixmatchLanguageHint => 'auto / en / es / ja'; @override String get downloadMusixmatchLanguageDesc => - 'Tercih ettiğiniz söz dilini belirleyin (örnek: tr, en, es). Otomatik seçim için boş bırakın.'; + 'Set preferred language code (example: en, es, ja). Leave empty for auto.'; @override - String get downloadMusixmatchAuto => 'Otomatik'; + String get downloadMusixmatchAuto => 'Auto'; @override - String get downloadNetworkAnySubtitle => 'Wi-Fi + Mobil Veri üzerinden indir'; + String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data'; @override String get downloadNetworkWifiOnlySubtitle => - 'Wi-Fi\'dan çıkarsanız indirmeler duraklatılır'; + 'Pause downloads on mobile data'; @override String get downloadSongLinkRegionDesc => - 'Şarkı aramalarında SongLink API\'ye iletilecek ülke kodunu belirler.'; + 'Used as userCountry for SongLink API lookup.'; @override - String get snackbarUnsupportedAudioFormat => 'Bu ses formatı desteklenmiyor'; + String get snackbarUnsupportedAudioFormat => 'Unsupported audio format'; @override - String get cacheRefresh => 'Yenile'; + String get cacheRefresh => 'Refresh'; @override String dialogDownloadPlaylistsMessage(int trackCount, int playlistCount) { String _temp0 = intl.Intl.pluralLogic( + trackCount, + locale: localeName, + other: 'tracks', + one: 'track', + ); + String _temp1 = intl.Intl.pluralLogic( playlistCount, locale: localeName, - other: 'listeden', - one: 'listeden', + other: 'playlists', + one: 'playlist', ); - return '$playlistCount $_temp0 toplam $trackCount şarkı indirilsin mi?'; + return 'Download $trackCount $_temp0 from $playlistCount $_temp1?'; } @override @@ -3084,123 +3056,122 @@ class AppLocalizationsTr extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'listeyi', - one: 'listeyi', + other: 'playlists', + one: 'playlist', ); - return 'Seçili $count $_temp0 indir'; + return 'Download $count $_temp0'; } @override - String get bulkDownloadSelectPlaylists => - 'İndirilecek çalma listelerini seçin'; + String get bulkDownloadSelectPlaylists => 'Select playlists to download'; @override String get snackbarSelectedPlaylistsEmpty => - 'Seçilen çalma listelerinde şarkı yok'; + 'Selected playlists have no tracks'; @override String playlistsCount(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: '$count çalma listesi', - one: '1 çalma listesi', + other: '$count playlists', + one: '1 playlist', ); return '$_temp0'; } @override - String get editMetadataAutoFill => 'İnternetten Otomatik Doldur'; + String get editMetadataAutoFill => 'Auto-fill from online'; @override String get editMetadataAutoFillDesc => - 'İnternetteki verilerle otomatik doldurulmasını istediğiniz alanları seçin'; + 'Select fields to fill automatically from online metadata'; @override - String get editMetadataAutoFillFetch => 'Bul ve Doldur'; + String get editMetadataAutoFillFetch => 'Fetch & Fill'; @override - String get editMetadataAutoFillSearching => 'İnternette eşleşme aranıyor...'; + String get editMetadataAutoFillSearching => 'Searching online...'; @override String get editMetadataAutoFillNoResults => - 'İnternette bu şarkıya uygun bir veri bulunamadı'; + 'No matching metadata found online'; @override String editMetadataAutoFillDone(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: 'alan', - one: 'alan', + other: 'fields', + one: 'field', ); - return 'Şarkı verilerinden $count $_temp0 internetten çekilerek dolduruldu'; + return 'Filled $count $_temp0 from online metadata'; } @override String get editMetadataAutoFillNoneSelected => - 'Lütfen otomatik doldurulacak en az bir alan seçin'; + 'Select at least one field to auto-fill'; @override - String get editMetadataFieldTitle => 'Şarkı Adı'; + String get editMetadataFieldTitle => 'Title'; @override - String get editMetadataFieldArtist => 'Sanatçı'; + String get editMetadataFieldArtist => 'Artist'; @override - String get editMetadataFieldAlbum => 'Albüm'; + String get editMetadataFieldAlbum => 'Album'; @override - String get editMetadataFieldAlbumArtist => 'Albüm Sanatçısı'; + String get editMetadataFieldAlbumArtist => 'Album Artist'; @override - String get editMetadataFieldDate => 'Tarih'; + String get editMetadataFieldDate => 'Date'; @override - String get editMetadataFieldTrackNum => 'Şarkı Sırası'; + String get editMetadataFieldTrackNum => 'Track #'; @override - String get editMetadataFieldDiscNum => 'Disk #'; + String get editMetadataFieldDiscNum => 'Disc #'; @override - String get editMetadataFieldGenre => 'Tür'; + String get editMetadataFieldGenre => 'Genre'; @override String get editMetadataFieldIsrc => 'ISRC'; @override - String get editMetadataFieldLabel => 'Plak Şirketi'; + String get editMetadataFieldLabel => 'Label'; @override - String get editMetadataFieldCopyright => 'Telif Hakkı'; + String get editMetadataFieldCopyright => 'Copyright'; @override - String get editMetadataFieldCover => 'Albüm Kapağı'; + String get editMetadataFieldCover => 'Cover Art'; @override - String get editMetadataSelectAll => 'Tümü'; + String get editMetadataSelectAll => 'All'; @override - String get editMetadataSelectEmpty => 'Sadece boşlar'; + String get editMetadataSelectEmpty => 'Empty only'; @override String queueDownloadingCount(int count) { - return 'Şu An İnenler ($count)'; + return 'Downloading ($count)'; } @override - String get queueDownloadedHeader => 'İnenler'; + String get queueDownloadedHeader => 'Downloaded'; @override - String get queueFilteringIndicator => 'Filtreleniyor...'; + String get queueFilteringIndicator => 'Filtering...'; @override String queueTrackCount(int count) { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: '$count şarkı', - one: '1 şarkı', + other: '$count tracks', + one: '1 track', ); return '$_temp0'; } @@ -3210,82 +3181,80 @@ class AppLocalizationsTr extends AppLocalizations { String _temp0 = intl.Intl.pluralLogic( count, locale: localeName, - other: '$count albüm', - one: '1 albüm', + other: '$count albums', + one: '1 album', ); return '$_temp0'; } @override - String get queueEmptyAlbums => 'İndirilmiş bir albüm yok'; + String get queueEmptyAlbums => 'No album downloads'; @override String get queueEmptyAlbumsSubtitle => - 'Bir albümden birden fazla şarkı indirdiğinizde burada görünecektir.'; + 'Download multiple tracks from an album to see them here'; @override - String get queueEmptySingles => 'İndirilmiş bir şarkı yok'; + String get queueEmptySingles => 'No single downloads'; @override String get queueEmptySinglesSubtitle => - 'Tek tek indirdiğiniz şarkılar burada görünecektir.'; + 'Single track downloads will appear here'; @override - String get queueEmptyHistory => 'İndirme geçmişi boş'; + String get queueEmptyHistory => 'No download history'; @override - String get queueEmptyHistorySubtitle => - 'İndirdiğiniz şarkılar başarıyla tamamlandığında burada görünecektir.'; + String get queueEmptyHistorySubtitle => 'Downloaded tracks will appear here'; @override - String get selectionAllPlaylistsSelected => 'Tüm listeler seçildi'; + String get selectionAllPlaylistsSelected => 'All playlists selected'; @override - String get selectionTapPlaylistsToSelect => 'Seçmek için listelere dokunun'; + String get selectionTapPlaylistsToSelect => 'Tap playlists to select'; @override - String get selectionSelectPlaylistsToDelete => - 'Silinecek çalma listelerini seçin'; + String get selectionSelectPlaylistsToDelete => 'Select playlists to delete'; @override - String get audioAnalysisTitle => 'Ses Kalitesi Analizi'; + String get audioAnalysisTitle => 'Audio Quality Analysis'; @override String get audioAnalysisDescription => - 'Kayıpsız kalite doğrulaması için spektrum analizi yapın'; + 'Verify lossless quality with spectrum analysis'; @override - String get audioAnalysisAnalyzing => 'Ses dosyası analiz ediliyor...'; + String get audioAnalysisAnalyzing => 'Analyzing audio...'; @override - String get audioAnalysisSampleRate => 'Örnekleme Hızı (Sample Rate)'; + String get audioAnalysisSampleRate => 'Sample Rate'; @override - String get audioAnalysisBitDepth => 'Bit Derinliği'; + String get audioAnalysisBitDepth => 'Bit Depth'; @override - String get audioAnalysisChannels => 'Kanal'; + String get audioAnalysisChannels => 'Channels'; @override - String get audioAnalysisDuration => 'Süre'; + String get audioAnalysisDuration => 'Duration'; @override - String get audioAnalysisNyquist => 'Nyquist Frekansı'; + String get audioAnalysisNyquist => 'Nyquist'; @override - String get audioAnalysisFileSize => 'Boyut'; + String get audioAnalysisFileSize => 'Size'; @override - String get audioAnalysisDynamicRange => 'Dinamik Aralık'; + String get audioAnalysisDynamicRange => 'Dynamic Range'; @override - String get audioAnalysisPeak => 'Tepe Değeri (Peak)'; + String get audioAnalysisPeak => 'Peak'; @override - String get audioAnalysisRms => 'Ortalama Değer (RMS)'; + String get audioAnalysisRms => 'RMS'; @override - String get audioAnalysisSamples => 'Toplam Örneklem (Samples)'; + String get audioAnalysisSamples => 'Samples'; @override String extensionsSearchWith(String providerName) { diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index f623054..6fbbdfc 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -3436,13 +3436,13 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get navSettings => '设置'; @override - String get navStore => '商店'; + String get navStore => 'Repo'; @override String get homeTitle => '主页'; @override - String get homeSubtitle => '粘贴 Spotify 链接或按名称搜索'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => '支持:歌曲、专辑、播放列表、艺人网址'; @@ -3489,6 +3489,13 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get downloadFilenameFormat => '文件名格式'; + @override + String get downloadSingleFilenameFormat => 'Single Filename Format'; + + @override + String get downloadSingleFilenameFormatDescription => + 'Filename pattern for singles and EPs. Uses the same tags as the album format.'; + @override String get downloadFolderOrganization => '文件夹结构'; @@ -3533,6 +3540,13 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { return '使用扩展:$extensionName'; } + @override + String get optionsDefaultSearchTab => 'Default Search Tab'; + + @override + String get optionsDefaultSearchTabSubtitle => + 'Choose which tab opens first for new search results.'; + @override String get optionsSwitchBack => '点击 Deezer 或 Spotify 即可从扩展程序切换回来'; @@ -3563,6 +3577,38 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get optionsMaxQualityCoverSubtitle => '下载最高分辨率封面'; + @override + String get optionsReplayGain => 'ReplayGain'; + + @override + String get optionsReplayGainSubtitleOn => + 'Scan loudness and embed ReplayGain tags (EBU R128)'; + + @override + String get optionsReplayGainSubtitleOff => + 'Disabled: no loudness normalization tags'; + + @override + String get optionsArtistTagMode => 'Artist Tag Mode'; + + @override + String get optionsArtistTagModeDescription => + 'Choose how multiple artists are written into embedded tags.'; + + @override + String get optionsArtistTagModeJoined => 'Single joined value'; + + @override + String get optionsArtistTagModeJoinedSubtitle => + 'Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.'; + + @override + String get optionsArtistTagModeSplitVorbis => 'Split tags for FLAC/Opus'; + + @override + String get optionsArtistTagModeSplitVorbisSubtitle => + 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; + @override String get optionsConcurrentDownloads => '并行下载数'; @@ -3578,10 +3624,10 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get optionsConcurrentWarning => '并行下载可能会触发速率限制'; @override - String get optionsExtensionStore => '扩展商店'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => '在导航中显示商店标签'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => '检查更新'; @@ -3655,7 +3701,7 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get extensionsUninstall => '卸载'; @override - String get storeTitle => '扩展商店'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => '搜索扩展……'; @@ -3931,6 +3977,9 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get dialogImport => 'Import'; + @override + String get dialogDownload => 'Download'; + @override String get dialogDiscard => 'Discard'; @@ -4161,6 +4210,36 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get searchPlaylists => 'Playlists'; + @override + String get searchSortTitle => 'Sort Results'; + + @override + String get searchSortDefault => 'Default'; + + @override + String get searchSortTitleAZ => 'Title (A-Z)'; + + @override + String get searchSortTitleZA => 'Title (Z-A)'; + + @override + String get searchSortArtistAZ => 'Artist (A-Z)'; + + @override + String get searchSortArtistZA => 'Artist (Z-A)'; + + @override + String get searchSortDurationShort => 'Duration (Shortest)'; + + @override + String get searchSortDurationLong => 'Duration (Longest)'; + + @override + String get searchSortDateOldest => 'Release Date (Oldest)'; + + @override + String get searchSortDateNewest => 'Release Date (Newest)'; + @override String get tooltipPlay => 'Play'; @@ -4259,6 +4338,17 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get providerPriorityInfo => 'If a track is not available on the first provider, the app will automatically try the next one.'; + @override + String get providerPriorityFallbackExtensionsTitle => 'Extension Fallback'; + + @override + String get providerPriorityFallbackExtensionsDescription => + 'Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.'; + + @override + String get providerPriorityFallbackExtensionsHint => + 'Only enabled extensions with download-provider capability are listed here.'; + @override String get providerBuiltIn => 'Built-in'; @@ -4533,6 +4623,12 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get trackLyricsNotAvailable => 'Lyrics not available for this track'; + @override + String get trackLyricsNotInFile => 'No lyrics found in this file'; + + @override + String get trackFetchOnlineLyrics => 'Fetch from Online'; + @override String get trackLyricsTimeout => 'Request timed out. Try again later.'; @@ -4601,7 +4697,48 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get storeClearFilters => 'Clear filters'; @override - String get extensionDefaultProvider => 'Default (Deezer/Spotify)'; + String get storeAddRepoTitle => 'Add Extension Repository'; + + @override + String get storeAddRepoDescription => + 'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.'; + + @override + String get storeRepoUrlLabel => 'Repository URL'; + + @override + String get storeRepoUrlHint => 'https://github.com/user/repo'; + + @override + String get storeRepoUrlHelper => + 'e.g. https://github.com/user/extensions-repo'; + + @override + String get storeAddRepoButton => 'Add Repository'; + + @override + String get storeChangeRepoTooltip => 'Change repository'; + + @override + String get storeRepoDialogTitle => 'Extension Repository'; + + @override + String get storeRepoDialogCurrent => 'Current repository:'; + + @override + String get storeNewRepoUrlLabel => 'New Repository URL'; + + @override + String get storeLoadError => 'Failed to load repository'; + + @override + String get storeEmptyNoExtensions => 'No extensions available'; + + @override + String get storeEmptyNoResults => 'No extensions found'; + + @override + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Use built-in search'; @@ -4701,6 +4838,13 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get extensionsDownloadPrioritySubtitle => 'Set download service order'; + @override + String get extensionsFallbackTitle => 'Fallback Extensions'; + + @override + String get extensionsFallbackSubtitle => + 'Choose which installed download extensions can be used as fallback'; + @override String get extensionsNoDownloadProvider => 'No extensions with download provider'; @@ -4750,6 +4894,38 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; + @override + String get downloadLossy320 => 'Lossy 320kbps'; + + @override + String get downloadLossyFormat => 'Lossy Format'; + + @override + String get downloadLossy320Format => 'Lossy 320kbps Format'; + + @override + String get downloadLossy320FormatDesc => + 'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.'; + + @override + String get downloadLossyMp3 => 'MP3 320kbps'; + + @override + String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track'; + + @override + String get downloadLossyOpus256 => 'Opus 256kbps'; + + @override + String get downloadLossyOpus256Subtitle => + 'Best quality Opus, ~8MB per track'; + + @override + String get downloadLossyOpus128 => 'Opus 128kbps'; + + @override + String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track'; + @override String get qualityNote => 'Actual quality depends on track availability from the service'; @@ -4851,6 +5027,13 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get albumFolderArtistAlbumSinglesSubtitle => 'Artist/Album/ and Artist/Singles/'; + @override + String get albumFolderArtistAlbumFlat => 'Artist / Album (Singles flat)'; + + @override + String get albumFolderArtistAlbumFlatSubtitle => + 'Artist/Album/ and Artist/song.flac'; + @override String get downloadedAlbumDeleteSelected => 'Delete Selected'; @@ -5046,6 +5229,25 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get libraryShowDuplicateIndicatorSubtitle => 'Show when searching for existing tracks'; + @override + String get libraryAutoScan => 'Auto Scan'; + + @override + String get libraryAutoScanSubtitle => + 'Automatically scan your library for new files'; + + @override + String get libraryAutoScanOff => 'Off'; + + @override + String get libraryAutoScanOnOpen => 'Every app open'; + + @override + String get libraryAutoScanDaily => 'Daily'; + + @override + String get libraryAutoScanWeekly => 'Weekly'; + @override String get libraryActions => 'Actions'; @@ -5096,6 +5298,17 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { return '$_temp0'; } + @override + String libraryFilesUnit(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'files', + one: 'file', + ); + return '$_temp0'; + } + @override String libraryLastScanned(String time) { return 'Last scanned: $time'; @@ -5107,6 +5320,9 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get libraryScanning => 'Scanning...'; + @override + String get libraryScanFinalizing => 'Finalizing library...'; + @override String libraryScanProgress(String progress, int total) { return '$progress% of $total files'; @@ -5175,6 +5391,24 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get libraryFilterFormat => 'Format'; + @override + String get libraryFilterMetadata => 'Metadata'; + + @override + String get libraryFilterMetadataComplete => 'Complete metadata'; + + @override + String get libraryFilterMetadataMissingAny => 'Missing any metadata'; + + @override + String get libraryFilterMetadataMissingYear => 'Missing year'; + + @override + String get libraryFilterMetadataMissingGenre => 'Missing genre'; + + @override + String get libraryFilterMetadataMissingAlbumArtist => 'Missing album artist'; + @override String get libraryFilterSort => 'Sort'; @@ -5184,6 +5418,18 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get libraryFilterSortOldest => 'Oldest'; + @override + String get libraryFilterSortAlbumAsc => 'Album (A-Z)'; + + @override + String get libraryFilterSortAlbumDesc => 'Album (Z-A)'; + + @override + String get libraryFilterSortGenreAsc => 'Genre (A-Z)'; + + @override + String get libraryFilterSortGenreDesc => 'Genre (Z-A)'; + @override String get timeJustNow => 'Just now'; @@ -5270,7 +5516,7 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -5468,6 +5714,30 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get trackReEnrichOnlineSubtitle => 'Search metadata online and embed into file'; + @override + String get trackReEnrichFieldsTitle => 'Fields to update'; + + @override + String get trackReEnrichFieldCover => 'Cover Art'; + + @override + String get trackReEnrichFieldLyrics => 'Lyrics'; + + @override + String get trackReEnrichFieldBasicTags => 'Album, Album Artist'; + + @override + String get trackReEnrichFieldTrackInfo => 'Track & Disc Number'; + + @override + String get trackReEnrichFieldReleaseInfo => 'Date & ISRC'; + + @override + String get trackReEnrichFieldExtra => 'Genre, Label, Copyright'; + + @override + String get trackReEnrichSelectAll => 'Select All'; + @override String get trackEditMetadata => 'Edit Metadata'; @@ -5496,6 +5766,28 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get trackReEnrichFfmpegFailed => 'FFmpeg metadata embed failed'; + @override + String get queueFlacAction => 'Queue FLAC'; + + @override + String queueFlacConfirmMessage(int count) { + return 'Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n$count selected'; + } + + @override + String queueFlacFindingProgress(int current, int total) { + return 'Finding FLAC matches... ($current/$total)'; + } + + @override + String get queueFlacNoReliableMatches => + 'No reliable online matches found for the selection'; + + @override + String queueFlacQueuedWithSkipped(int addedCount, int skippedCount) { + return 'Added $addedCount tracks to queue, skipped $skippedCount'; + } + @override String trackSaveFailed(String error) { return 'Failed: $error'; @@ -5505,7 +5797,8 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get trackConvertFormat => 'Convert Format'; @override - String get trackConvertFormatSubtitle => 'Convert to MP3 or Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; @@ -5528,6 +5821,18 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { return 'Convert from $sourceFormat to $targetFormat at $bitrate?\n\nThe original file will be deleted after conversion.'; } + @override + String trackConvertConfirmMessageLossless( + String sourceFormat, + String targetFormat, + ) { + return 'Convert from $sourceFormat to $targetFormat? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.'; + } + + @override + String get trackConvertLosslessHint => + 'Lossless conversion — no quality loss'; + @override String get trackConvertConverting => 'Converting audio...'; @@ -5781,6 +6086,17 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { return 'Convert $count $_temp0 to $format at $bitrate?\n\nOriginal files will be deleted after conversion.'; } + @override + String selectionBatchConvertConfirmMessageLossless(int count, String format) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Convert $count $_temp0 to $format? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.'; + } + @override String selectionBatchConvertProgress(int current, int total) { return 'Converting $current of $total...'; @@ -5803,6 +6119,706 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { @override String get downloadUseAlbumArtistForFoldersTrackSubtitle => 'Artist folders use Track Artist only'; + + @override + String get lyricsProvidersTitle => 'Lyrics Providers'; + + @override + String get lyricsProvidersDescription => + 'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.'; + + @override + String get lyricsProvidersInfoText => + 'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.'; + + @override + String lyricsProvidersEnabledSection(int count) { + return 'Enabled ($count)'; + } + + @override + String lyricsProvidersDisabledSection(int count) { + return 'Disabled ($count)'; + } + + @override + String get lyricsProvidersAtLeastOne => + 'At least one provider must remain enabled'; + + @override + String get lyricsProvidersSaved => 'Lyrics provider priority saved'; + + @override + String get lyricsProvidersDiscardContent => + 'You have unsaved changes that will be lost.'; + + @override + String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database'; + + @override + String get lyricsProviderNeteaseDesc => + 'NetEase Cloud Music (good for Asian songs)'; + + @override + String get lyricsProviderMusixmatchDesc => + 'Largest lyrics database (multi-language)'; + + @override + String get lyricsProviderAppleMusicDesc => + 'Word-by-word synced lyrics (via proxy)'; + + @override + String get lyricsProviderQqMusicDesc => + 'QQ Music (good for Chinese songs, via proxy)'; + + @override + String get lyricsProviderExtensionDesc => 'Extension provider'; + + @override + String get safMigrationTitle => 'Storage Update Required'; + + @override + String get safMigrationMessage1 => + 'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.'; + + @override + String get safMigrationMessage2 => + 'Please select your download folder again to switch to the new storage system.'; + + @override + String get safMigrationSuccess => 'Download folder updated to SAF mode'; + + @override + String get settingsDonate => 'Donate'; + + @override + String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development'; + + @override + String get tooltipLoveAll => 'Love All'; + + @override + String get tooltipAddToPlaylist => 'Add to Playlist'; + + @override + String snackbarRemovedTracksFromLoved(int count) { + return 'Removed $count tracks from Loved'; + } + + @override + String snackbarAddedTracksToLoved(int count) { + return 'Added $count tracks to Loved'; + } + + @override + String get dialogDownloadAllTitle => 'Download All'; + + @override + String dialogDownloadAllMessage(int count) { + return 'Download $count tracks?'; + } + + @override + String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs'; + + @override + String get homeGoToAlbum => 'Go to Album'; + + @override + String get homeAlbumInfoUnavailable => 'Album info not available'; + + @override + String get snackbarLoadingCueSheet => 'Loading CUE sheet...'; + + @override + String get snackbarMetadataSaved => 'Metadata saved successfully'; + + @override + String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics'; + + @override + String get snackbarFailedToWriteStorage => 'Failed to write back to storage'; + + @override + String snackbarError(String error) { + return 'Error: $error'; + } + + @override + String get snackbarNoActionDefined => 'No action defined for this button'; + + @override + String get noTracksFoundForAlbum => 'No tracks found for this album'; + + @override + String get downloadLocationSubtitle => + 'Choose storage mode for downloaded files.'; + + @override + String get storageModeAppFolder => 'App folder (non-SAF)'; + + @override + String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path'; + + @override + String get storageModeSaf => 'SAF folder'; + + @override + String get storageModeSafSubtitle => + 'Pick folder via Android Storage Access Framework'; + + @override + String get downloadFilenameDescription => + 'Customize how your files are named.'; + + @override + String get downloadFilenameInsertTag => 'Tap to insert tag:'; + + @override + String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders'; + + @override + String get downloadSeparateSinglesDisabled => 'All files in same structure'; + + @override + String get downloadArtistNameFilters => 'Artist Name Filters'; + + @override + String get downloadCreatePlaylistSourceFolder => + 'Create playlist source folder'; + + @override + String get downloadCreatePlaylistSourceFolderEnabled => + 'Playlist downloads use Playlist/ plus your normal folder structure.'; + + @override + String get downloadCreatePlaylistSourceFolderDisabled => + 'Playlist downloads use the normal folder structure only.'; + + @override + String get downloadCreatePlaylistSourceFolderRedundant => + 'By Playlist already places downloads inside a playlist folder.'; + + @override + String get downloadSongLinkRegion => 'SongLink Region'; + + @override + String get downloadNetworkCompatibilityMode => 'Network compatibility mode'; + + @override + String get downloadNetworkCompatibilityModeEnabled => + 'Enabled: try HTTP + accept invalid TLS certificates (unsafe)'; + + @override + String get downloadNetworkCompatibilityModeDisabled => + 'Off: strict HTTPS certificate validation (recommended)'; + + @override + String get downloadSelectServiceToEnable => + 'Select a built-in service to enable'; + + @override + String get downloadSelectTidalQobuz => + 'Select Tidal or Qobuz above to configure quality'; + + @override + String get downloadEmbedLyricsDisabled => + 'Disabled while Embed Metadata is turned off'; + + @override + String get downloadNeteaseIncludeTranslation => + 'Netease: Include Translation'; + + @override + String get downloadNeteaseIncludeTranslationEnabled => + 'Append translated lyrics when available'; + + @override + String get downloadNeteaseIncludeTranslationDisabled => + 'Use original lyrics only'; + + @override + String get downloadNeteaseIncludeRomanization => + 'Netease: Include Romanization'; + + @override + String get downloadNeteaseIncludeRomanizationEnabled => + 'Append romanized lyrics when available'; + + @override + String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled'; + + @override + String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word'; + + @override + String get downloadAppleQqMultiPersonEnabled => + 'Enable v1/v2 speaker and [bg:] tags'; + + @override + String get downloadAppleQqMultiPersonDisabled => + 'Simplified word-by-word formatting'; + + @override + String get downloadMusixmatchLanguage => 'Musixmatch Language'; + + @override + String get downloadMusixmatchLanguageAuto => 'Auto (original)'; + + @override + String get downloadFilterContributing => + 'Filter contributing artists in Album Artist'; + + @override + String get downloadFilterContributingEnabled => + 'Album Artist metadata uses primary artist only'; + + @override + String get downloadFilterContributingDisabled => + 'Keep full Album Artist metadata value'; + + @override + String get downloadProvidersNoneEnabled => 'None enabled'; + + @override + String get downloadMusixmatchLanguageCode => 'Language code'; + + @override + String get downloadMusixmatchLanguageHint => 'auto / en / es / ja'; + + @override + String get downloadMusixmatchLanguageDesc => + 'Set preferred language code (example: en, es, ja). Leave empty for auto.'; + + @override + String get downloadMusixmatchAuto => 'Auto'; + + @override + String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data'; + + @override + String get downloadNetworkWifiOnlySubtitle => + 'Pause downloads on mobile data'; + + @override + String get downloadSongLinkRegionDesc => + 'Used as userCountry for SongLink API lookup.'; + + @override + String get snackbarUnsupportedAudioFormat => 'Unsupported audio format'; + + @override + String get cacheRefresh => 'Refresh'; + + @override + String dialogDownloadPlaylistsMessage(int trackCount, int playlistCount) { + String _temp0 = intl.Intl.pluralLogic( + trackCount, + locale: localeName, + other: 'tracks', + one: 'track', + ); + String _temp1 = intl.Intl.pluralLogic( + playlistCount, + locale: localeName, + other: 'playlists', + one: 'playlist', + ); + return 'Download $trackCount $_temp0 from $playlistCount $_temp1?'; + } + + @override + String bulkDownloadPlaylistsButton(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'playlists', + one: 'playlist', + ); + return 'Download $count $_temp0'; + } + + @override + String get bulkDownloadSelectPlaylists => 'Select playlists to download'; + + @override + String get snackbarSelectedPlaylistsEmpty => + 'Selected playlists have no tracks'; + + @override + String playlistsCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count playlists', + one: '1 playlist', + ); + return '$_temp0'; + } + + @override + String get editMetadataAutoFill => 'Auto-fill from online'; + + @override + String get editMetadataAutoFillDesc => + 'Select fields to fill automatically from online metadata'; + + @override + String get editMetadataAutoFillFetch => 'Fetch & Fill'; + + @override + String get editMetadataAutoFillSearching => 'Searching online...'; + + @override + String get editMetadataAutoFillNoResults => + 'No matching metadata found online'; + + @override + String editMetadataAutoFillDone(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'fields', + one: 'field', + ); + return 'Filled $count $_temp0 from online metadata'; + } + + @override + String get editMetadataAutoFillNoneSelected => + 'Select at least one field to auto-fill'; + + @override + String get editMetadataFieldTitle => 'Title'; + + @override + String get editMetadataFieldArtist => 'Artist'; + + @override + String get editMetadataFieldAlbum => 'Album'; + + @override + String get editMetadataFieldAlbumArtist => 'Album Artist'; + + @override + String get editMetadataFieldDate => 'Date'; + + @override + String get editMetadataFieldTrackNum => 'Track #'; + + @override + String get editMetadataFieldDiscNum => 'Disc #'; + + @override + String get editMetadataFieldGenre => 'Genre'; + + @override + String get editMetadataFieldIsrc => 'ISRC'; + + @override + String get editMetadataFieldLabel => 'Label'; + + @override + String get editMetadataFieldCopyright => 'Copyright'; + + @override + String get editMetadataFieldCover => 'Cover Art'; + + @override + String get editMetadataSelectAll => 'All'; + + @override + String get editMetadataSelectEmpty => 'Empty only'; + + @override + String queueDownloadingCount(int count) { + return 'Downloading ($count)'; + } + + @override + String get queueDownloadedHeader => 'Downloaded'; + + @override + String get queueFilteringIndicator => 'Filtering...'; + + @override + String queueTrackCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count tracks', + one: '1 track', + ); + return '$_temp0'; + } + + @override + String queueAlbumCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count albums', + one: '1 album', + ); + return '$_temp0'; + } + + @override + String get queueEmptyAlbums => 'No album downloads'; + + @override + String get queueEmptyAlbumsSubtitle => + 'Download multiple tracks from an album to see them here'; + + @override + String get queueEmptySingles => 'No single downloads'; + + @override + String get queueEmptySinglesSubtitle => + 'Single track downloads will appear here'; + + @override + String get queueEmptyHistory => 'No download history'; + + @override + String get queueEmptyHistorySubtitle => 'Downloaded tracks will appear here'; + + @override + String get selectionAllPlaylistsSelected => 'All playlists selected'; + + @override + String get selectionTapPlaylistsToSelect => 'Tap playlists to select'; + + @override + String get selectionSelectPlaylistsToDelete => 'Select playlists to delete'; + + @override + String get audioAnalysisTitle => 'Audio Quality Analysis'; + + @override + String get audioAnalysisDescription => + 'Verify lossless quality with spectrum analysis'; + + @override + String get audioAnalysisAnalyzing => 'Analyzing audio...'; + + @override + String get audioAnalysisSampleRate => 'Sample Rate'; + + @override + String get audioAnalysisBitDepth => 'Bit Depth'; + + @override + String get audioAnalysisChannels => 'Channels'; + + @override + String get audioAnalysisDuration => 'Duration'; + + @override + String get audioAnalysisNyquist => 'Nyquist'; + + @override + String get audioAnalysisFileSize => 'Size'; + + @override + String get audioAnalysisDynamicRange => 'Dynamic Range'; + + @override + String get audioAnalysisPeak => 'Peak'; + + @override + String get audioAnalysisRms => 'RMS'; + + @override + String get audioAnalysisSamples => 'Samples'; + + @override + String extensionsSearchWith(String providerName) { + return 'Search with $providerName'; + } + + @override + String get extensionsHomeFeedProvider => 'Home Feed Provider'; + + @override + String get extensionsHomeFeedDescription => + 'Choose which extension provides the home feed on the main screen'; + + @override + String get extensionsHomeFeedAuto => 'Auto'; + + @override + String get extensionsHomeFeedAutoSubtitle => + 'Automatically select the best available'; + + @override + String extensionsHomeFeedUse(String extensionName) { + return 'Use $extensionName home feed'; + } + + @override + String get extensionsNoHomeFeedExtensions => 'No extensions with home feed'; + + @override + String get sortAlphaAsc => 'A-Z'; + + @override + String get sortAlphaDesc => 'Z-A'; + + @override + String get cancelDownloadTitle => 'Cancel download?'; + + @override + String cancelDownloadContent(String trackName) { + return 'This will cancel the active download for \"$trackName\".'; + } + + @override + String get cancelDownloadKeep => 'Keep'; + + @override + String get metadataSaveFailedFfmpeg => 'Failed to save metadata via FFmpeg'; + + @override + String get metadataSaveFailedStorage => + 'Failed to write metadata back to storage'; + + @override + String snackbarFolderPickerFailed(String error) { + return 'Failed to open folder picker: $error'; + } + + @override + String get errorLoadAlbum => 'Failed to load album'; + + @override + String get errorLoadPlaylist => 'Failed to load playlist'; + + @override + String get errorLoadArtist => 'Failed to load artist'; + + @override + String get notifChannelDownloadName => 'Download Progress'; + + @override + String get notifChannelDownloadDesc => 'Shows download progress for tracks'; + + @override + String get notifChannelLibraryScanName => 'Library Scan'; + + @override + String get notifChannelLibraryScanDesc => 'Shows local library scan progress'; + + @override + String notifDownloadingTrack(String trackName) { + return 'Downloading $trackName'; + } + + @override + String notifFinalizingTrack(String trackName) { + return 'Finalizing $trackName'; + } + + @override + String get notifEmbeddingMetadata => 'Embedding metadata...'; + + @override + String notifAlreadyInLibraryCount(int completed, int total) { + return 'Already in Library ($completed/$total)'; + } + + @override + String get notifAlreadyInLibrary => 'Already in Library'; + + @override + String notifDownloadCompleteCount(int completed, int total) { + return 'Download Complete ($completed/$total)'; + } + + @override + String get notifDownloadComplete => 'Download Complete'; + + @override + String notifDownloadsFinished(int completed, int failed) { + return 'Downloads Finished ($completed done, $failed failed)'; + } + + @override + String get notifAllDownloadsComplete => 'All Downloads Complete'; + + @override + String notifTracksDownloadedSuccess(int count) { + return '$count tracks downloaded successfully'; + } + + @override + String get notifScanningLibrary => 'Scanning local library'; + + @override + String notifLibraryScanProgressWithTotal( + int scanned, + int total, + int percentage, + ) { + return '$scanned/$total files • $percentage%'; + } + + @override + String notifLibraryScanProgressNoTotal(int scanned, int percentage) { + return '$scanned files scanned • $percentage%'; + } + + @override + String get notifLibraryScanComplete => 'Library scan complete'; + + @override + String notifLibraryScanCompleteBody(int count) { + return '$count tracks indexed'; + } + + @override + String notifLibraryScanExcluded(int count) { + return '$count excluded'; + } + + @override + String notifLibraryScanErrors(int count) { + return '$count errors'; + } + + @override + String get notifLibraryScanFailed => 'Library scan failed'; + + @override + String get notifLibraryScanCancelled => 'Library scan cancelled'; + + @override + String get notifLibraryScanStopped => 'Scan stopped before completion.'; + + @override + String notifDownloadingUpdate(String version) { + return 'Downloading SpotiFLAC v$version'; + } + + @override + String notifUpdateProgress(String received, String total, int percentage) { + return '$received / $total MB • $percentage%'; + } + + @override + String get notifUpdateReady => 'Update Ready'; + + @override + String notifUpdateReadyBody(String version) { + return 'SpotiFLAC v$version downloaded. Tap to install.'; + } + + @override + String get notifUpdateFailed => 'Update Failed'; + + @override + String get notifUpdateFailedBody => + 'Could not download update. Try again later.'; } /// The translations for Chinese, as used in Taiwan (`zh_TW`). @@ -5822,13 +6838,13 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get navSettings => 'Settings'; @override - String get navStore => 'Store'; + String get navStore => 'Repo'; @override String get homeTitle => 'Home'; @override - String get homeSubtitle => 'Paste a Spotify link or search by name'; + String get homeSubtitle => 'Paste a supported URL or search by name'; @override String get homeSupports => 'Supports: Track, Album, Playlist, Artist URLs'; @@ -5876,6 +6892,13 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get downloadFilenameFormat => 'Filename Format'; + @override + String get downloadSingleFilenameFormat => 'Single Filename Format'; + + @override + String get downloadSingleFilenameFormatDescription => + 'Filename pattern for singles and EPs. Uses the same tags as the album format.'; + @override String get downloadFolderOrganization => 'Folder Organization'; @@ -5921,6 +6944,13 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { return 'Using extension: $extensionName'; } + @override + String get optionsDefaultSearchTab => 'Default Search Tab'; + + @override + String get optionsDefaultSearchTabSubtitle => + 'Choose which tab opens first for new search results.'; + @override String get optionsSwitchBack => 'Tap Deezer or Spotify to switch back from extension'; @@ -5955,6 +6985,38 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get optionsMaxQualityCoverSubtitle => 'Download highest resolution cover art'; + @override + String get optionsReplayGain => 'ReplayGain'; + + @override + String get optionsReplayGainSubtitleOn => + 'Scan loudness and embed ReplayGain tags (EBU R128)'; + + @override + String get optionsReplayGainSubtitleOff => + 'Disabled: no loudness normalization tags'; + + @override + String get optionsArtistTagMode => 'Artist Tag Mode'; + + @override + String get optionsArtistTagModeDescription => + 'Choose how multiple artists are written into embedded tags.'; + + @override + String get optionsArtistTagModeJoined => 'Single joined value'; + + @override + String get optionsArtistTagModeJoinedSubtitle => + 'Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.'; + + @override + String get optionsArtistTagModeSplitVorbis => 'Split tags for FLAC/Opus'; + + @override + String get optionsArtistTagModeSplitVorbisSubtitle => + 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; + @override String get optionsConcurrentDownloads => 'Concurrent Downloads'; @@ -5971,10 +7033,10 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { 'Parallel downloads may trigger rate limiting'; @override - String get optionsExtensionStore => 'Extension Store'; + String get optionsExtensionStore => 'Extension Repo'; @override - String get optionsExtensionStoreSubtitle => 'Show Store tab in navigation'; + String get optionsExtensionStoreSubtitle => 'Show Repo tab in navigation'; @override String get optionsCheckUpdates => 'Check for Updates'; @@ -6051,7 +7113,7 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get extensionsUninstall => 'Uninstall'; @override - String get storeTitle => 'Extension Store'; + String get storeTitle => 'Extension Repo'; @override String get storeSearch => 'Search extensions...'; @@ -6329,6 +7391,9 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get dialogImport => 'Import'; + @override + String get dialogDownload => 'Download'; + @override String get dialogDiscard => 'Discard'; @@ -6560,6 +7625,36 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get searchPlaylists => 'Playlists'; + @override + String get searchSortTitle => 'Sort Results'; + + @override + String get searchSortDefault => 'Default'; + + @override + String get searchSortTitleAZ => 'Title (A-Z)'; + + @override + String get searchSortTitleZA => 'Title (Z-A)'; + + @override + String get searchSortArtistAZ => 'Artist (A-Z)'; + + @override + String get searchSortArtistZA => 'Artist (Z-A)'; + + @override + String get searchSortDurationShort => 'Duration (Shortest)'; + + @override + String get searchSortDurationLong => 'Duration (Longest)'; + + @override + String get searchSortDateOldest => 'Release Date (Oldest)'; + + @override + String get searchSortDateNewest => 'Release Date (Newest)'; + @override String get tooltipPlay => 'Play'; @@ -6658,6 +7753,17 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get providerPriorityInfo => 'If a track is not available on the first provider, the app will automatically try the next one.'; + @override + String get providerPriorityFallbackExtensionsTitle => 'Extension Fallback'; + + @override + String get providerPriorityFallbackExtensionsDescription => + 'Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.'; + + @override + String get providerPriorityFallbackExtensionsHint => + 'Only enabled extensions with download-provider capability are listed here.'; + @override String get providerBuiltIn => 'Built-in'; @@ -6932,6 +8038,12 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get trackLyricsNotAvailable => 'Lyrics not available for this track'; + @override + String get trackLyricsNotInFile => 'No lyrics found in this file'; + + @override + String get trackFetchOnlineLyrics => 'Fetch from Online'; + @override String get trackLyricsTimeout => 'Request timed out. Try again later.'; @@ -7000,7 +8112,48 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get storeClearFilters => 'Clear filters'; @override - String get extensionDefaultProvider => 'Default (Deezer/Spotify)'; + String get storeAddRepoTitle => 'Add Extension Repository'; + + @override + String get storeAddRepoDescription => + 'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.'; + + @override + String get storeRepoUrlLabel => 'Repository URL'; + + @override + String get storeRepoUrlHint => 'https://github.com/user/repo'; + + @override + String get storeRepoUrlHelper => + 'e.g. https://github.com/user/extensions-repo'; + + @override + String get storeAddRepoButton => 'Add Repository'; + + @override + String get storeChangeRepoTooltip => 'Change repository'; + + @override + String get storeRepoDialogTitle => 'Extension Repository'; + + @override + String get storeRepoDialogCurrent => 'Current repository:'; + + @override + String get storeNewRepoUrlLabel => 'New Repository URL'; + + @override + String get storeLoadError => 'Failed to load repository'; + + @override + String get storeEmptyNoExtensions => 'No extensions available'; + + @override + String get storeEmptyNoResults => 'No extensions found'; + + @override + String get extensionDefaultProvider => 'Default (Deezer)'; @override String get extensionDefaultProviderSubtitle => 'Use built-in search'; @@ -7100,6 +8253,13 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get extensionsDownloadPrioritySubtitle => 'Set download service order'; + @override + String get extensionsFallbackTitle => 'Fallback Extensions'; + + @override + String get extensionsFallbackSubtitle => + 'Choose which installed download extensions can be used as fallback'; + @override String get extensionsNoDownloadProvider => 'No extensions with download provider'; @@ -7149,6 +8309,38 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; + @override + String get downloadLossy320 => 'Lossy 320kbps'; + + @override + String get downloadLossyFormat => 'Lossy Format'; + + @override + String get downloadLossy320Format => 'Lossy 320kbps Format'; + + @override + String get downloadLossy320FormatDesc => + 'Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.'; + + @override + String get downloadLossyMp3 => 'MP3 320kbps'; + + @override + String get downloadLossyMp3Subtitle => 'Best compatibility, ~10MB per track'; + + @override + String get downloadLossyOpus256 => 'Opus 256kbps'; + + @override + String get downloadLossyOpus256Subtitle => + 'Best quality Opus, ~8MB per track'; + + @override + String get downloadLossyOpus128 => 'Opus 128kbps'; + + @override + String get downloadLossyOpus128Subtitle => 'Smallest size, ~4MB per track'; + @override String get qualityNote => 'Actual quality depends on track availability from the service'; @@ -7250,6 +8442,13 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get albumFolderArtistAlbumSinglesSubtitle => 'Artist/Album/ and Artist/Singles/'; + @override + String get albumFolderArtistAlbumFlat => 'Artist / Album (Singles flat)'; + + @override + String get albumFolderArtistAlbumFlatSubtitle => + 'Artist/Album/ and Artist/song.flac'; + @override String get downloadedAlbumDeleteSelected => 'Delete Selected'; @@ -7445,6 +8644,25 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get libraryShowDuplicateIndicatorSubtitle => 'Show when searching for existing tracks'; + @override + String get libraryAutoScan => 'Auto Scan'; + + @override + String get libraryAutoScanSubtitle => + 'Automatically scan your library for new files'; + + @override + String get libraryAutoScanOff => 'Off'; + + @override + String get libraryAutoScanOnOpen => 'Every app open'; + + @override + String get libraryAutoScanDaily => 'Daily'; + + @override + String get libraryAutoScanWeekly => 'Weekly'; + @override String get libraryActions => 'Actions'; @@ -7495,6 +8713,17 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { return '$_temp0'; } + @override + String libraryFilesUnit(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'files', + one: 'file', + ); + return '$_temp0'; + } + @override String libraryLastScanned(String time) { return 'Last scanned: $time'; @@ -7506,6 +8735,9 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get libraryScanning => 'Scanning...'; + @override + String get libraryScanFinalizing => 'Finalizing library...'; + @override String libraryScanProgress(String progress, int total) { return '$progress% of $total files'; @@ -7574,6 +8806,24 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get libraryFilterFormat => 'Format'; + @override + String get libraryFilterMetadata => 'Metadata'; + + @override + String get libraryFilterMetadataComplete => 'Complete metadata'; + + @override + String get libraryFilterMetadataMissingAny => 'Missing any metadata'; + + @override + String get libraryFilterMetadataMissingYear => 'Missing year'; + + @override + String get libraryFilterMetadataMissingGenre => 'Missing genre'; + + @override + String get libraryFilterMetadataMissingAlbumArtist => 'Missing album artist'; + @override String get libraryFilterSort => 'Sort'; @@ -7583,6 +8833,18 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get libraryFilterSortOldest => 'Oldest'; + @override + String get libraryFilterSortAlbumAsc => 'Album (A-Z)'; + + @override + String get libraryFilterSortAlbumDesc => 'Album (Z-A)'; + + @override + String get libraryFilterSortGenreAsc => 'Genre (A-Z)'; + + @override + String get libraryFilterSortGenreDesc => 'Genre (Z-A)'; + @override String get timeJustNow => 'Just now'; @@ -7669,7 +8931,7 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get tutorialExtensionsTip1 => - 'Browse the Store tab to discover useful extensions'; + 'Browse the Repo tab to discover useful extensions'; @override String get tutorialExtensionsTip2 => @@ -7867,6 +9129,30 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get trackReEnrichOnlineSubtitle => 'Search metadata online and embed into file'; + @override + String get trackReEnrichFieldsTitle => 'Fields to update'; + + @override + String get trackReEnrichFieldCover => 'Cover Art'; + + @override + String get trackReEnrichFieldLyrics => 'Lyrics'; + + @override + String get trackReEnrichFieldBasicTags => 'Album, Album Artist'; + + @override + String get trackReEnrichFieldTrackInfo => 'Track & Disc Number'; + + @override + String get trackReEnrichFieldReleaseInfo => 'Date & ISRC'; + + @override + String get trackReEnrichFieldExtra => 'Genre, Label, Copyright'; + + @override + String get trackReEnrichSelectAll => 'Select All'; + @override String get trackEditMetadata => 'Edit Metadata'; @@ -7895,6 +9181,28 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get trackReEnrichFfmpegFailed => 'FFmpeg metadata embed failed'; + @override + String get queueFlacAction => 'Queue FLAC'; + + @override + String queueFlacConfirmMessage(int count) { + return 'Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n$count selected'; + } + + @override + String queueFlacFindingProgress(int current, int total) { + return 'Finding FLAC matches... ($current/$total)'; + } + + @override + String get queueFlacNoReliableMatches => + 'No reliable online matches found for the selection'; + + @override + String queueFlacQueuedWithSkipped(int addedCount, int skippedCount) { + return 'Added $addedCount tracks to queue, skipped $skippedCount'; + } + @override String trackSaveFailed(String error) { return 'Failed: $error'; @@ -7904,7 +9212,8 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get trackConvertFormat => 'Convert Format'; @override - String get trackConvertFormatSubtitle => 'Convert to MP3 or Opus'; + String get trackConvertFormatSubtitle => + 'Convert to MP3, Opus, ALAC, or FLAC'; @override String get trackConvertTitle => 'Convert Audio'; @@ -7927,6 +9236,18 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { return 'Convert from $sourceFormat to $targetFormat at $bitrate?\n\nThe original file will be deleted after conversion.'; } + @override + String trackConvertConfirmMessageLossless( + String sourceFormat, + String targetFormat, + ) { + return 'Convert from $sourceFormat to $targetFormat? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.'; + } + + @override + String get trackConvertLosslessHint => + 'Lossless conversion — no quality loss'; + @override String get trackConvertConverting => 'Converting audio...'; @@ -8180,6 +9501,17 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { return 'Convert $count $_temp0 to $format at $bitrate?\n\nOriginal files will be deleted after conversion.'; } + @override + String selectionBatchConvertConfirmMessageLossless(int count, String format) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'tracks', + one: 'track', + ); + return 'Convert $count $_temp0 to $format? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.'; + } + @override String selectionBatchConvertProgress(int current, int total) { return 'Converting $current of $total...'; @@ -8202,4 +9534,704 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get downloadUseAlbumArtistForFoldersTrackSubtitle => 'Artist folders use Track Artist only'; + + @override + String get lyricsProvidersTitle => 'Lyrics Providers'; + + @override + String get lyricsProvidersDescription => + 'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.'; + + @override + String get lyricsProvidersInfoText => + 'Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.'; + + @override + String lyricsProvidersEnabledSection(int count) { + return 'Enabled ($count)'; + } + + @override + String lyricsProvidersDisabledSection(int count) { + return 'Disabled ($count)'; + } + + @override + String get lyricsProvidersAtLeastOne => + 'At least one provider must remain enabled'; + + @override + String get lyricsProvidersSaved => 'Lyrics provider priority saved'; + + @override + String get lyricsProvidersDiscardContent => + 'You have unsaved changes that will be lost.'; + + @override + String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database'; + + @override + String get lyricsProviderNeteaseDesc => + 'NetEase Cloud Music (good for Asian songs)'; + + @override + String get lyricsProviderMusixmatchDesc => + 'Largest lyrics database (multi-language)'; + + @override + String get lyricsProviderAppleMusicDesc => + 'Word-by-word synced lyrics (via proxy)'; + + @override + String get lyricsProviderQqMusicDesc => + 'QQ Music (good for Chinese songs, via proxy)'; + + @override + String get lyricsProviderExtensionDesc => 'Extension provider'; + + @override + String get safMigrationTitle => 'Storage Update Required'; + + @override + String get safMigrationMessage1 => + 'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.'; + + @override + String get safMigrationMessage2 => + 'Please select your download folder again to switch to the new storage system.'; + + @override + String get safMigrationSuccess => 'Download folder updated to SAF mode'; + + @override + String get settingsDonate => 'Donate'; + + @override + String get settingsDonateSubtitle => 'Support SpotiFLAC-Mobile development'; + + @override + String get tooltipLoveAll => 'Love All'; + + @override + String get tooltipAddToPlaylist => 'Add to Playlist'; + + @override + String snackbarRemovedTracksFromLoved(int count) { + return 'Removed $count tracks from Loved'; + } + + @override + String snackbarAddedTracksToLoved(int count) { + return 'Added $count tracks to Loved'; + } + + @override + String get dialogDownloadAllTitle => 'Download All'; + + @override + String dialogDownloadAllMessage(int count) { + return 'Download $count tracks?'; + } + + @override + String get homeSkipAlreadyDownloaded => 'Skip already downloaded songs'; + + @override + String get homeGoToAlbum => 'Go to Album'; + + @override + String get homeAlbumInfoUnavailable => 'Album info not available'; + + @override + String get snackbarLoadingCueSheet => 'Loading CUE sheet...'; + + @override + String get snackbarMetadataSaved => 'Metadata saved successfully'; + + @override + String get snackbarFailedToEmbedLyrics => 'Failed to embed lyrics'; + + @override + String get snackbarFailedToWriteStorage => 'Failed to write back to storage'; + + @override + String snackbarError(String error) { + return 'Error: $error'; + } + + @override + String get snackbarNoActionDefined => 'No action defined for this button'; + + @override + String get noTracksFoundForAlbum => 'No tracks found for this album'; + + @override + String get downloadLocationSubtitle => + 'Choose storage mode for downloaded files.'; + + @override + String get storageModeAppFolder => 'App folder (non-SAF)'; + + @override + String get storageModeAppFolderSubtitle => 'Use default Music/SpotiFLAC path'; + + @override + String get storageModeSaf => 'SAF folder'; + + @override + String get storageModeSafSubtitle => + 'Pick folder via Android Storage Access Framework'; + + @override + String get downloadFilenameDescription => + 'Customize how your files are named.'; + + @override + String get downloadFilenameInsertTag => 'Tap to insert tag:'; + + @override + String get downloadSeparateSinglesEnabled => 'Albums/ and Singles/ folders'; + + @override + String get downloadSeparateSinglesDisabled => 'All files in same structure'; + + @override + String get downloadArtistNameFilters => 'Artist Name Filters'; + + @override + String get downloadCreatePlaylistSourceFolder => + 'Create playlist source folder'; + + @override + String get downloadCreatePlaylistSourceFolderEnabled => + 'Playlist downloads use Playlist/ plus your normal folder structure.'; + + @override + String get downloadCreatePlaylistSourceFolderDisabled => + 'Playlist downloads use the normal folder structure only.'; + + @override + String get downloadCreatePlaylistSourceFolderRedundant => + 'By Playlist already places downloads inside a playlist folder.'; + + @override + String get downloadSongLinkRegion => 'SongLink Region'; + + @override + String get downloadNetworkCompatibilityMode => 'Network compatibility mode'; + + @override + String get downloadNetworkCompatibilityModeEnabled => + 'Enabled: try HTTP + accept invalid TLS certificates (unsafe)'; + + @override + String get downloadNetworkCompatibilityModeDisabled => + 'Off: strict HTTPS certificate validation (recommended)'; + + @override + String get downloadSelectServiceToEnable => + 'Select a built-in service to enable'; + + @override + String get downloadSelectTidalQobuz => + 'Select Tidal or Qobuz above to configure quality'; + + @override + String get downloadEmbedLyricsDisabled => + 'Disabled while Embed Metadata is turned off'; + + @override + String get downloadNeteaseIncludeTranslation => + 'Netease: Include Translation'; + + @override + String get downloadNeteaseIncludeTranslationEnabled => + 'Append translated lyrics when available'; + + @override + String get downloadNeteaseIncludeTranslationDisabled => + 'Use original lyrics only'; + + @override + String get downloadNeteaseIncludeRomanization => + 'Netease: Include Romanization'; + + @override + String get downloadNeteaseIncludeRomanizationEnabled => + 'Append romanized lyrics when available'; + + @override + String get downloadNeteaseIncludeRomanizationDisabled => 'Disabled'; + + @override + String get downloadAppleQqMultiPerson => 'Apple/QQ Multi-Person Word-by-Word'; + + @override + String get downloadAppleQqMultiPersonEnabled => + 'Enable v1/v2 speaker and [bg:] tags'; + + @override + String get downloadAppleQqMultiPersonDisabled => + 'Simplified word-by-word formatting'; + + @override + String get downloadMusixmatchLanguage => 'Musixmatch Language'; + + @override + String get downloadMusixmatchLanguageAuto => 'Auto (original)'; + + @override + String get downloadFilterContributing => + 'Filter contributing artists in Album Artist'; + + @override + String get downloadFilterContributingEnabled => + 'Album Artist metadata uses primary artist only'; + + @override + String get downloadFilterContributingDisabled => + 'Keep full Album Artist metadata value'; + + @override + String get downloadProvidersNoneEnabled => 'None enabled'; + + @override + String get downloadMusixmatchLanguageCode => 'Language code'; + + @override + String get downloadMusixmatchLanguageHint => 'auto / en / es / ja'; + + @override + String get downloadMusixmatchLanguageDesc => + 'Set preferred language code (example: en, es, ja). Leave empty for auto.'; + + @override + String get downloadMusixmatchAuto => 'Auto'; + + @override + String get downloadNetworkAnySubtitle => 'WiFi + Mobile Data'; + + @override + String get downloadNetworkWifiOnlySubtitle => + 'Pause downloads on mobile data'; + + @override + String get downloadSongLinkRegionDesc => + 'Used as userCountry for SongLink API lookup.'; + + @override + String get snackbarUnsupportedAudioFormat => 'Unsupported audio format'; + + @override + String get cacheRefresh => 'Refresh'; + + @override + String dialogDownloadPlaylistsMessage(int trackCount, int playlistCount) { + String _temp0 = intl.Intl.pluralLogic( + trackCount, + locale: localeName, + other: 'tracks', + one: 'track', + ); + String _temp1 = intl.Intl.pluralLogic( + playlistCount, + locale: localeName, + other: 'playlists', + one: 'playlist', + ); + return 'Download $trackCount $_temp0 from $playlistCount $_temp1?'; + } + + @override + String bulkDownloadPlaylistsButton(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'playlists', + one: 'playlist', + ); + return 'Download $count $_temp0'; + } + + @override + String get bulkDownloadSelectPlaylists => 'Select playlists to download'; + + @override + String get snackbarSelectedPlaylistsEmpty => + 'Selected playlists have no tracks'; + + @override + String playlistsCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count playlists', + one: '1 playlist', + ); + return '$_temp0'; + } + + @override + String get editMetadataAutoFill => 'Auto-fill from online'; + + @override + String get editMetadataAutoFillDesc => + 'Select fields to fill automatically from online metadata'; + + @override + String get editMetadataAutoFillFetch => 'Fetch & Fill'; + + @override + String get editMetadataAutoFillSearching => 'Searching online...'; + + @override + String get editMetadataAutoFillNoResults => + 'No matching metadata found online'; + + @override + String editMetadataAutoFillDone(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'fields', + one: 'field', + ); + return 'Filled $count $_temp0 from online metadata'; + } + + @override + String get editMetadataAutoFillNoneSelected => + 'Select at least one field to auto-fill'; + + @override + String get editMetadataFieldTitle => 'Title'; + + @override + String get editMetadataFieldArtist => 'Artist'; + + @override + String get editMetadataFieldAlbum => 'Album'; + + @override + String get editMetadataFieldAlbumArtist => 'Album Artist'; + + @override + String get editMetadataFieldDate => 'Date'; + + @override + String get editMetadataFieldTrackNum => 'Track #'; + + @override + String get editMetadataFieldDiscNum => 'Disc #'; + + @override + String get editMetadataFieldGenre => 'Genre'; + + @override + String get editMetadataFieldIsrc => 'ISRC'; + + @override + String get editMetadataFieldLabel => 'Label'; + + @override + String get editMetadataFieldCopyright => 'Copyright'; + + @override + String get editMetadataFieldCover => 'Cover Art'; + + @override + String get editMetadataSelectAll => 'All'; + + @override + String get editMetadataSelectEmpty => 'Empty only'; + + @override + String queueDownloadingCount(int count) { + return 'Downloading ($count)'; + } + + @override + String get queueDownloadedHeader => 'Downloaded'; + + @override + String get queueFilteringIndicator => 'Filtering...'; + + @override + String queueTrackCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count tracks', + one: '1 track', + ); + return '$_temp0'; + } + + @override + String queueAlbumCount(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: '$count albums', + one: '1 album', + ); + return '$_temp0'; + } + + @override + String get queueEmptyAlbums => 'No album downloads'; + + @override + String get queueEmptyAlbumsSubtitle => + 'Download multiple tracks from an album to see them here'; + + @override + String get queueEmptySingles => 'No single downloads'; + + @override + String get queueEmptySinglesSubtitle => + 'Single track downloads will appear here'; + + @override + String get queueEmptyHistory => 'No download history'; + + @override + String get queueEmptyHistorySubtitle => 'Downloaded tracks will appear here'; + + @override + String get selectionAllPlaylistsSelected => 'All playlists selected'; + + @override + String get selectionTapPlaylistsToSelect => 'Tap playlists to select'; + + @override + String get selectionSelectPlaylistsToDelete => 'Select playlists to delete'; + + @override + String get audioAnalysisTitle => 'Audio Quality Analysis'; + + @override + String get audioAnalysisDescription => + 'Verify lossless quality with spectrum analysis'; + + @override + String get audioAnalysisAnalyzing => 'Analyzing audio...'; + + @override + String get audioAnalysisSampleRate => 'Sample Rate'; + + @override + String get audioAnalysisBitDepth => 'Bit Depth'; + + @override + String get audioAnalysisChannels => 'Channels'; + + @override + String get audioAnalysisDuration => 'Duration'; + + @override + String get audioAnalysisNyquist => 'Nyquist'; + + @override + String get audioAnalysisFileSize => 'Size'; + + @override + String get audioAnalysisDynamicRange => 'Dynamic Range'; + + @override + String get audioAnalysisPeak => 'Peak'; + + @override + String get audioAnalysisRms => 'RMS'; + + @override + String get audioAnalysisSamples => 'Samples'; + + @override + String extensionsSearchWith(String providerName) { + return 'Search with $providerName'; + } + + @override + String get extensionsHomeFeedProvider => 'Home Feed Provider'; + + @override + String get extensionsHomeFeedDescription => + 'Choose which extension provides the home feed on the main screen'; + + @override + String get extensionsHomeFeedAuto => 'Auto'; + + @override + String get extensionsHomeFeedAutoSubtitle => + 'Automatically select the best available'; + + @override + String extensionsHomeFeedUse(String extensionName) { + return 'Use $extensionName home feed'; + } + + @override + String get extensionsNoHomeFeedExtensions => 'No extensions with home feed'; + + @override + String get sortAlphaAsc => 'A-Z'; + + @override + String get sortAlphaDesc => 'Z-A'; + + @override + String get cancelDownloadTitle => 'Cancel download?'; + + @override + String cancelDownloadContent(String trackName) { + return 'This will cancel the active download for \"$trackName\".'; + } + + @override + String get cancelDownloadKeep => 'Keep'; + + @override + String get metadataSaveFailedFfmpeg => 'Failed to save metadata via FFmpeg'; + + @override + String get metadataSaveFailedStorage => + 'Failed to write metadata back to storage'; + + @override + String snackbarFolderPickerFailed(String error) { + return 'Failed to open folder picker: $error'; + } + + @override + String get errorLoadAlbum => 'Failed to load album'; + + @override + String get errorLoadPlaylist => 'Failed to load playlist'; + + @override + String get errorLoadArtist => 'Failed to load artist'; + + @override + String get notifChannelDownloadName => 'Download Progress'; + + @override + String get notifChannelDownloadDesc => 'Shows download progress for tracks'; + + @override + String get notifChannelLibraryScanName => 'Library Scan'; + + @override + String get notifChannelLibraryScanDesc => 'Shows local library scan progress'; + + @override + String notifDownloadingTrack(String trackName) { + return 'Downloading $trackName'; + } + + @override + String notifFinalizingTrack(String trackName) { + return 'Finalizing $trackName'; + } + + @override + String get notifEmbeddingMetadata => 'Embedding metadata...'; + + @override + String notifAlreadyInLibraryCount(int completed, int total) { + return 'Already in Library ($completed/$total)'; + } + + @override + String get notifAlreadyInLibrary => 'Already in Library'; + + @override + String notifDownloadCompleteCount(int completed, int total) { + return 'Download Complete ($completed/$total)'; + } + + @override + String get notifDownloadComplete => 'Download Complete'; + + @override + String notifDownloadsFinished(int completed, int failed) { + return 'Downloads Finished ($completed done, $failed failed)'; + } + + @override + String get notifAllDownloadsComplete => 'All Downloads Complete'; + + @override + String notifTracksDownloadedSuccess(int count) { + return '$count tracks downloaded successfully'; + } + + @override + String get notifScanningLibrary => 'Scanning local library'; + + @override + String notifLibraryScanProgressWithTotal( + int scanned, + int total, + int percentage, + ) { + return '$scanned/$total files • $percentage%'; + } + + @override + String notifLibraryScanProgressNoTotal(int scanned, int percentage) { + return '$scanned files scanned • $percentage%'; + } + + @override + String get notifLibraryScanComplete => 'Library scan complete'; + + @override + String notifLibraryScanCompleteBody(int count) { + return '$count tracks indexed'; + } + + @override + String notifLibraryScanExcluded(int count) { + return '$count excluded'; + } + + @override + String notifLibraryScanErrors(int count) { + return '$count errors'; + } + + @override + String get notifLibraryScanFailed => 'Library scan failed'; + + @override + String get notifLibraryScanCancelled => 'Library scan cancelled'; + + @override + String get notifLibraryScanStopped => 'Scan stopped before completion.'; + + @override + String notifDownloadingUpdate(String version) { + return 'Downloading SpotiFLAC v$version'; + } + + @override + String notifUpdateProgress(String received, String total, int percentage) { + return '$received / $total MB • $percentage%'; + } + + @override + String get notifUpdateReady => 'Update Ready'; + + @override + String notifUpdateReadyBody(String version) { + return 'SpotiFLAC v$version downloaded. Tap to install.'; + } + + @override + String get notifUpdateFailed => 'Update Failed'; + + @override + String get notifUpdateFailedBody => + 'Could not download update. Try again later.'; } diff --git a/lib/l10n/arb/app_de.arb b/lib/l10n/arb/app_de.arb index 02aa479..188f5d3 100644 --- a/lib/l10n/arb/app_de.arb +++ b/lib/l10n/arb/app_de.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Store", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Spotify-Link einfügen oder nach Namen suchen", + "homeSubtitle": "Unterstützte URL einfügen oder nach Namen suchen", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Ordnerstruktur", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Erscheinungsbild", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Tippe auf Deezer oder Spotify, um von der Erweiterung zurückzuwechseln", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Künstler Tag-Modus", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Wähle aus, wie mehrere Künstler in eingebetteten Tags geschrieben sind.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Einzelne beigefügte Werte", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Einen Künstler wert wie \"Artist A, Artist B\" für maximale Spieler-Kompatibilität schreiben.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Tags für FLAC/Opus aufteilen", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Parallele Downloads", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Erweiterungs-Store", + "optionsExtensionStore": "Erweiterungs-Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Store-Tab in Navigation anzeigen", + "optionsExtensionStoreSubtitle": "Repo-Tab in der Navigation anzeigen", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Erweiterungs-Store", + "storeTitle": "Erweiterungs-Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Herunterladen", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Verwerfen", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -732,7 +788,7 @@ "@dialogDeleteSelectedTitle": { "description": "Dialog title - delete selected items" }, - "dialogDeleteSelectedMessage": "Lösche {count} {count, plural, one {Track} other{Tracks}} aus dem Verlauf?\n\nDies löscht auch die Dateien aus dem Speicher.", + "dialogDeleteSelectedMessage": "Lösche {count} {count, plural, one {}=1{Track} other{Tracks}} aus dem Verlauf?\n\nDies löscht auch die Dateien aus dem Speicher.", "@dialogDeleteSelectedMessage": { "description": "Dialog message - delete selected tracks", "placeholders": { @@ -811,7 +867,7 @@ "@snackbarCredentialsCleared": { "description": "Snackbar - Spotify credentials removed" }, - "snackbarDeletedTracks": "{count} {count, plural, one {Titel} other{Titel}}", + "snackbarDeletedTracks": "{count} {count, plural, one {}=1{Titel} other{Titel}}", "@snackbarDeletedTracks": { "description": "Snackbar - tracks deleted", "placeholders": { @@ -995,10 +1051,50 @@ "@searchAlbums": { "description": "Search result category - albums" }, - "searchPlaylists": "Playlisten", + "searchPlaylists": "Playlists", "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Ergebnisse sortieren", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Standard", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Titel (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Titel (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Künstler (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Künstler (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Dauer (kürzeste)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Dauer (längste)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Veröffentlichungsdatum (älteste)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Veröffentlichungsdatum (Neueste)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Abspielen", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Integriert", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Anfrage Timeout. Versuche es später erneut.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Standard (Deezer/Spotify)", + "storeAddRepoTitle": "Erweiterungs-Repository hinzufügen", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Gib eine GitHub Repository-URL ein, die eine Registry.json Datei enthält, um Erweiterungen zu durchsuchen und zu installieren.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository-URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "z.B. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Repository hinzufügen", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Repository ändern", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Erweiterungs-Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Aktuelles Repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "Neue Repository-URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Standard (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "Keine Erweiterungen mit Download-Provider", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Verlustbehaftet 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Verlustbehaftetes Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Wähle das Ausgabeformat für Tidal 320kbps verlustbehaftete Downloads. Der ursprüngliche AAC Stream wird in das ausgewählte Format konvertiert.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Beste Kompatibilität, ~10MB pro Titel", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Beste Qualität, ~8MB pro Titel", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Kleinste Größe, ~4MB pro Track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Die eigentliche Qualität hängt von der Verfügbarkeit des Dienstes ab", "@qualityNote": { "description": "Note about quality availability" @@ -1897,11 +2113,19 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Ausgewählte löschen", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" }, - "downloadedAlbumDeleteMessage": "{count} {count, plural, one {Titel} other{Titel}} aus diesem Album löschen?\n\nDadurch werden auch die Dateien aus dem Speicher gelöscht.", + "downloadedAlbumDeleteMessage": "{count} {count, plural, one {}=1{Titel} other{Titel}} aus diesem Album löschen?\n\nDadurch werden auch die Dateien aus dem Speicher gelöscht.", "@downloadedAlbumDeleteMessage": { "description": "Delete confirmation with count", "placeholders": { @@ -1927,7 +2151,7 @@ "@downloadedAlbumTapToSelect": { "description": "Selection hint" }, - "downloadedAlbumDeleteCount": "Lösche {count} {count, plural, one {Titel} other{Titel}}", + "downloadedAlbumDeleteCount": "Lösche {count} {count, plural, one {}=1{Titel}other{Titel}}", "@downloadedAlbumDeleteCount": { "description": "Delete button text with count", "placeholders": { @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto-Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Aus", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Bei jeder App Öffnung", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Täglich", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Wöchentlich", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Aktionen", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{1 Datei} other{{count} Datein}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Zuletzt gescannt: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Bibliothek wird aktualisiert...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% von {total} Dateien", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadaten", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Komplette Metadaten", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Metadaten fehlen", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Jahr fehlt", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Genre fehlt", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Fehlender Album-Künstler", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sortieren", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,11 +2646,27 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Gerade eben", "@timeJustNow": { "description": "Relative time - less than a minute ago" }, - "timeMinutesAgo": "{count, plural, one {vor {count} Minute} other{vor {count} Minuten}}", + "timeMinutesAgo": "{count, plural, one {}=1{vor 1 Minute} other{vor {count} Minuten}}", "@timeMinutesAgo": { "description": "Relative time - minutes ago", "placeholders": { @@ -2374,7 +2675,7 @@ } } }, - "timeHoursAgo": "{count, plural, one {vor {count} Stunde} other{vor {count} Stunden}}", + "timeHoursAgo": "{count, plural, one {}=1{vor 1 Stunde} other{vor {count} Stunden}}", "@timeHoursAgo": { "description": "Relative time - hours ago", "placeholders": { @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Im Store Tab findest du nützliche Erweiterungen", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Metadaten bearbeiten", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Warteschlange FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Suche Online-Matches für ausgewählte Titel und Playlists für FLAC-Downloads.\n\nVorhandene Dateien werden weder geändert noch gelöscht.\n\nNur eindeutige Treffer werden automatisch zur Warteschlange hinzugefügt.\n\n{count} ausgewählt", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Fehler: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "In MP3 oder Opus konvertieren", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Konvertieren von {sourceFormat} in {targetFormat}? (kein Qualitätsverlust)\n\nDie Originaldatei wird nach der Konvertierung gelöscht.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Konvertiere Audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -2920,7 +3310,7 @@ "@collectionLoved": { "description": "Custom folder for favorite tracks" }, - "collectionPlaylists": "Playlisten", + "collectionPlaylists": "Playlists", "@collectionPlaylists": { "description": "Custom user playlists folder" }, @@ -3109,7 +3499,7 @@ "@collectionPlaylistRemoveCover": { "description": "Bottom sheet action to remove custom cover image from a playlist" }, - "selectionShareCount": "Teile {count} {count, plural, one {Titel} other{Titel}}", + "selectionShareCount": "Teile {count} {count, plural, one {}=1{Titel}other{Titel}}", "@selectionShareCount": { "description": "Share button text with count in selection mode", "placeholders": { @@ -3122,7 +3512,7 @@ "@selectionShareNoFiles": { "description": "Snackbar when no selected files exist on disk" }, - "selectionConvertCount": "Konvertiere {count} {count, plural, one {Titel} other{Titel}}", + "selectionConvertCount": "Konvertiere {count} {count, plural, one {}=1{Titel}other{Titel}}", "@selectionConvertCount": { "description": "Convert button text with count in selection mode", "placeholders": { @@ -3139,7 +3529,7 @@ "@selectionBatchConvertConfirmTitle": { "description": "Confirmation dialog title for batch conversion" }, - "selectionBatchConvertConfirmMessage": "Konvertiere {count} {format} {count, plural, one {Titel} other{Titel}} zu {bitrate}?\n\nOriginaldateien werden nach der Konvertierung gelöscht.", + "selectionBatchConvertConfirmMessage": "Konvertiere {count} {format} {count, plural, one {}=1{Titel} other{Titel}} zu {bitrate}?\n\nOriginaldateien werden nach der Konvertierung gelöscht.", "@selectionBatchConvertConfirmMessage": { "description": "Confirmation dialog message for batch conversion", "placeholders": { @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Konvertiere {count} {count, plural, one {}=1{Titel} other{Titel}} in {format}? (kein Qualitätsverlust)\n\nOriginaldateien werden nach der Konvertierung gelöscht.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Konvertiere {current} von {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Künstler-Ordner nur für Titel-Künstler", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics-Anbieter", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Lyrics aktivieren, deaktivieren und neu ordnen. Anbieter werden von oben nach unten ausprobiert, bis Lyrics gefunden werden.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Erweiterungsanbieter werden immer vor eingebauten ausgeführt. Mindestens ein Anbieter muss aktiviert bleiben.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "({count}) aktiviert", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "({count}) deaktiviert", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (gut für asiatische Lieder)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Größte Lyrics-Datenbank (mehrsprachig)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Wort-für-Wort-synchronisierte Lyrics (via Proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (gut für chinesische Lieder, via Proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Erweiterungsanbieter", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Speicheraktualisierung erforderlich", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC verwendet jetzt Android Storage Access Framework (SAF) beim Herunterladen. Dies behebt Fehler bei Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Bitte wähle dein Download-Ordner erneut aus, um zum neuen System zu wechseln.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Unterstützen", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Unterstütze die SpotiFLAC-Mobile Entwickler", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Alle lieben", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Zur Wiedergabeliste hinzufügen", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "{count} Titel von geliebt entfernt", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Alle Herunterladen", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Zum Album gehen", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Fehler: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF-Ordner", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tippe, um Tag einzufügen:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink-Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Netzwerkkompatibilitätsmodus", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Deaktiviert", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "Keine aktiviert", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Sprach-Code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WLAN + Mobile Daten", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Aktualisieren", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Lade {trackCount} {trackCount, plural, one {}=1{Titel} other{Titel}} von {playlistCount} {playlistCount, plural, one {}=1{Playlist} other{Playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Abrufen & Ausfüllen", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Titel", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Künstler", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Künstler", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Datum", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Titel #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disk #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Urheberrecht", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover-Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "Alle", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Nur leer", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Heruntergeladen", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtere...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "Keine Album-Downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Playlist zum Löschen wählen", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Audio wird analysiert...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit-Tiefe", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Kanäle", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Länge", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Größe", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamischer Bereich", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Maximum", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Proben", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Anbieter", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Download abbrechen?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Behalten", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Fehler beim Laden des Albums", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Fehler beim Laden der Playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Fehler beim Laden des Interpreten", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Fortschritt", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Bibliotheksscan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Bereits in der Bibliothek", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download abgeschlossen", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} ausgeschlossen", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} Fehler", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update bereit", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update fehlgeschlagen", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } } \ No newline at end of file diff --git a/lib/l10n/arb/app_es_ES.arb b/lib/l10n/arb/app_es_ES.arb index d5b2f6a..286f0a0 100644 --- a/lib/l10n/arb/app_es_ES.arb +++ b/lib/l10n/arb/app_es_ES.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Tienda", + "navStore": "Repositorio", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Pegar enlace de Spotify o buscar por nombre", + "homeSubtitle": "Pega una URL compatible o busca por nombre", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Formato de título único", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Patrón de título para sencillos y mini-álbumes. Usa las mismas etiquetas que un álbum completo.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Organización de carpetas", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Apariencia", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Toque Deezer o Spotify para volver desde la extensión", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "Nivelación de Ganancia", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Analizar volumen e incrustar etiquetas de RG (EBU-R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Desactivado: sin etiquetas de normalización de volumen", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Modo de Etiqueta de Artista", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Elija cómo se ingresan múltiples artistas en etiquetas incrustadas.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Valor único ingresado", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Escribe un valor ARTIST, como \"Artista A, Artista B\" para mejor compatibilidad en reproductores.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Dividir (recortar) etiquetar para FLAC/OPUS", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Escribe una etiqueta de artista por artista para FLAC y OPUS; MP3 y M4A se mantienen agrupados.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Descargas Simultáneas", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Tienda de extensiones", + "optionsExtensionStore": "Extensión .Repo (repositorio)", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Mostrar pestaña de tienda en la navegación", + "optionsExtensionStoreSubtitle": "Mostar barra de navegación repo", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -284,7 +336,7 @@ "@optionsSpotifyWarning": { "description": "Info about Spotify API requirement" }, - "optionsSpotifyDeprecationWarning": "Spotify search will be deprecated on March 3, 2026 due to Spotify API changes. Please switch to Deezer.", + "optionsSpotifyDeprecationWarning": "La función de búsqueda de Spotify dejará de estar disponible el 3 de marzo de 2026 debido a cambios en la API de Spotify. Te recomendamos que te pases a Deezer.", "@optionsSpotifyDeprecationWarning": { "description": "Warning about Spotify API deprecation" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Tienda de extensiones", + "storeTitle": "Extensión .Repo", "@storeTitle": { "description": "Store screen title" }, @@ -454,7 +506,7 @@ "@aboutSpotiSaverDesc": { "description": "Credit for SpotiSaver API" }, - "aboutAppDescription": "Download Spotify tracks in lossless quality from Tidal and Qobuz.", + "aboutAppDescription": "Descargar pistas de Spotify en alta calidad (sin pérdida) de Tidal y Qobuz.", "@aboutAppDescription": { "description": "App description in header card" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Descargar", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Descartar", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -732,7 +788,7 @@ "@dialogDeleteSelectedTitle": { "description": "Dialog title - delete selected items" }, - "dialogDeleteSelectedMessage": "¿Eliminar {count} {count, plural, one {pista} other{pistas}} del historial?\n\nEsto también eliminará los archivos del almacenamiento.", + "dialogDeleteSelectedMessage": "¿Eliminar {count} {count, plural, one {}=1{pista} other{pistas}} del historial?\n\nEsto también eliminará los archivos del almacenamiento.", "@dialogDeleteSelectedMessage": { "description": "Dialog message - delete selected tracks", "placeholders": { @@ -811,7 +867,7 @@ "@snackbarCredentialsCleared": { "description": "Snackbar - Spotify credentials removed" }, - "snackbarDeletedTracks": "Eliminado {count} {count, plural, one {pista} other{pistas}}", + "snackbarDeletedTracks": "Eliminado {count} {count, plural, one {}=1{pista} other{pistas}}", "@snackbarDeletedTracks": { "description": "Snackbar - tracks deleted", "placeholders": { @@ -901,15 +957,15 @@ "@errorNoTracksFound": { "description": "Error - search returned no results" }, - "errorUrlNotRecognized": "Link not recognized", + "errorUrlNotRecognized": "Enlace no reconocido", "@errorUrlNotRecognized": { "description": "Error title - URL not handled by any extension or service" }, - "errorUrlNotRecognizedMessage": "This link is not supported. Make sure the URL is correct and a compatible extension is installed.", + "errorUrlNotRecognizedMessage": "Este enlace no es compatible. Asegúrate de que la URL sea correcta y de tener instalada una extensión compatible.", "@errorUrlNotRecognizedMessage": { "description": "Error message - URL not recognized explanation" }, - "errorUrlFetchFailed": "Failed to load content from this link. Please try again.", + "errorUrlFetchFailed": "No se ha podido cargar el contenido de este enlace. Inténtalo de nuevo.", "@errorUrlFetchFailed": { "description": "Error message - generic URL fetch failure" }, @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Ordenar resultados", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Por defecto", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Nombre (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Nombre (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artista (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artista (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duración (más corto)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duración (más largo)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Fecha de lanzamiento (antiguo)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Fecha de lanzamiento (reciente)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Reproducir", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1007,11 +1103,11 @@ "@filenameFormat": { "description": "Setting title - filename pattern" }, - "filenameShowAdvancedTags": "Show advanced tags", + "filenameShowAdvancedTags": "Mostrar etiquetas avanzadas", "@filenameShowAdvancedTags": { "description": "Toggle label for showing advanced filename tags" }, - "filenameShowAdvancedTagsDescription": "Enable formatted tags for track padding and date patterns", + "filenameShowAdvancedTagsDescription": "Habilitar etiquetas con formato para el relleno de pistas y los formatos de fecha", "@filenameShowAdvancedTagsDescription": { "description": "Description for advanced filename tag toggle" }, @@ -1019,11 +1115,11 @@ "@folderOrganizationNone": { "description": "Folder option - flat structure" }, - "folderOrganizationByPlaylist": "By Playlist", + "folderOrganizationByPlaylist": "Por Playlist", "@folderOrganizationByPlaylist": { "description": "Folder option - playlist folders" }, - "folderOrganizationByPlaylistSubtitle": "Separate folder for each playlist", + "folderOrganizationByPlaylistSubtitle": "Una carpeta independiente para cada Playlist", "@folderOrganizationByPlaylistSubtitle": { "description": "Subtitle for playlist folder option" }, @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Fallback de extensión", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Elije qué extensiones instaladas se pueden utilizar durante el cambio automático a una alternativa. Los proveedores integrados siguen el orden de prioridad indicado anteriormente.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Solo las extensiones activas con proveedor de descarga se listan aquí.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Integrado", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1374,7 +1482,7 @@ } } }, - "tracksCount": "{count, plural, one {1 pista} other{{count} pistas}}", + "tracksCount": "{count, plural, one {}=1{1 pista} other{{count} pistas}}", "@tracksCount": { "description": "Track count display", "placeholders": { @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No se encontraron letras", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Obtener en línea", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Tiempo de espera agotado. Inténtalo de nuevo más tarde.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Por defecto (Deezer/Spotify)", + "storeAddRepoTitle": "Añadir repositorio de extensiones", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Introduzca una URL de repositorio de GitHub que contenga un archivo registry.json para navegar e instalar extensiones.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "URL del repositorio", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "Ejemplo: https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Añadir repositorio", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Cambiar repositorio", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Repositorio de extensiones", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Repositorio actual:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "Nueva URL del repositorio", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Falló al carga repositorio", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No hay extensiones disponibles", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No se encontraron extensiones", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Predeterminado (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback de extensiones", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Elija que extensiones pueden usarse como reserva", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "No hay extensiones con proveedor de descargas", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Con pérdida, 320 kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Formato con pérdida", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Formato con pérdida a 320 kbps", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Elige el formato de salida para las descargas con pérdida de Tidal a 320kbps. La transmisión AAC original se convertirá al formato que hayas seleccionado.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 (320kbps)", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Óptima compatibilidad, ~10 MB por pista", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "OPUS (256kbps)", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Opus de la mejor calidad, ~8 MB por pista", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "OPUS (128kbps)", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Tamaño mínimo: ~4 MB por pista", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "La calidad real depende de la disponibilidad de la pista del servicio", "@qualityNote": { "description": "Note about quality availability" @@ -1793,19 +2009,19 @@ "@downloadAlbumFolderStructure": { "description": "Setting - album folder organization" }, - "downloadUseAlbumArtistForFolders": "Use Album Artist for folders", + "downloadUseAlbumArtistForFolders": "Usar álbum de artista cómo carpeta", "@downloadUseAlbumArtistForFolders": { "description": "Setting - choose whether artist folders use Album Artist or Track Artist" }, - "downloadUsePrimaryArtistOnly": "Primary artist only for folders", + "downloadUsePrimaryArtistOnly": "Artista principal solo para carpetas", "@downloadUsePrimaryArtistOnly": { "description": "Setting - strip featured artists from folder name" }, - "downloadUsePrimaryArtistOnlyEnabled": "Featured artists removed from folder name (e.g. Justin Bieber, Quavo → Justin Bieber)", + "downloadUsePrimaryArtistOnlyEnabled": "Se han eliminado los nombres de los artistas destacados del nombre de la carpeta (p. ej., Justin Bieber, Quavo → Justin Bieber)", "@downloadUsePrimaryArtistOnlyEnabled": { "description": "Subtitle when primary artist only is enabled" }, - "downloadUsePrimaryArtistOnlyDisabled": "Full artist string used for folder name", + "downloadUsePrimaryArtistOnlyDisabled": "Se utiliza el nombre completo del artista como nombre de la carpeta", "@downloadUsePrimaryArtistOnlyDisabled": { "description": "Subtitle when primary artist only is disabled" }, @@ -1897,11 +2113,19 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artista / Álbum (sencillos planos)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Borrar Seleccionados", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" }, - "downloadedAlbumDeleteMessage": "¿Eliminar {count} {count, plural, one {pista} other{pistas}} del historial?\n\nEsto también eliminará los archivos del almacenamiento.", + "downloadedAlbumDeleteMessage": "¿Eliminar {count} {count, plural, one {}=1{pista} other{pistas}} del historial?\n\nEsto también eliminará los archivos del almacenamiento.", "@downloadedAlbumDeleteMessage": { "description": "Delete confirmation with count", "placeholders": { @@ -1927,7 +2151,7 @@ "@downloadedAlbumTapToSelect": { "description": "Selection hint" }, - "downloadedAlbumDeleteCount": "¡Eliminar {count} {count, plural, one {pista} other{pistas}}", + "downloadedAlbumDeleteCount": "¡Eliminar {count} {count, plural, one {}=1{pista} other{pistas}}", "@downloadedAlbumDeleteCount": { "description": "Delete button text with count", "placeholders": { @@ -1966,11 +2190,11 @@ "@recentTypePlaylist": { "description": "Recent access item type - playlist" }, - "recentEmpty": "No recent items yet", + "recentEmpty": "Aún no hay entradas recientes", "@recentEmpty": { "description": "Empty state text for recent access list" }, - "recentShowAllDownloads": "Show All Downloads", + "recentShowAllDownloads": "Mostrar todas las descargas", "@recentShowAllDownloads": { "description": "Button label to unhide hidden downloads in recent access" }, @@ -2024,7 +2248,7 @@ "@discographySinglesOnly": { "description": "Option - download only singles" }, - "discographySinglesOnlySubtitle": "{count} tracks from {albumCount} singles", + "discographySinglesOnlySubtitle": "{count} Pistas de {albumCount} sencillos", "@discographySinglesOnlySubtitle": { "description": "Subtitle showing singles tracks count", "placeholders": { @@ -2036,19 +2260,19 @@ } } }, - "discographySelectAlbums": "Select Albums...", + "discographySelectAlbums": "Seleccionar álbumes...", "@discographySelectAlbums": { "description": "Option - manually select albums to download" }, - "discographySelectAlbumsSubtitle": "Choose specific albums or singles", + "discographySelectAlbumsSubtitle": "Elige álbumes o sencillos concretos", "@discographySelectAlbumsSubtitle": { "description": "Subtitle for select albums option" }, - "discographyFetchingTracks": "Fetching tracks...", + "discographyFetchingTracks": "Cargando canciones...", "@discographyFetchingTracks": { "description": "Progress - fetching album tracks" }, - "discographyFetchingAlbum": "Fetching {current} of {total}...", + "discographyFetchingAlbum": "Cargando {current} de {total}...", "@discographyFetchingAlbum": { "description": "Progress - fetching specific album", "placeholders": { @@ -2060,7 +2284,7 @@ } } }, - "discographySelectedCount": "{count} selected", + "discographySelectedCount": "{count} seleccionados", "@discographySelectedCount": { "description": "Selection count badge", "placeholders": { @@ -2069,7 +2293,7 @@ } } }, - "discographyDownloadSelected": "Download Selected", + "discographyDownloadSelected": "Descargar seleccionados", "@discographyDownloadSelected": { "description": "Button - download selected albums" }, @@ -2138,11 +2362,11 @@ "@settingsLocalLibrarySubtitle": { "description": "Subtitle for local library settings" }, - "settingsCache": "Storage & Cache", + "settingsCache": "Almacenamiento & Caché", "@settingsCache": { "description": "Settings menu item - cache management" }, - "settingsCacheSubtitle": "View size and clear cached data", + "settingsCacheSubtitle": "Ver tamaño y borrar datos en caché", "@settingsCacheSubtitle": { "description": "Subtitle for cache management menu" }, @@ -2158,7 +2382,7 @@ "@libraryEnableLocalLibrary": { "description": "Toggle to enable library scanning" }, - "libraryEnableLocalLibrarySubtitle": "Scan and track your existing music", + "libraryEnableLocalLibrarySubtitle": "Escanea y rastrea tu música existente", "@libraryEnableLocalLibrarySubtitle": { "description": "Subtitle for enable toggle" }, @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Escaneo Automático", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Apagado", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Convert to MP3 or Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } -} \ No newline at end of file +} diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb index 9a91ed2..dccad29 100644 --- a/lib/l10n/arb/app_fr.arb +++ b/lib/l10n/arb/app_fr.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Magasin", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Coller un lien Spotify ou rechercher par nom", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Organisation du dossier", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Apparence", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Appuyez sur Deezer ou Spotify pour revenir à l'extension", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Concurrent Downloads", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Extension Store", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Show Store tab in navigation", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -292,7 +344,7 @@ "@extensionsTitle": { "description": "Extensions page title" }, - "extensionsDisabled": "Disabled", + "extensionsDisabled": "Désactivée", "@extensionsDisabled": { "description": "Extension status - inactive" }, @@ -305,7 +357,7 @@ } } }, - "extensionsAuthor": "by {author}", + "extensionsAuthor": "par {author}", "@extensionsAuthor": { "description": "Extension author credit", "placeholders": { @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Magasin d'extension", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -326,31 +378,31 @@ "@storeSearch": { "description": "Store search placeholder" }, - "storeInstall": "Install", + "storeInstall": "Installer", "@storeInstall": { "description": "Install extension button" }, - "storeInstalled": "Installed", + "storeInstalled": "Installé", "@storeInstalled": { "description": "Already installed badge" }, - "storeUpdate": "Update", + "storeUpdate": "Mettre à jour", "@storeUpdate": { "description": "Update available button" }, - "aboutTitle": "About", + "aboutTitle": "À propos de", "@aboutTitle": { "description": "About page title" }, - "aboutContributors": "Contributors", + "aboutContributors": "Contributeurs", "@aboutContributors": { "description": "Section for contributors" }, - "aboutMobileDeveloper": "Mobile version developer", + "aboutMobileDeveloper": "Développeur de la version mobile", "@aboutMobileDeveloper": { "description": "Role description for mobile dev" }, - "aboutOriginalCreator": "Creator of the original SpotiFLAC", + "aboutOriginalCreator": "Créateur de SpotiFLAC original", "@aboutOriginalCreator": { "description": "Role description for original creator" }, @@ -402,7 +454,7 @@ "@aboutTelegramChannel": { "description": "Link to Telegram channel" }, - "aboutTelegramChannelSubtitle": "Announcements and updates", + "aboutTelegramChannelSubtitle": "Annonces et mises à jour", "@aboutTelegramChannelSubtitle": { "description": "Subtitle for Telegram channel" }, @@ -603,11 +655,11 @@ "@setupStorageDescription": { "description": "Explanation for storage permission" }, - "setupNotificationGranted": "Notification Permission Granted!", + "setupNotificationGranted": "Autorisation de notifications accordée!", "@setupNotificationGranted": { "description": "Success message for notification permission" }, - "setupNotificationEnable": "Enable Notifications", + "setupNotificationEnable": "Activer les notifications", "@setupNotificationEnable": { "description": "Button to enable notifications" }, @@ -619,11 +671,11 @@ "@setupFolderDescription": { "description": "Explanation for folder selection" }, - "setupSelectFolder": "Select Folder", + "setupSelectFolder": "Sélectionner un dossier", "@setupSelectFolder": { "description": "Button to select folder" }, - "setupEnableNotifications": "Enable Notifications", + "setupEnableNotifications": "Activer les notifications", "@setupEnableNotifications": { "description": "Button to enable notifications" }, @@ -631,35 +683,35 @@ "@setupNotificationBackgroundDescription": { "description": "Detailed notification explanation" }, - "setupSkipForNow": "Skip for now", + "setupSkipForNow": "Ignorer pour le moment", "@setupSkipForNow": { "description": "Skip button text" }, - "setupNext": "Next", + "setupNext": "Suivant", "@setupNext": { "description": "Next button text" }, - "setupGetStarted": "Get Started", + "setupGetStarted": "Démarrer", "@setupGetStarted": { "description": "Final setup button" }, - "setupAllowAccessToManageFiles": "Please enable \"Allow access to manage all files\" in the next screen.", + "setupAllowAccessToManageFiles": "Veuillez activer \"Autoriser l'accès à tous les fichiers\" sur l'écran suivant.", "@setupAllowAccessToManageFiles": { "description": "Instruction for file access permission" }, - "dialogCancel": "Cancel", + "dialogCancel": "Annuler", "@dialogCancel": { "description": "Dialog button - cancel action" }, - "dialogSave": "Save", + "dialogSave": "Sauvegarder", "@dialogSave": { "description": "Dialog button - save changes" }, - "dialogDelete": "Delete", + "dialogDelete": "Supprimer", "@dialogDelete": { "description": "Dialog button - delete item" }, - "dialogRetry": "Retry", + "dialogRetry": "Réessayer", "@dialogRetry": { "description": "Dialog button - retry action" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Télécharger", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Discard", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -683,11 +739,11 @@ "@dialogRemove": { "description": "Dialog button - remove item" }, - "dialogUninstall": "Uninstall", + "dialogUninstall": "Désinstaller", "@dialogUninstall": { "description": "Dialog button - uninstall extension" }, - "dialogDiscardChanges": "Discard Changes?", + "dialogDiscardChanges": "Ignorer les modifications ?", "@dialogDiscardChanges": { "description": "Dialog title - unsaved changes warning" }, @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Play", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Built-in", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Request timed out. Try again later.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Default (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "No extensions with download provider", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Actual quality depends on track availability from the service", "@qualityNote": { "description": "Note about quality availability" @@ -1897,6 +2113,14 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Delete Selected", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Convert to MP3 or Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } } \ No newline at end of file diff --git a/lib/l10n/arb/app_hi.arb b/lib/l10n/arb/app_hi.arb index af06bd6..355c5c7 100644 --- a/lib/l10n/arb/app_hi.arb +++ b/lib/l10n/arb/app_hi.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Store", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Paste a Spotify link or search by name", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Folder Organization", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "दिखावट", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Tap Deezer or Spotify to switch back from extension", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Concurrent Downloads", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Extension Store", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Show Store tab in navigation", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Extension Store", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Discard", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Play", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Built-in", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Request timed out. Try again later.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Default (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "No extensions with download provider", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Actual quality depends on track availability from the service", "@qualityNote": { "description": "Note about quality availability" @@ -1897,6 +2113,14 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Delete Selected", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Convert to MP3 or Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } } \ No newline at end of file diff --git a/lib/l10n/arb/app_id.arb b/lib/l10n/arb/app_id.arb index e54cd15..667c7d8 100644 --- a/lib/l10n/arb/app_id.arb +++ b/lib/l10n/arb/app_id.arb @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Tempel URL yang didukung atau cari berdasarkan nama", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Organisasi Folder", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Tampilan", "@appearanceTitle": { @@ -150,11 +158,11 @@ } } }, - "optionsDefaultSearchTab": "Tab Pencarian Default", + "optionsDefaultSearchTab": "Default Search Tab", "@optionsDefaultSearchTab": { "description": "Title for the preferred default search tab setting" }, - "optionsDefaultSearchTabSubtitle": "Pilih tab yang dibuka lebih dulu untuk hasil pencarian baru.", + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", "@optionsDefaultSearchTabSubtitle": { "description": "Subtitle for the preferred default search tab setting" }, @@ -198,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Unduhan Bersamaan", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -219,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Repo Ekstensi", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Tampilkan tab Repo di navigasi", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -326,14 +370,10 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Repo Ekstensi", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, - "storeLoadError": "Gagal memuat repo", - "@storeLoadError": { - "description": "Error heading when the store cannot be loaded" - }, "storeSearch": "Cari ekstensi...", "@storeSearch": { "description": "Store search placeholder" @@ -687,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Buang", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -913,15 +957,15 @@ "@errorNoTracksFound": { "description": "Error - search returned no results" }, - "errorUrlNotRecognized": "Link tidak dikenali", + "errorUrlNotRecognized": "Tautan tidak dikenali", "@errorUrlNotRecognized": { "description": "Error title - URL not handled by any extension or service" }, - "errorUrlNotRecognizedMessage": "Link ini tidak didukung. Pastikan URL benar dan ekstensi yang kompatibel sudah terpasang.", + "errorUrlNotRecognizedMessage": "Tautan ini tidak didukung. Pastikan URL sudah benar dan ekstensi yang kompatibel telah terpasang.", "@errorUrlNotRecognizedMessage": { "description": "Error message - URL not recognized explanation" }, - "errorUrlFetchFailed": "Gagal memuat konten dari link ini. Silakan coba lagi.", + "errorUrlFetchFailed": "Konten dari tautan ini gagal dimuat. Silakan coba lagi.", "@errorUrlFetchFailed": { "description": "Error message - generic URL fetch failure" }, @@ -1011,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Putar", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1131,15 +1215,15 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, - "providerPriorityFallbackExtensionsTitle": "Fallback Ekstensi", + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", "@providerPriorityFallbackExtensionsTitle": { "description": "Section title for choosing which download extensions can be used as fallback providers" }, - "providerPriorityFallbackExtensionsDescription": "Pilih ekstensi unduhan terpasang mana yang boleh dipakai saat fallback otomatis. Provider bawaan tetap mengikuti urutan prioritas di atas.", + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", "@providerPriorityFallbackExtensionsDescription": { "description": "Section description for extension fallback selection" }, - "providerPriorityFallbackExtensionsHint": "Hanya ekstensi aktif dengan kemampuan download provider yang ditampilkan di sini.", + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", "@providerPriorityFallbackExtensionsHint": { "description": "Hint below the extension fallback selection list" }, @@ -1503,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Permintaan timeout. Coba lagi nanti.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1598,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Bawaan (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1741,7 +1885,7 @@ "@extensionsFallbackTitle": { "description": "Setting and page title for choosing which download extensions can be used during fallback" }, - "extensionsFallbackSubtitle": "Pilih ekstensi unduhan terpasang yang boleh dipakai saat fallback", + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", "@extensionsFallbackSubtitle": { "description": "Subtitle for download fallback extensions menu" }, @@ -1805,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Kualitas sebenarnya tergantung ketersediaan lagu dari layanan", "@qualityNote": { "description": "Note about quality availability" @@ -1829,22 +2013,6 @@ "@downloadUseAlbumArtistForFolders": { "description": "Setting - choose whether artist folders use Album Artist or Track Artist" }, - "downloadCreatePlaylistSourceFolder": "Buat folder sumber playlist", - "@downloadCreatePlaylistSourceFolder": { - "description": "Setting title for adding a playlist folder prefix before the normal organization structure" - }, - "downloadCreatePlaylistSourceFolderEnabled": "Unduhan dari playlist memakai Playlist/ lalu struktur folder normal Anda.", - "@downloadCreatePlaylistSourceFolderEnabled": { - "description": "Subtitle when playlist source folder prefix is enabled" - }, - "downloadCreatePlaylistSourceFolderDisabled": "Unduhan dari playlist hanya memakai struktur folder normal.", - "@downloadCreatePlaylistSourceFolderDisabled": { - "description": "Subtitle when playlist source folder prefix is disabled" - }, - "downloadCreatePlaylistSourceFolderRedundant": "Mode Berdasarkan Playlist sudah menaruh unduhan ke dalam folder playlist.", - "@downloadCreatePlaylistSourceFolderRedundant": { - "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" - }, "downloadUsePrimaryArtistOnly": "Hanya artis utama untuk folder", "@downloadUsePrimaryArtistOnly": { "description": "Setting - strip featured artists from folder name" @@ -1945,6 +2113,14 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Hapus yang Dipilih", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" @@ -2226,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2283,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2300,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2397,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2409,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2495,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Buka tab Repo untuk menemukan ekstensi yang berguna", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2761,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2803,11 +3088,11 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, - "queueFlacAction": "Antrekan FLAC", + "queueFlacAction": "Queue FLAC", "@queueFlacAction": { "description": "Action/button label for queueing FLAC redownloads for local tracks" }, - "queueFlacConfirmMessage": "Cari kecocokan online untuk track yang dipilih lalu antrekan download FLAC.\n\nFile yang sudah ada tidak akan diubah atau dihapus.\n\nHanya kecocokan dengan keyakinan tinggi yang akan diantrikan otomatis.\n\n{count} dipilih", + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", "@queueFlacConfirmMessage": { "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", "placeholders": { @@ -2816,7 +3101,7 @@ } } }, - "queueFlacFindingProgress": "Mencari kecocokan FLAC... ({current}/{total})", + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", "@queueFlacFindingProgress": { "description": "Snackbar while resolving remote matches for local FLAC redownloads", "placeholders": { @@ -2828,11 +3113,11 @@ } } }, - "queueFlacNoReliableMatches": "Tidak ada kecocokan online yang cukup meyakinkan untuk pilihan ini", + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", "@queueFlacNoReliableMatches": { "description": "Snackbar when no safe FLAC redownload matches were found" }, - "queueFlacQueuedWithSkipped": "Menambahkan {addedCount} track ke antrean, melewati {skippedCount}", + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", "@queueFlacQueuedWithSkipped": { "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", "placeholders": { @@ -2857,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Konversi ke MP3, Opus, ALAC, atau FLAC", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2892,7 +3177,7 @@ } } }, - "trackConvertConfirmMessageLossless": "Konversi dari {sourceFormat} ke {targetFormat}? (Lossless — tanpa kehilangan kualitas)\n\nFile asli akan dihapus setelah konversi.", + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", "@trackConvertConfirmMessageLossless": { "description": "Confirmation dialog message for lossless-to-lossless conversion", "placeholders": { @@ -2904,7 +3189,7 @@ } } }, - "trackConvertLosslessHint": "Konversi lossless — tanpa kehilangan kualitas", + "trackConvertLosslessHint": "Lossless conversion — no quality loss", "@trackConvertLosslessHint": { "description": "Hint shown when converting between lossless formats" }, @@ -3259,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3302,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } -} +} \ No newline at end of file diff --git a/lib/l10n/arb/app_ja.arb b/lib/l10n/arb/app_ja.arb index 7dd086a..c265d49 100644 --- a/lib/l10n/arb/app_ja.arb +++ b/lib/l10n/arb/app_ja.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "ストア", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Spotify のリンクを貼り付けるか、名前で検索します", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "フォルダ構成", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "外観", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Tap Deezer or Spotify to switch back from extension", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "同時ダウンロード", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "拡張ストア", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "ナビゲーションにストアタブを表示", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "拡張ストア", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "破棄", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "再生", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "内蔵", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "リクエストがタイムアウトしました。後ほどお試しください。", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "デフォルト (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "ダウンロードプロバイダーの拡張はありません", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "実際の品質はサービスからのトラックの可用性に依存します", "@qualityNote": { "description": "Note about quality availability" @@ -1897,6 +2113,14 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "選択済みを削除", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "アクション", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "最終スキャン: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "メタデータを編集", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "失敗: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "MP3 または Opus に変換", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "オーディオを変換中...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } } \ No newline at end of file diff --git a/lib/l10n/arb/app_ko.arb b/lib/l10n/arb/app_ko.arb index 7565a8b..862b39c 100644 --- a/lib/l10n/arb/app_ko.arb +++ b/lib/l10n/arb/app_ko.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Store", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Spotify URL을 붙여 넣거나 검색", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "폴더 분류 형식", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "외관", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Deezer 또는 Spotify를 탭하여 확장 기능에서 다시 전환하세요.", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "동시 다운로드", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "확장 기능 스토어", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "탐색 메뉴에 스토어 탭 표시", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "확장 기능 스토어", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "취소", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "재생", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Built-in", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Request timed out. Try again later.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Default (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "No extensions with download provider", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Actual quality depends on track availability from the service", "@qualityNote": { "description": "Note about quality availability" @@ -1897,6 +2113,14 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Delete Selected", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Convert to MP3 or Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } } \ No newline at end of file diff --git a/lib/l10n/arb/app_nl.arb b/lib/l10n/arb/app_nl.arb index e7031f0..5e4be11 100644 --- a/lib/l10n/arb/app_nl.arb +++ b/lib/l10n/arb/app_nl.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Store", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Paste a Spotify link or search by name", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Folder Organization", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Appearance", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Tap Deezer or Spotify to switch back from extension", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Concurrent Downloads", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Extension Store", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Show Store tab in navigation", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Extension Store", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Discard", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Play", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Built-in", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Request timed out. Try again later.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Default (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "No extensions with download provider", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Actual quality depends on track availability from the service", "@qualityNote": { "description": "Note about quality availability" @@ -1897,6 +2113,14 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Delete Selected", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Convert to MP3 or Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } } \ No newline at end of file diff --git a/lib/l10n/arb/app_pt_PT.arb b/lib/l10n/arb/app_pt_PT.arb index e5eb9c0..3cf494e 100644 --- a/lib/l10n/arb/app_pt_PT.arb +++ b/lib/l10n/arb/app_pt_PT.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Loja", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Cole um link do Spotify ou procure por nome", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Organização de Pastas", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Aparência", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Toque no Deezer ou Spotify para alternar de volta da extensão", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Downloads Simultâneos", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Loja de Extensões", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Mostrar aba da Loja na navegação", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Loja de Extensões", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Descartar", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -732,7 +788,7 @@ "@dialogDeleteSelectedTitle": { "description": "Dialog title - delete selected items" }, - "dialogDeleteSelectedMessage": "Apagar {count} {count, plural, one {faixa} other{faixas}} do histórico?\n\nIsso também apagará os arquivos do armazenamento.", + "dialogDeleteSelectedMessage": "Apagar {count} {count, plural, one {}=1{faixa} other{faixas}} do histórico?\n\nIsso também apagará os arquivos do armazenamento.", "@dialogDeleteSelectedMessage": { "description": "Dialog message - delete selected tracks", "placeholders": { @@ -811,7 +867,7 @@ "@snackbarCredentialsCleared": { "description": "Snackbar - Spotify credentials removed" }, - "snackbarDeletedTracks": "{count} {count, plural, one {faixa apagada} other{faixas apagadas}}", + "snackbarDeletedTracks": "{count} {count, plural, one {}=1{faixa apagada} other{faixas apagadas}}", "@snackbarDeletedTracks": { "description": "Snackbar - tracks deleted", "placeholders": { @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Reproduzir", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Embutido", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1374,7 +1482,7 @@ } } }, - "tracksCount": "{count, plural, one {1 faixa} other{{count} faixas}}", + "tracksCount": "{count, plural, one {}=1{1 faixa} other{{count} faixas}}", "@tracksCount": { "description": "Track count display", "placeholders": { @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "A solicitação expirou. Tente novamente mais tarde.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Padrão (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "Nenhuma extensão com provedor de download", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "A qualidade real depende da faixa que estiver disponível no serviço", "@qualityNote": { "description": "Note about quality availability" @@ -1897,11 +2113,19 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Apagar Selecionados", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" }, - "downloadedAlbumDeleteMessage": "Excluir {count} {count, plural, one {faixa} other{faixas}} deste álbum?\n\nIsso também excluirá os arquivos do armazenamento.", + "downloadedAlbumDeleteMessage": "Excluir {count} {count, plural, one {}=1{faixa} other{faixas}} deste álbum?\n\nIsso também excluirá os arquivos do armazenamento.", "@downloadedAlbumDeleteMessage": { "description": "Delete confirmation with count", "placeholders": { @@ -1927,7 +2151,7 @@ "@downloadedAlbumTapToSelect": { "description": "Selection hint" }, - "downloadedAlbumDeleteCount": "Apagar {count} {count, plural, one {faixa} other{faixas}}", + "downloadedAlbumDeleteCount": "Apagar {count} {count, plural, one {}=1{faixa} other{faixas}}", "@downloadedAlbumDeleteCount": { "description": "Delete button text with count", "placeholders": { @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Convert to MP3 or Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } -} \ No newline at end of file +} diff --git a/lib/l10n/arb/app_ru.arb b/lib/l10n/arb/app_ru.arb index 4d8901f..c3d650f 100644 --- a/lib/l10n/arb/app_ru.arb +++ b/lib/l10n/arb/app_ru.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Магазин", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Вставьте ссылку Spotify или ищите по названию", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Организация папок", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Внешний вид", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Нажмите Deezer или Spotify для возврата с расширения", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Одновременные загрузки", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Магазин расширений", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Показывать вкладку Магазин в гл. меню", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Магазин расширений", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Отменить", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -732,7 +788,7 @@ "@dialogDeleteSelectedTitle": { "description": "Dialog title - delete selected items" }, - "dialogDeleteSelectedMessage": "Удалить {count} {count, plural, one {трек} few {трека} many {треков} other{треков}} из истории?\n\nЭто также удалит файлы из хранилища.", + "dialogDeleteSelectedMessage": "Удалить {count} {count, plural, one {трек} few {трека} many {треков} =1{трек} other{треков}} из истории?\n\nЭто также удалит файлы из хранилища.", "@dialogDeleteSelectedMessage": { "description": "Dialog message - delete selected tracks", "placeholders": { @@ -811,7 +867,7 @@ "@snackbarCredentialsCleared": { "description": "Snackbar - Spotify credentials removed" }, - "snackbarDeletedTracks": "Удалено {count} {count, plural, one {трек} few {трека} many {треков} other{треков}}", + "snackbarDeletedTracks": "Удалено {count} {count, plural, one {трек} few {трека} many {треков} =1{трек} other{треков}}", "@snackbarDeletedTracks": { "description": "Snackbar - tracks deleted", "placeholders": { @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Воспроизвести", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Встроенные", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1374,7 +1482,7 @@ } } }, - "tracksCount": "{count, plural, one {{count} трек} few {{count} трека} many {{count} треков} other {{count} треков}}", + "tracksCount": "{count, plural, one {{count} трек} few {{count} трека} many {{count} треков} =1 {1 трек} other {{count} треков}}", "@tracksCount": { "description": "Track count display", "placeholders": { @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Время ожидания запроса истекло. Повторите попытку позже.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "По умолчанию (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "Нет расширений с провайдером загрузки", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Фактическое качество зависит от доступности треков в сервисе", "@qualityNote": { "description": "Note about quality availability" @@ -1897,11 +2113,19 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Удалить выбранные", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" }, - "downloadedAlbumDeleteMessage": "Удалить {count} {count, plural, one {трек} few {трека} many {треков} other{треков}} из этого альбома?\n\nЭто также удалит файлы из хранилища.", + "downloadedAlbumDeleteMessage": "Удалить {count} {count, plural, one {трек} few {трека} many {треков} =1{трек} other{треков}} из этого альбома?\n\nЭто также удалит файлы из хранилища.", "@downloadedAlbumDeleteMessage": { "description": "Delete confirmation with count", "placeholders": { @@ -1927,7 +2151,7 @@ "@downloadedAlbumTapToSelect": { "description": "Selection hint" }, - "downloadedAlbumDeleteCount": "Удалить {count} {count, plural, one {трек} few {трека} many {треков} other{треков}}", + "downloadedAlbumDeleteCount": "Удалить {count} {count, plural, one {трек} few {трека} many {треков} =1{трек} other{треков}}", "@downloadedAlbumDeleteCount": { "description": "Delete button text with count", "placeholders": { @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Действия", "@libraryActions": { "description": "Section header for library actions" @@ -2226,7 +2474,7 @@ "@libraryAboutDescription": { "description": "Description of local library feature" }, - "libraryTracksUnit": "{count, plural, one {трек} few {трека} many {треков} other{треков}}", + "libraryTracksUnit": "{count, plural, one {трек} few {трека} many {треков} =1{трек} other{треков}}", "@libraryTracksUnit": { "description": "Unit label for tracks count (without the number itself)", "placeholders": { @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Последнее сканирование: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% из {total} файлов", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Сортировка", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,11 +2646,27 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Только что", "@timeJustNow": { "description": "Relative time - less than a minute ago" }, - "timeMinutesAgo": "{count, plural, one {{count} минуту} few {{count} минуты} many {{count} минут} other {{count} минут}} назад", + "timeMinutesAgo": "{count, plural, one {{count} минуту} few {{count} минуты} many {{count} минут} =1 {1 минуту} other {{count} минут}} назад", "@timeMinutesAgo": { "description": "Relative time - minutes ago", "placeholders": { @@ -2374,7 +2675,7 @@ } } }, - "timeHoursAgo": "{count, plural, one {{count} час} few {{count} часа} many {{count} часов} other {{count} часов}} назад", + "timeHoursAgo": "{count, plural, one {{count} час} few {{count} часа} many {{count} часов} =1 {1 час} other {{count} часов}} назад", "@timeHoursAgo": { "description": "Relative time - hours ago", "placeholders": { @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Просмотрите вкладку Магазина, чтобы найти полезные расширения", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Редактировать метаданные", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Ошибка: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Конвертировать в MP3 или Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Конвертация аудио...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -2944,7 +3334,7 @@ "@collectionNoPlaylistsSubtitle": { "description": "Empty state subtitle when user has no playlists" }, - "collectionPlaylistTracks": "{count, plural, one {{count} трек} few {{count} трека} many {{count} треков} other {{count} треков}}", + "collectionPlaylistTracks": "{count, plural, one {{count} трек} few {{count} трека} many {{count} треков} =1 {1 трек} other {{count} треков}}", "@collectionPlaylistTracks": { "description": "Track count label for custom playlists", "placeholders": { @@ -3109,7 +3499,7 @@ "@collectionPlaylistRemoveCover": { "description": "Bottom sheet action to remove custom cover image from a playlist" }, - "selectionShareCount": "Отправить {count} {count, plural, one {трек} few {трека} many {треков} other{треков}}", + "selectionShareCount": "Отправить {count} {count, plural, one {трек} few {трека} many {треков} =1{трек} other{треков}}", "@selectionShareCount": { "description": "Share button text with count in selection mode", "placeholders": { @@ -3122,7 +3512,7 @@ "@selectionShareNoFiles": { "description": "Snackbar when no selected files exist on disk" }, - "selectionConvertCount": "Конвертировать {count} {count, plural, one {трек} few {трека} many {треков} other{треков}}", + "selectionConvertCount": "Конвертировать {count} {count, plural, one {трек} few {трека} many {треков} =1{трек} other{треков}}", "@selectionConvertCount": { "description": "Convert button text with count in selection mode", "placeholders": { @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Конвертация {current} из {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Папки исполнителя используют только трек исполнителя", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } } \ No newline at end of file diff --git a/lib/l10n/arb/app_tr.arb b/lib/l10n/arb/app_tr.arb index b00e4fa..e0aa8df 100644 --- a/lib/l10n/arb/app_tr.arb +++ b/lib/l10n/arb/app_tr.arb @@ -5,11 +5,11 @@ "@appName": { "description": "App name - DO NOT TRANSLATE" }, - "navHome": "Ana Sayfa", + "navHome": "Ana sayfa", "@navHome": { "description": "Bottom navigation - Home tab" }, - "navLibrary": "Kitaplık", + "navLibrary": "Kitaplığın", "@navLibrary": { "description": "Bottom navigation - Library tab" }, @@ -17,23 +17,23 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Mağaza", + "navStore": "Depo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, - "homeTitle": "Ana Sayfa", + "homeTitle": "Ana sayfa", "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Bir Spotify bağlantısı yapıştırın veya şarkı arayın", + "homeSubtitle": "Desteklenen bir URL yapıştırın veya isme göre arayın", "@homeSubtitle": { "description": "Subtitle shown below search box" }, - "homeSupports": "Desteklenenler: Şarkı, Albüm, Çalma Listesi, Sanatçı bağlantıları", + "homeSupports": "Desteklenen linkler: Şarkı, Albüm, Çalma Listesi, Sanatçı linkleri", "@homeSupports": { "description": "Info text about supported URL types" }, - "homeRecent": "Son Arananlar", + "homeRecent": "En son", "@homeRecent": { "description": "Section header for recent searches" }, @@ -49,7 +49,7 @@ "@historyFilterSingles": { "description": "Filter chip - show singles only" }, - "historySearchHint": "Geçmişte ara...", + "historySearchHint": "Arama geçmişi...", "@historySearchHint": { "description": "Search bar placeholder in history" }, @@ -81,17 +81,25 @@ "@downloadTitle": { "description": "Download settings page title" }, - "downloadAskQualitySubtitle": "Her indirmede kalite seçme ekranını göster", + "downloadAskQualitySubtitle": "Her indirmeden önce kalite seçim ekranını göster", "@downloadAskQualitySubtitle": { "description": "Subtitle for ask quality toggle" }, - "downloadFilenameFormat": "Dosya Adı Formatı", + "downloadFilenameFormat": "Dosya adı formatı", "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, - "downloadFolderOrganization": "Klasör Düzeni", + "downloadSingleFilenameFormat": "Single Dosya Adı Formatı", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Single ve EP'ler için dosya adı örneği. Albüm formatıyla aynı etiketleri kullanır.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, + "downloadFolderOrganization": "Dosya Organizasyonu", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Görünüm", "@appearanceTitle": { @@ -109,15 +117,15 @@ "@appearanceThemeDark": { "description": "Dark theme" }, - "appearanceDynamicColor": "Dinamik Renkler", + "appearanceDynamicColor": "Dinamik Renk", "@appearanceDynamicColor": { "description": "Material You dynamic colors" }, - "appearanceDynamicColorSubtitle": "Uygulama renklerini duvar kağıdınızdan alır", + "appearanceDynamicColorSubtitle": "Duvar kağıdının renklerini kullan", "@appearanceDynamicColorSubtitle": { "description": "Subtitle for dynamic color" }, - "appearanceHistoryView": "Geçmiş Görünümü", + "appearanceHistoryView": "Geçmiş Düzeni", "@appearanceHistoryView": { "description": "Layout style for history" }, @@ -133,15 +141,15 @@ "@optionsTitle": { "description": "Options settings page title" }, - "optionsPrimaryProvider": "Ana Sağlayıcı", + "optionsPrimaryProvider": "Ana Kaynek", "@optionsPrimaryProvider": { "description": "Main search provider setting" }, - "optionsPrimaryProviderSubtitle": "Şarkı adıyla arama yaparken kullanılacak servis.", + "optionsPrimaryProviderSubtitle": "Şarkı ismi aratılırken kullanılan kaynak.", "@optionsPrimaryProviderSubtitle": { "description": "Subtitle for primary provider" }, - "optionsUsingExtension": "Şu anki eklenti: {extensionName}", + "optionsUsingExtension": "Kullanılan eklenti: {extensionName}", "@optionsUsingExtension": { "description": "Shows active extension name", "placeholders": { @@ -150,51 +158,95 @@ } } }, - "optionsSwitchBack": "Eklentiden çıkıp varsayılana dönmek için Deezer veya Spotify'a dokunun", + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, + "optionsSwitchBack": "Dahili kaynaklara dönmek için Deezer veya Spotify'a tıkla", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" }, - "optionsAutoFallback": "Otomatik Geçiş", + "optionsAutoFallback": "Diğerlerini dene", "@optionsAutoFallback": { "description": "Auto-retry with other services" }, - "optionsAutoFallbackSubtitle": "İndirme başarısız olursa otomatik olarak diğer servisleri dener", + "optionsAutoFallbackSubtitle": "İndirme başarısız olursa diğer hizmetleri dene", "@optionsAutoFallbackSubtitle": { "description": "Subtitle for auto fallback" }, - "optionsUseExtensionProviders": "Eklenti Sağlayıcılarını Kullan", + "optionsUseExtensionProviders": "Eklenti sağlayıcılarını kullan", "@optionsUseExtensionProviders": { "description": "Enable extension download providers" }, - "optionsUseExtensionProvidersOn": "İndirme için önce eklentiler denenecek", + "optionsUseExtensionProvidersOn": "Eklentiler ilk denenecek", "@optionsUseExtensionProvidersOn": { "description": "Status when extension providers enabled" }, - "optionsUseExtensionProvidersOff": "Sadece yerleşik sağlayıcılar kullanılıyor", + "optionsUseExtensionProvidersOff": "Sadece dahili sağlayıcıları kullan", "@optionsUseExtensionProvidersOff": { "description": "Status when extension providers disabled" }, - "optionsEmbedLyrics": "Şarkı Sözlerini Gömer", + "optionsEmbedLyrics": "Şarkı Sözlerini Göm", "@optionsEmbedLyrics": { "description": "Embed lyrics in audio files" }, - "optionsEmbedLyricsSubtitle": "Senkronize şarkı sözlerini FLAC dosyalarının içine gömer", + "optionsEmbedLyricsSubtitle": "Senkronize şarkı sözlerini FLAC dosyalarına göm", "@optionsEmbedLyricsSubtitle": { "description": "Subtitle for embed lyrics" }, - "optionsMaxQualityCover": "En Yüksek Kalite Albüm Kapağı", + "optionsMaxQualityCover": "En Yüksek Kapak Kalitesi", "@optionsMaxQualityCover": { "description": "Download highest quality album art" }, - "optionsMaxQualityCoverSubtitle": "Albüm kapağını bulunabilen en yüksek çözünürlükte indirir", + "optionsMaxQualityCoverSubtitle": "En yüksek kalitedeki albüm kapaklarını indir", "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, - "optionsConcurrentDownloads": "Eşzamanlı İndirmeler", + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Ses yüksekliğini tara ve ReplayGain etiketlerini göm (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Devre dışı: Ses normalleştirme etiketi yok", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Sanatçı Etiketi Modu", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Birden fazla sanatçının gömülü etiketlere nasıl yazılacağını seçin.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Birleşik tek değer", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Maksimum oynatıcı uyumluluğu için 'Sanatçı A, Sanatçı B' şeklinde tek bir SANATÇI değeri yazın.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "FLAC/Opus için ayrılmış etiketler", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "FLAC ve Opus için her sanatçıya ayrı bir etiket yazın; MP3 ve M4A birleşik kalır.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, + "optionsConcurrentDownloads": "Eş Zamanlı İndirmeler", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" }, - "optionsConcurrentSequential": "Sırayla (Tek tek)", + "optionsConcurrentSequential": "Sıralı (Birer birer)", "@optionsConcurrentSequential": { "description": "Download one at a time" }, @@ -207,23 +259,23 @@ } } }, - "optionsConcurrentWarning": "Aynı anda çok fazla indirme yapmak kısıtlamaya takılmanıza neden olabilir", + "optionsConcurrentWarning": "Aynı anda birden fazla indirme sınırlamaya takılabilir", "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Eklenti Mağazası", + "optionsExtensionStore": "Eklenti Deposu", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Gezinme çubuğunda Mağaza sekmesini göster", + "optionsExtensionStoreSubtitle": "Gezinme menüsünde Depo sekmesini göster", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, - "optionsCheckUpdates": "Güncellemeleri Kontrol Et", + "optionsCheckUpdates": "Güncelleştirmeleri Denetle", "@optionsCheckUpdates": { "description": "Auto update check toggle" }, - "optionsCheckUpdatesSubtitle": "Yeni bir sürüm çıktığında haber ver", + "optionsCheckUpdatesSubtitle": "Yeni sürüm çıktığında bildir", "@optionsCheckUpdatesSubtitle": { "description": "Subtitle for update check" }, @@ -231,15 +283,15 @@ "@optionsUpdateChannel": { "description": "Stable vs preview releases" }, - "optionsUpdateChannelStable": "Sadece kararlı sürümler", + "optionsUpdateChannelStable": "Sadece stabil sürümler", "@optionsUpdateChannelStable": { "description": "Only stable updates" }, - "optionsUpdateChannelPreview": "Ön izleme (Beta) sürümlerini de al", + "optionsUpdateChannelPreview": "Önizleme sürümlerini al", "@optionsUpdateChannelPreview": { "description": "Include beta/preview updates" }, - "optionsUpdateChannelWarning": "Beta sürümler hatalar içerebilir veya tamamlanmamış özellikler barındırabilir", + "optionsUpdateChannelWarning": "Önizleme sürümleri hatalar veya tamamlanmamış özellikler içerebilir", "@optionsUpdateChannelWarning": { "description": "Warning about preview channel" }, @@ -247,27 +299,27 @@ "@optionsClearHistory": { "description": "Delete all download history" }, - "optionsClearHistorySubtitle": "İndirilen tüm şarkıları geçmişten siler", + "optionsClearHistorySubtitle": "İndirilen bütün şarkıları geçmişten temizle", "@optionsClearHistorySubtitle": { "description": "Subtitle for clear history" }, - "optionsDetailedLogging": "Detaylı Hata Ayıklama (Log)", + "optionsDetailedLogging": "Detaylı Günlükleme", "@optionsDetailedLogging": { "description": "Enable verbose logs for debugging" }, - "optionsDetailedLoggingOn": "Arka planda detaylı kayıt tutuluyor", + "optionsDetailedLoggingOn": "Detaylı günlük kayıt ediliyor", "@optionsDetailedLoggingOn": { "description": "Status when logging enabled" }, - "optionsDetailedLoggingOff": "Hata bildirimi yapacaksanız açın", + "optionsDetailedLoggingOff": "Hata bildirmek için aç", "@optionsDetailedLoggingOff": { "description": "Status when logging disabled" }, - "optionsSpotifyCredentials": "Spotify API Kimlik Bilgileri", + "optionsSpotifyCredentials": "Spotify Kimlik Bilgileri", "@optionsSpotifyCredentials": { "description": "Spotify API credentials setting" }, - "optionsSpotifyCredentialsConfigured": "İstemci Kimliği (Client ID): {clientId}...", + "optionsSpotifyCredentialsConfigured": "Client ID: {clientId}...", "@optionsSpotifyCredentialsConfigured": { "description": "Shows configured client ID preview", "placeholders": { @@ -276,15 +328,15 @@ } } }, - "optionsSpotifyCredentialsRequired": "Gerekli - ayarlamak için dokunun", + "optionsSpotifyCredentialsRequired": "Zorunlu - değiştirmek için tıkla", "@optionsSpotifyCredentialsRequired": { "description": "Prompt to set up credentials" }, - "optionsSpotifyWarning": "Spotify, kendi API kimlik bilgilerinizi kullanmanızı gerektirir. developer.spotify.com adresinden ücretsiz alabilirsiniz.", + "optionsSpotifyWarning": "Spotify'ın senin API kimlik bilgilerine ihtiyacı var. Onları developer.spotify.com'dan alabilirsin", "@optionsSpotifyWarning": { "description": "Info about Spotify API requirement" }, - "optionsSpotifyDeprecationWarning": "Spotify API'sindeki değişiklikler nedeniyle Spotify araması 3 Mart 2026'da kullanımdan kaldırılacak. Lütfen Deezer'a geçin.", + "optionsSpotifyDeprecationWarning": "Spotify API değişiklikleri nedeniyle Spotify araması 3 Mart 2026 tarihinde kullanımdan kaldırılacaktır. Lütfen Deezer'a geçiş yapın.", "@optionsSpotifyDeprecationWarning": { "description": "Warning about Spotify API deprecation" }, @@ -292,11 +344,11 @@ "@extensionsTitle": { "description": "Extensions page title" }, - "extensionsDisabled": "Devre dışı", + "extensionsDisabled": "Devre Dışı", "@extensionsDisabled": { "description": "Extension status - inactive" }, - "extensionsVersion": "Sürüm {version}", + "extensionsVersion": "Versiyon {version}", "@extensionsVersion": { "description": "Extension version display", "placeholders": { @@ -318,19 +370,19 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Eklenti Mağazası", + "storeTitle": "Uzantı Deposu", "@storeTitle": { "description": "Store screen title" }, - "storeSearch": "Eklentilerde ara...", + "storeSearch": "Eklenti ara...", "@storeSearch": { "description": "Store search placeholder" }, - "storeInstall": "Yükle", + "storeInstall": "Kur", "@storeInstall": { "description": "Install extension button" }, - "storeInstalled": "Yüklü", + "storeInstalled": "Kuruldu", "@storeInstalled": { "description": "Already installed badge" }, @@ -346,15 +398,15 @@ "@aboutContributors": { "description": "Section for contributors" }, - "aboutMobileDeveloper": "Mobil sürüm geliştiricisi", + "aboutMobileDeveloper": "Mobil versiyon geliştiricisi", "@aboutMobileDeveloper": { "description": "Role description for mobile dev" }, - "aboutOriginalCreator": "Orijinal SpotiFLAC'ın yaratıcısı", + "aboutOriginalCreator": "Orijinal SpotiFLAC'ın kurucusu", "@aboutOriginalCreator": { "description": "Role description for original creator" }, - "aboutLogoArtist": "Uygulamanın harika logosunu tasarlayan yetenekli sanatçı!", + "aboutLogoArtist": "Uygulama logomuzu yaratmış yetenekli sanatçımız!", "@aboutLogoArtist": { "description": "Role description for logo artist" }, @@ -362,11 +414,11 @@ "@aboutTranslators": { "description": "Section for translators" }, - "aboutSpecialThanks": "Özel Teşekkürler", + "aboutSpecialThanks": "Özel teşekkür", "@aboutSpecialThanks": { "description": "Section for special thanks" }, - "aboutLinks": "Bağlantılar", + "aboutLinks": "Linkler", "@aboutLinks": { "description": "Section for external links" }, @@ -386,7 +438,7 @@ "@aboutReportIssue": { "description": "Link to report bugs" }, - "aboutReportIssueSubtitle": "Karşılaştığınız sorunları bize iletin", + "aboutReportIssueSubtitle": "Karşılaştığın herhangi bir problemi bildir", "@aboutReportIssueSubtitle": { "description": "Subtitle for report issue" }, @@ -394,7 +446,7 @@ "@aboutFeatureRequest": { "description": "Link to suggest features" }, - "aboutFeatureRequestSubtitle": "Uygulama için yeni özellikler önerin", + "aboutFeatureRequestSubtitle": "Uygulama için yeni özellikler isteyin", "@aboutFeatureRequestSubtitle": { "description": "Subtitle for feature request" }, @@ -406,35 +458,35 @@ "@aboutTelegramChannelSubtitle": { "description": "Subtitle for Telegram channel" }, - "aboutTelegramChat": "Telegram Topluluğu", + "aboutTelegramChat": "Telegram Grubu", "@aboutTelegramChat": { "description": "Link to Telegram chat group" }, - "aboutTelegramChatSubtitle": "Diğer kullanıcılarla sohbet edin", + "aboutTelegramChatSubtitle": "Diğer kullanıcılarla sohbet et", "@aboutTelegramChatSubtitle": { "description": "Subtitle for Telegram chat" }, - "aboutSocial": "Sosyal Medya", + "aboutSocial": "Sosyal ağlar", "@aboutSocial": { "description": "Section for social links" }, - "aboutApp": "Uygulama Bilgisi", + "aboutApp": "Uygulama", "@aboutApp": { "description": "Section for app info" }, - "aboutVersion": "Sürüm", + "aboutVersion": "Versiyon", "@aboutVersion": { "description": "Version info label" }, - "aboutBinimumDesc": "QQDL ve HiFi API'nin yaratıcısı. Bu API olmasaydı Tidal indirmeleri var olamazdı!", + "aboutBinimumDesc": "QQDL ve HiFi API'ın kurucusu. Bu API olmadan, Tidal indirmeleri olmazdı!", "@aboutBinimumDesc": { "description": "Credit description for binimum" }, - "aboutSachinsenalDesc": "Orijinal HiFi projesinin kurucusu. Tidal entegrasyonunun temel taşı!", + "aboutSachinsenalDesc": "Orijinal HiFi projesi kurucusu. Tidal entegrasyonun temeli!", "@aboutSachinsenalDesc": { "description": "Credit description for sachinsenal0x64" }, - "aboutSjdonadoDesc": "I Don't Have Spotify (IDHS) projesinin yaratıcısı. Günü kurtaran bağlantı çözümleyicimiz!", + "aboutSjdonadoDesc": "I Don't Have Spotify (IDHS) yaratıcısı. Günü kurtaran yedek bağlantı çözücü!", "@aboutSjdonadoDesc": { "description": "Credit description for sjdonado" }, @@ -442,7 +494,7 @@ "@aboutDabMusic": { "description": "Name of Qobuz API service - DO NOT TRANSLATE" }, - "aboutDabMusicDesc": "En iyi Qobuz yayın API'si. Hi-Res indirmeler onlar olmadan mümkün olamazdı!", + "aboutDabMusicDesc": "En iyi Qobuz streaming API'ı. Yüksek kalite indirmeler bunun sayesinde!", "@aboutDabMusicDesc": { "description": "Credit for DAB Music API" }, @@ -450,11 +502,11 @@ "@aboutSpotiSaver": { "description": "Name of SpotiSaver API service - DO NOT TRANSLATE" }, - "aboutSpotiSaverDesc": "Tidal Hi-Res FLAC altyapısı. Kayıpsız ses deneyiminin kilit parçası!", + "aboutSpotiSaverDesc": "Tidal Hi-Res FLAC akış uç noktaları. Kayıpsız ses yapbozunun kilit bir parçası!", "@aboutSpotiSaverDesc": { "description": "Credit for SpotiSaver API" }, - "aboutAppDescription": "Spotify şarkılarını Tidal ve Qobuz üzerinden kayıpsız kalitede indirin.", + "aboutAppDescription": "Spotify parçalarını Tidal ve Qobuz aracılığıyla kayıpsız kalitede indirin.", "@aboutAppDescription": { "description": "App description in header card" }, @@ -484,7 +536,7 @@ } } }, - "trackMetadataService": "Sağlayıcı", + "trackMetadataService": "Hizmet", "@trackMetadataService": { "description": "Metadata field - download service used" }, @@ -508,11 +560,11 @@ "@setupSkip": { "description": "Skip current step button" }, - "setupStorageAccessRequired": "Depolama İzni Gerekli", + "setupStorageAccessRequired": "Depolama Erişimi Gerekli", "@setupStorageAccessRequired": { "description": "Title when storage access needed" }, - "setupStorageAccessMessageAndroid11": "Android 11 ve üzeri, müzikleri seçtiğiniz klasöre kaydedebilmek için 'Tüm dosyalara erişim' izni gerektirir.", + "setupStorageAccessMessageAndroid11": "Android 11 ve sonrasında şarkıların seçili klasörünüze kaydedilebilmesi için \"Bütün dosyalara eriş\" iznine ihtiyaç var.", "@setupStorageAccessMessageAndroid11": { "description": "Android 11+ specific explanation" }, @@ -520,11 +572,11 @@ "@setupOpenSettings": { "description": "Button to open system settings" }, - "setupPermissionDeniedMessage": "İzin reddedildi. Devam etmek için lütfen gerekli izinleri verin.", + "setupPermissionDeniedMessage": "İzin reddedildi. Devam etmek için lütfen bütün izinleri verin.", "@setupPermissionDeniedMessage": { "description": "Error when permission denied" }, - "setupPermissionRequired": "{permissionType} İzni Gerekli", + "setupPermissionRequired": "{permissionType} İzni Zorunlu", "@setupPermissionRequired": { "description": "Generic permission required title", "placeholders": { @@ -534,7 +586,7 @@ } } }, - "setupPermissionRequiredMessage": "En iyi deneyim için {permissionType} iznine ihtiyacımız var. Bunu daha sonra Ayarlar'dan değiştirebilirsiniz.", + "setupPermissionRequiredMessage": "En iyi deneyim için {permissionType} izni zorunludur. Bunu ayarlardan daha sonra değiştirebilirsiniz.", "@setupPermissionRequiredMessage": { "description": "Generic permission required message", "placeholders": { @@ -543,11 +595,11 @@ } } }, - "setupUseDefaultFolder": "Varsayılan Klasör Kullanılsın mı?", + "setupUseDefaultFolder": "Varsayılan Klasörü Kullan?", "@setupUseDefaultFolder": { "description": "Dialog title for default folder" }, - "setupNoFolderSelected": "Hiçbir klasör seçilmedi. İndirilenler için cihazınızdaki varsayılan Müzik klasörü kullanılsın mı?", + "setupNoFolderSelected": "Klasör seçilmedi. Varsayılan \"Music\" klasörünü kullanmak ister misiniz?", "@setupNoFolderSelected": { "description": "Prompt when no folder selected" }, @@ -559,15 +611,15 @@ "@setupDownloadLocationTitle": { "description": "Download location dialog title" }, - "setupDownloadLocationIosMessage": "iOS'te indirilen dosyalar uygulamanın Belgeler klasörüne kaydedilir. Bunlara Dosyalar uygulaması üzerinden erişebilirsiniz.", + "setupDownloadLocationIosMessage": "iOS'ta indirilenler uygulamanın \"Documents\" dosyasına kaydedilir. Onlara Dosyalar uygulamasından erişebilirsiniz.", "@setupDownloadLocationIosMessage": { "description": "iOS-specific folder info" }, - "setupAppDocumentsFolder": "Uygulama Belgeleri Klasörü", + "setupAppDocumentsFolder": "Uygulama Belgeler Klasörü", "@setupAppDocumentsFolder": { "description": "iOS documents folder option" }, - "setupAppDocumentsFolderSubtitle": "Önerilen - Dosyalar uygulamasıyla erişilebilir", + "setupAppDocumentsFolderSubtitle": "Tavsiye edilen - Dosyalar uygulamasından erişilebilir", "@setupAppDocumentsFolderSubtitle": { "description": "Subtitle for documents folder" }, @@ -575,19 +627,19 @@ "@setupChooseFromFiles": { "description": "iOS file picker option" }, - "setupChooseFromFilesSubtitle": "iCloud veya başka bir konum seçin", + "setupChooseFromFilesSubtitle": "iCloud veya başka konum seç", "@setupChooseFromFilesSubtitle": { "description": "Subtitle for file picker" }, - "setupIosEmptyFolderWarning": "iOS Kısıtlaması: Boş klasörler seçilemez. Lütfen içinde en az bir dosya olan bir klasör seçin.", + "setupIosEmptyFolderWarning": "iOS'un sınırlaması: Boş klasörler seçilemiyor. İçinde en az bir dosya bulunan bir klasör seçin.", "@setupIosEmptyFolderWarning": { "description": "iOS folder selection warning" }, - "setupIcloudNotSupported": "iCloud Drive desteklenmiyor. Lütfen uygulamanın Belgeler klasörünü kullanın.", + "setupIcloudNotSupported": "iCloud Drive desteklenmiyor. Lütfen uygulama Belgeler klasörünü kullanın.", "@setupIcloudNotSupported": { "description": "Error when user selects iCloud Drive on iOS" }, - "setupDownloadInFlac": "Spotify müziklerini FLAC formatında indirin", + "setupDownloadInFlac": "Spotify şarkılarını FLAC olarak indirin", "@setupDownloadInFlac": { "description": "App tagline in setup" }, @@ -599,7 +651,7 @@ "@setupStorageRequired": { "description": "Title when storage permission needed" }, - "setupStorageDescription": "İndirdiğiniz şarkıları kaydedebilmemiz için SpotiFLAC'ın depolama iznine ihtiyacı var.", + "setupStorageDescription": "SpotiFLAC'ın şarkılarınızı kaydetmek için depolama iznine ihtiyacı var.", "@setupStorageDescription": { "description": "Explanation for storage permission" }, @@ -607,15 +659,15 @@ "@setupNotificationGranted": { "description": "Success message for notification permission" }, - "setupNotificationEnable": "Bildirimleri Aç", + "setupNotificationEnable": "Bildirimleri Etkinleştir", "@setupNotificationEnable": { "description": "Button to enable notifications" }, - "setupFolderChoose": "İndirme Klasörü Seç", + "setupFolderChoose": "İndirilecek Klasörü Seç", "@setupFolderChoose": { "description": "Button to choose folder" }, - "setupFolderDescription": "İndirilen şarkıların nereye kaydedileceğini seçin.", + "setupFolderDescription": "İndirdiğin şarkıların kaydedileceği klasörü seç.", "@setupFolderDescription": { "description": "Explanation for folder selection" }, @@ -623,11 +675,11 @@ "@setupSelectFolder": { "description": "Button to select folder" }, - "setupEnableNotifications": "Bildirimleri Aç", + "setupEnableNotifications": "Bildirimleri Etkinleştir", "@setupEnableNotifications": { "description": "Button to enable notifications" }, - "setupNotificationBackgroundDescription": "İndirme durumları ve tamamlanan şarkılar hakkında anında bildirim alın. Bu, uygulama arka plandayken süreci takip etmenizi kolaylaştırır.", + "setupNotificationBackgroundDescription": "İndirmelerin durumu hakkında bildirim al. Bunu açmak uygulama arka plandayken indirmelerinizi takip etmenizi sağlar.", "@setupNotificationBackgroundDescription": { "description": "Detailed notification explanation" }, @@ -635,15 +687,15 @@ "@setupSkipForNow": { "description": "Skip button text" }, - "setupNext": "İleri", + "setupNext": "Sıradaki", "@setupNext": { "description": "Next button text" }, - "setupGetStarted": "Hadi Başlayalım", + "setupGetStarted": "Başla", "@setupGetStarted": { "description": "Final setup button" }, - "setupAllowAccessToManageFiles": "Lütfen sonraki ekranda \"Tüm dosyaları yönetme erişimine izin ver\" seçeneğini açın.", + "setupAllowAccessToManageFiles": "Lütfen bir sonraki ekranda \"Bütün dosyalara eriş\" iznini sağlayın.", "@setupAllowAccessToManageFiles": { "description": "Instruction for file access permission" }, @@ -659,7 +711,7 @@ "@dialogDelete": { "description": "Dialog button - delete item" }, - "dialogRetry": "Yeniden Dene", + "dialogRetry": "Yeniden dene", "@dialogRetry": { "description": "Dialog button - retry action" }, @@ -667,19 +719,19 @@ "@dialogClear": { "description": "Dialog button - clear items" }, - "dialogDone": "Bitti", + "dialogDone": "Tamamlandı", "@dialogDone": { "description": "Dialog button - action completed" }, - "dialogImport": "İçe Aktar", + "dialogImport": "İçe aktar", "@dialogImport": { "description": "Dialog button - import data" }, "dialogDownload": "İndir", "@dialogDownload": { - "description": "Dialog button - download action" + "description": "Confirm button in Download All dialog" }, - "dialogDiscard": "Değişiklikleri Sil", + "dialogDiscard": "Vazgeç", "@dialogDiscard": { "description": "Dialog button - discard changes" }, @@ -687,15 +739,15 @@ "@dialogRemove": { "description": "Dialog button - remove item" }, - "dialogUninstall": "Sil", + "dialogUninstall": "Kaldır", "@dialogUninstall": { "description": "Dialog button - uninstall extension" }, - "dialogDiscardChanges": "Değişiklikler İptal Edilsin mi?", + "dialogDiscardChanges": "Değişiklikleri İptal Et?", "@dialogDiscardChanges": { "description": "Dialog title - unsaved changes warning" }, - "dialogUnsavedChanges": "Kaydedilmemiş değişiklikleriniz var. Çıkmak istediğinize emin misiniz?", + "dialogUnsavedChanges": "Kaydedilmeyen değişiklikler mevcut. Bu değişiklikleri iptal etmek istiyor musunuz?", "@dialogUnsavedChanges": { "description": "Dialog message - unsaved changes" }, @@ -707,15 +759,15 @@ "@dialogRemoveExtension": { "description": "Dialog title - uninstall extension" }, - "dialogRemoveExtensionMessage": "Bu eklentiyi kaldırmak istediğinize emin misiniz? Bu işlem geri alınamaz.", + "dialogRemoveExtensionMessage": "Bu eklentiyi kaldırmak istediğine emin misin? Bu işlem geri alınamaz.", "@dialogRemoveExtensionMessage": { "description": "Dialog message - uninstall confirmation" }, - "dialogUninstallExtension": "Eklentiyi Sil?", + "dialogUninstallExtension": "Eklentiyi Kaldır?", "@dialogUninstallExtension": { "description": "Dialog title - uninstall extension" }, - "dialogUninstallExtensionMessage": "{extensionName} eklentisini silmek istediğinize emin misiniz?", + "dialogUninstallExtensionMessage": "{extensionName} eklentisini kaldırmak istediğine emin misin?", "@dialogUninstallExtensionMessage": { "description": "Dialog message - uninstall specific extension", "placeholders": { @@ -728,15 +780,15 @@ "@dialogClearHistoryTitle": { "description": "Dialog title - clear download history" }, - "dialogClearHistoryMessage": "Tüm indirme geçmişinizi silmek istediğinize emin misiniz? Bu işlem geri alınamaz.", + "dialogClearHistoryMessage": "Tüm indirme geçmişini temizlemek istediğinizden emin misiniz? Bu işlem geri alınamaz.", "@dialogClearHistoryMessage": { "description": "Dialog message - clear history confirmation" }, - "dialogDeleteSelectedTitle": "Seçilenleri Sil", + "dialogDeleteSelectedTitle": "Seçileni Sil", "@dialogDeleteSelectedTitle": { "description": "Dialog title - delete selected items" }, - "dialogDeleteSelectedMessage": "Geçmişten {count} {count, plural, =1{şarkı} other{şarkı}} silinsin mi?\n\nBu işlem, indirilen dosyaları cihazınızdan da tamamen silecek.", + "dialogDeleteSelectedMessage": "{count} {count, plural, one {}=1{şarkıyı} other{şarkıyı}} geçmişten silmeye emin misiniz?\n\nBu işlem seçilenleri cihazınızdan da silecektir.", "@dialogDeleteSelectedMessage": { "description": "Dialog message - delete selected tracks", "placeholders": { @@ -745,11 +797,11 @@ } } }, - "dialogImportPlaylistTitle": "Çalma Listesi İçe Aktar", + "dialogImportPlaylistTitle": "Çalma listesini içe aktar", "@dialogImportPlaylistTitle": { "description": "Dialog title - import CSV playlist" }, - "dialogImportPlaylistMessage": "CSV dosyasında {count} şarkı bulundu. İndirme sırasına eklensin mi?", + "dialogImportPlaylistMessage": "CSV'de {count} şarkı bulundu. İndirme kuyruğuna ekle?", "csvImportTracks": "CSV'den {count} şarkı", "@csvImportTracks": { "description": "Label shown in quality picker for CSV import", @@ -767,7 +819,7 @@ } } }, - "snackbarAddedToQueue": "\"{trackName}\" indirme sırasına eklendi", + "snackbarAddedToQueue": "\"{trackName}\" kuyruğa eklendi", "@snackbarAddedToQueue": { "description": "Snackbar - track added to download queue", "placeholders": { @@ -776,7 +828,7 @@ } } }, - "snackbarAddedTracksToQueue": "{count} şarkı indirme sırasına eklendi", + "snackbarAddedTracksToQueue": "{count} şarkı kuyruğa eklendi", "@snackbarAddedTracksToQueue": { "description": "Snackbar - multiple tracks added to queue", "placeholders": { @@ -785,7 +837,7 @@ } } }, - "snackbarAlreadyDownloaded": "\"{trackName}\" zaten inmiş durumda", + "snackbarAlreadyDownloaded": "\"{trackName}\" zaten indirilmiş", "@snackbarAlreadyDownloaded": { "description": "Snackbar - track already exists", "placeholders": { @@ -807,15 +859,15 @@ "@snackbarHistoryCleared": { "description": "Snackbar - history deleted" }, - "snackbarCredentialsSaved": "API bilgileri kaydedildi", + "snackbarCredentialsSaved": "Kimlik bilgileri kaydedildi", "@snackbarCredentialsSaved": { "description": "Snackbar - Spotify credentials saved" }, - "snackbarCredentialsCleared": "API bilgileri silindi", + "snackbarCredentialsCleared": "Kimlik bilgileri temizlendi", "@snackbarCredentialsCleared": { "description": "Snackbar - Spotify credentials removed" }, - "snackbarDeletedTracks": "{count} {count, plural, =1{şarkı} other{şarkı}} silindi", + "snackbarDeletedTracks": "{count} {count, plural, one {}=1{şarkı} other{şarkı}} silindi", "@snackbarDeletedTracks": { "description": "Snackbar - tracks deleted", "placeholders": { @@ -824,7 +876,7 @@ } } }, - "snackbarCannotOpenFile": "Dosya açılamıyor: {error}", + "snackbarCannotOpenFile": "Dosya açılamadı: {error}", "@snackbarCannotOpenFile": { "description": "Snackbar - file open error", "placeholders": { @@ -837,11 +889,11 @@ "@snackbarFillAllFields": { "description": "Snackbar - validation error" }, - "snackbarViewQueue": "Sırayı Gör", + "snackbarViewQueue": "Kuyruğu Görüntüle", "@snackbarViewQueue": { "description": "Snackbar action - view download queue" }, - "snackbarUrlCopied": "{platform} bağlantısı panoya kopyalandı", + "snackbarUrlCopied": "{platform} Bağlantı panoya kopyalandı", "@snackbarUrlCopied": { "description": "Snackbar - URL copied", "placeholders": { @@ -855,7 +907,7 @@ "@snackbarFileNotFound": { "description": "Snackbar - file doesn't exist" }, - "snackbarSelectExtFile": "Lütfen bir .spotiflac-ext dosyası seçin", + "snackbarSelectExtFile": "Lütfen .spotiflac-ext dosyasını seçin", "@snackbarSelectExtFile": { "description": "Snackbar - wrong file type selected" }, @@ -863,11 +915,11 @@ "@snackbarProviderPrioritySaved": { "description": "Snackbar - provider order saved" }, - "snackbarMetadataProviderSaved": "Veri sağlayıcı önceliği kaydedildi", + "snackbarMetadataProviderSaved": "Meta veri sağlayıcı önceliği kaydedildi", "@snackbarMetadataProviderSaved": { "description": "Snackbar - metadata provider order saved" }, - "snackbarExtensionInstalled": "{extensionName} başarıyla yüklendi.", + "snackbarExtensionInstalled": "{extensionName} yüklendi.", "@snackbarExtensionInstalled": { "description": "Snackbar - extension installed successfully", "placeholders": { @@ -876,7 +928,7 @@ } } }, - "snackbarExtensionUpdated": "{extensionName} başarıyla güncellendi.", + "snackbarExtensionUpdated": "{extensionName} güncellendi.", "@snackbarExtensionUpdated": { "description": "Snackbar - extension updated successfully", "placeholders": { @@ -885,31 +937,31 @@ } } }, - "snackbarFailedToInstall": "Eklenti yüklenemedi", + "snackbarFailedToInstall": "Eklenti yüklenirken hata oluştu", "@snackbarFailedToInstall": { "description": "Snackbar - extension install error" }, - "snackbarFailedToUpdate": "Eklenti güncellenemedi", + "snackbarFailedToUpdate": "Eklenti güncellenirken hata oluştu", "@snackbarFailedToUpdate": { "description": "Snackbar - extension update error" }, - "errorRateLimited": "Hız Sınırına Takıldınız", + "errorRateLimited": "Aşırı istek gönderildi", "@errorRateLimited": { "description": "Error title - too many requests" }, - "errorRateLimitedMessage": "Çok fazla istek gönderdiniz. Yeniden arama yapmadan önce lütfen biraz bekleyin.", + "errorRateLimitedMessage": "Çok fazla istek. Lütfen arama yapmadan önce biraz bekleyin.", "@errorRateLimitedMessage": { "description": "Error message - rate limit explanation" }, - "errorNoTracksFound": "Şarkı bulunamadı", + "errorNoTracksFound": "Parça bulunamadı", "@errorNoTracksFound": { "description": "Error - search returned no results" }, - "errorUrlNotRecognized": "Bağlantı algılanamadı", + "errorUrlNotRecognized": "Bağlantı tanınamadı", "@errorUrlNotRecognized": { "description": "Error title - URL not handled by any extension or service" }, - "errorUrlNotRecognizedMessage": "Bu bağlantı desteklenmiyor. Bağlantının doğru olduğundan ve gerekli eklentinin yüklü olduğundan emin olun.", + "errorUrlNotRecognizedMessage": "Bu bağlantı desteklenmiyor. URL'nin doğru olduğundan ve uyumlu bir uzantının yüklü olduğundan emin olun.", "@errorUrlNotRecognizedMessage": { "description": "Error message - URL not recognized explanation" }, @@ -917,7 +969,7 @@ "@errorUrlFetchFailed": { "description": "Error message - generic URL fetch failure" }, - "errorMissingExtensionSource": "{item} yüklenemiyor: Eklenti kaynağı eksik", + "errorMissingExtensionSource": "{item} yüklenemedi: Eksik eklenti kaynağı", "@errorMissingExtensionSource": { "description": "Error - extension source not available", "placeholders": { @@ -930,11 +982,11 @@ "@actionPause": { "description": "Action button - pause download" }, - "actionResume": "Devam Et", + "actionResume": "Devam et", "@actionResume": { "description": "Action button - resume download" }, - "actionCancel": "İptal", + "actionCancel": "Vazgeç", "@actionCancel": { "description": "Action button - cancel operation" }, @@ -942,15 +994,15 @@ "@actionSelectAll": { "description": "Action button - select all items" }, - "actionDeselect": "Seçimi Kaldır", + "actionDeselect": "Seçimi kaldır", "@actionDeselect": { "description": "Action button - deselect all" }, - "actionRemoveCredentials": "API Bilgilerini Sil", + "actionRemoveCredentials": "Özellikleri kaldır", "@actionRemoveCredentials": { "description": "Action button - delete Spotify credentials" }, - "actionSaveCredentials": "API Bilgilerini Kaydet", + "actionSaveCredentials": "Özellikleri kaydet", "@actionSaveCredentials": { "description": "Action button - save Spotify credentials" }, @@ -963,15 +1015,15 @@ } } }, - "selectionAllSelected": "Tüm şarkılar seçildi", + "selectionAllSelected": "Tüm parçalar seçildi", "@selectionAllSelected": { "description": "Status - all items selected" }, - "selectionSelectToDelete": "Silinecek şarkıları seçin", + "selectionSelectToDelete": "Silinecek parçaları seçin", "@selectionSelectToDelete": { "description": "Placeholder when nothing selected" }, - "progressFetchingMetadata": "Veriler alınıyor... {current}/{total}", + "progressFetchingMetadata": "Meta verileri alınıyor... {current}/{total}", "@progressFetchingMetadata": { "description": "Progress indicator - loading track info", "placeholders": { @@ -983,7 +1035,7 @@ } } }, - "progressReadingCsv": "CSV dosyası okunuyor...", + "progressReadingCsv": "CSV okunuyor...", "@progressReadingCsv": { "description": "Progress indicator - parsing CSV file" }, @@ -1011,11 +1063,11 @@ "@searchSortDefault": { "description": "Sort option - default API order" }, - "searchSortTitleAZ": "Şarkı Adı (A-Z)", + "searchSortTitleAZ": "Başlık (A-Z)", "@searchSortTitleAZ": { "description": "Sort option - title ascending" }, - "searchSortTitleZA": "Şarkı Adı (Z-A)", + "searchSortTitleZA": "Başlık (Z-A)", "@searchSortTitleZA": { "description": "Sort option - title descending" }, @@ -1027,19 +1079,19 @@ "@searchSortArtistZA": { "description": "Sort option - artist descending" }, - "searchSortDurationShort": "Süre (Önce kısalar)", + "searchSortDurationShort": "Süre (en kısa)", "@searchSortDurationShort": { "description": "Sort option - shortest duration first" }, - "searchSortDurationLong": "Süre (Önce uzunlar)", + "searchSortDurationLong": "Süre (en uzun)", "@searchSortDurationLong": { "description": "Sort option - longest duration first" }, - "searchSortDateOldest": "Çıkış Tarihi (Önce eskiler)", + "searchSortDateOldest": "Yayın Tarihi (En eski)", "@searchSortDateOldest": { "description": "Sort option - oldest release first" }, - "searchSortDateNewest": "Çıkış Tarihi (Önce yeniler)", + "searchSortDateNewest": "Yayın Tarihi (En yeni)", "@searchSortDateNewest": { "description": "Sort option - newest release first" }, @@ -1047,7 +1099,7 @@ "@tooltipPlay": { "description": "Tooltip - play button" }, - "filenameFormat": "Dosya Adı Formatı", + "filenameFormat": "Dosya adı formatı", "@filenameFormat": { "description": "Setting title - filename pattern" }, @@ -1055,11 +1107,11 @@ "@filenameShowAdvancedTags": { "description": "Toggle label for showing advanced filename tags" }, - "filenameShowAdvancedTagsDescription": "Boşluk doldurma ve tarih formatları için gelişmiş dosya adı etiketlerini açar", + "filenameShowAdvancedTagsDescription": "Parça numarası tamamlama ve tarih desenleri için biçimlendirilmiş etiketleri etkinleştir", "@filenameShowAdvancedTagsDescription": { "description": "Description for advanced filename tag toggle" }, - "folderOrganizationNone": "Düzen yok", + "folderOrganizationNone": "Organizasyon yok", "@folderOrganizationNone": { "description": "Folder option - flat structure" }, @@ -1067,7 +1119,7 @@ "@folderOrganizationByPlaylist": { "description": "Folder option - playlist folders" }, - "folderOrganizationByPlaylistSubtitle": "Her çalma listesi için ayrı bir klasör oluşturur", + "folderOrganizationByPlaylistSubtitle": "Her çalma listesi için ayrı klasör", "@folderOrganizationByPlaylistSubtitle": { "description": "Subtitle for playlist folder option" }, @@ -1079,31 +1131,31 @@ "@folderOrganizationByAlbum": { "description": "Folder option - album folders" }, - "folderOrganizationByArtistAlbum": "Sanatçı / Albüm", + "folderOrganizationByArtistAlbum": "Sanatçı/Albüm", "@folderOrganizationByArtistAlbum": { "description": "Folder option - nested folders" }, - "folderOrganizationDescription": "İndirilen dosyaları klasörlere düzenler", + "folderOrganizationDescription": "İndirilenleri klasörlerle organize et", "@folderOrganizationDescription": { "description": "Folder organization sheet description" }, - "folderOrganizationNoneSubtitle": "Tüm dosyalar tek bir klasöre atılır", + "folderOrganizationNoneSubtitle": "Her şey indirilen dosyasına kaydedilecek", "@folderOrganizationNoneSubtitle": { "description": "Subtitle for no organization option" }, - "folderOrganizationByArtistSubtitle": "Her sanatçı için ayrı klasör oluşturur", + "folderOrganizationByArtistSubtitle": "Her sanatçı için ayrı klasör", "@folderOrganizationByArtistSubtitle": { "description": "Subtitle for artist folder option" }, - "folderOrganizationByAlbumSubtitle": "Her albüm için ayrı klasör oluşturur", + "folderOrganizationByAlbumSubtitle": "Her albüm için ayrı klasör", "@folderOrganizationByAlbumSubtitle": { "description": "Subtitle for album folder option" }, - "folderOrganizationByArtistAlbumSubtitle": "İç içe Sanatçı ve Albüm klasörleri oluşturur", + "folderOrganizationByArtistAlbumSubtitle": "Sanatçı klasörlerinin içinde Albüm klasörleri", "@folderOrganizationByArtistAlbumSubtitle": { "description": "Subtitle for nested folder option" }, - "updateAvailable": "Güncelleme Var", + "updateAvailable": "Güncelleme Mevcut", "@updateAvailable": { "description": "Update dialog title" }, @@ -1111,7 +1163,7 @@ "@updateLater": { "description": "Update button - dismiss" }, - "updateStartingDownload": "İndirme başlatılıyor...", + "updateStartingDownload": "İndirme başlıyor...", "@updateStartingDownload": { "description": "Update status - initializing" }, @@ -1119,15 +1171,15 @@ "@updateDownloadFailed": { "description": "Update error title" }, - "updateFailedMessage": "Güncelleme dosyası indirilemedi", + "updateFailedMessage": "Güncelleme indirilemedi", "@updateFailedMessage": { "description": "Update error message" }, - "updateNewVersionReady": "Uygulamanın yeni bir sürümü hazır", + "updateNewVersionReady": "Yeni bir sürüm hazır", "@updateNewVersionReady": { "description": "Update subtitle" }, - "updateCurrent": "Mevcut", + "updateCurrent": "Şimdiki", "@updateCurrent": { "description": "Label for current version" }, @@ -1139,31 +1191,43 @@ "@updateDownloading": { "description": "Update status - downloading" }, - "updateWhatsNew": "Neler Yeni?", + "updateWhatsNew": "Yenilikler", "@updateWhatsNew": { "description": "Changelog section title" }, - "updateDownloadInstall": "İndir ve Yükle", + "updateDownloadInstall": "İndir & Yükle", "@updateDownloadInstall": { "description": "Update button - download and install" }, - "updateDontRemind": "Bir daha hatırlatma", + "updateDontRemind": "Bir daha sorma", "@updateDontRemind": { "description": "Update button - skip this version" }, - "providerPriorityTitle": "Sağlayıcı Önceliği", + "providerPriorityTitle": "İndirme hizmetleri öncelik sırası", "@providerPriorityTitle": { "description": "Provider priority page title" }, - "providerPriorityDescription": "İndirme sağlayıcılarını sürükleyip sıralayın. Uygulama, şarkıları indirirken sağlayıcıları yukarıdan aşağıya doğru dener.", + "providerPriorityDescription": "İndirme hizmetlerini sıralamak için kaydır. Uygulama şarkı indirirken hizmetleri yukarıdan aşağıya doğru deneyecektir.", "@providerPriorityDescription": { "description": "Provider priority page description" }, - "providerPriorityInfo": "Bir şarkı ilk sağlayıcıda bulunamazsa, uygulama otomatik olarak listedeki bir sonrakini dener.", + "providerPriorityInfo": "Eğer bir şarkı ilk hizmette mevcut değilse uygulama otomatik olarak bir sonrakini deneyecektir.", "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, - "providerBuiltIn": "Yerleşik", + "providerPriorityFallbackExtensionsTitle": "Uzantı Yedeği", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Otomatik yedekleme sırasında hangi yüklü indirme uzantılarının kullanılabileceğini seçin. Yerleşik sağlayıcılar hâlâ yukarıdaki öncelik sırasını takip eder.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Burada yalnızca indirme sağlayıcısı yeteneğine sahip olan ve etkinleştirilmiş uzantılar listelenir.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, + "providerBuiltIn": "Dahili", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" }, @@ -1171,27 +1235,27 @@ "@providerExtension": { "description": "Label for extension-provided providers" }, - "metadataProviderPriorityTitle": "Arama Kaynağı Önceliği", + "metadataProviderPriorityTitle": "Meta Veri Önceliği", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, - "metadataProviderPriorityDescription": "Arama kaynaklarını sürükleyip sıralayın. Uygulama, şarkı ararken ve veri çekerken kaynakları yukarıdan aşağıya doğru dener.", + "metadataProviderPriorityDescription": "Meta veri sağlayıcılarını yeniden sıralamak için sürükleyin. Uygulama, parça ararken ve meta verileri alırken sağlayıcıları yukarıdan aşağıya doğru deneyecektir.", "@metadataProviderPriorityDescription": { "description": "Metadata priority page description" }, - "metadataProviderPriorityInfo": "Deezer'da hız sınırı yoktur, bu yüzden ana kaynak olarak kullanılması tavsiye edilir. Spotify, çok fazla istekte bulunduğunuzda kısıtlama yapabilir.", + "metadataProviderPriorityInfo": "Deezer'da istek sınırı yoktur ve birincil olarak önerilir. Spotify, çok sayıda istekten sonra hız sınırlaması uygulayabilir.", "@metadataProviderPriorityInfo": { "description": "Info tip about rate limits" }, - "metadataNoRateLimits": "Hız sınırı yok", + "metadataNoRateLimits": "İstek sınırı yok", "@metadataNoRateLimits": { "description": "Deezer provider description" }, - "metadataMayRateLimit": "Hız sınırı yapabilir", + "metadataMayRateLimit": "Hız sınırlaması uygulanabilir", "@metadataMayRateLimit": { "description": "Spotify provider description" }, - "logTitle": "Hata Kayıtları (Log)", + "logTitle": "Kayıtlar", "@logTitle": { "description": "Logs screen title" }, @@ -1199,7 +1263,7 @@ "@logCopied": { "description": "Snackbar - logs copied" }, - "logSearchHint": "Kayıtlarda ara...", + "logSearchHint": "Kayıtları Ara...", "@logSearchHint": { "description": "Log search placeholder" }, @@ -1207,7 +1271,7 @@ "@logFilterLevel": { "description": "Filter by log level" }, - "logFilterSection": "Filtrele", + "logFilterSection": "Filtre", "@logFilterSection": { "description": "Filter section title" }, @@ -1219,15 +1283,15 @@ "@logClearLogs": { "description": "Clear button tooltip" }, - "logClearLogsTitle": "Kayıtları Temizle", + "logClearLogsTitle": "Kayıtları temizle", "@logClearLogsTitle": { "description": "Clear logs dialog title" }, - "logClearLogsMessage": "Tüm hata kayıtlarını silmek istediğinize emin misiniz?", + "logClearLogsMessage": "Tüm kayıtları temizlemek istediğinize emin misiniz?", "@logClearLogsMessage": { "description": "Clear logs confirmation message" }, - "logFilterBySeverity": "Önem derecesine göre filtrele", + "logFilterBySeverity": "Günlükleri önem derecesine göre filtrele", "@logFilterBySeverity": { "description": "Filter dialog title" }, @@ -1235,7 +1299,7 @@ "@logNoLogsYet": { "description": "Empty state title" }, - "logNoLogsYetSubtitle": "Uygulamayı kullandıkça teknik kayıtlar burada görünecek", + "logNoLogsYetSubtitle": "Uygulamayı kullandıkça günlükler burada görünecektir", "@logNoLogsYetSubtitle": { "description": "Empty state subtitle" }, @@ -1257,15 +1321,15 @@ } } }, - "credentialsTitle": "Spotify API Bilgileri", + "credentialsTitle": "Spotify Kimlik Bilgileri", "@credentialsTitle": { "description": "Credentials dialog title" }, - "credentialsDescription": "Kendi Spotify uygulamanızın kota limitlerini kullanmak için İstemci Kimliği (Client ID) ve Gizli Anahtarınızı (Client Secret) girin.", + "credentialsDescription": "Kendi Spotify uygulama kotanızı kullanmak için Client ID ve Secret girin.", "@credentialsDescription": { "description": "Credentials dialog explanation" }, - "credentialsClientId": "Client ID (İstemci Kimliği)", + "credentialsClientId": "Client ID", "@credentialsClientId": { "description": "Client ID field label - DO NOT TRANSLATE" }, @@ -1273,7 +1337,7 @@ "@credentialsClientIdHint": { "description": "Client ID placeholder" }, - "credentialsClientSecret": "Client Secret (Gizli Anahtar)", + "credentialsClientSecret": "Client Secret", "@credentialsClientSecret": { "description": "Client Secret field label - DO NOT TRANSLATE" }, @@ -1285,7 +1349,7 @@ "@channelStable": { "description": "Update channel - stable releases" }, - "channelPreview": "Beta (Ön İzleme)", + "channelPreview": "Önizleme", "@channelPreview": { "description": "Update channel - beta/preview releases" }, @@ -1293,7 +1357,7 @@ "@sectionSearchSource": { "description": "Settings section header" }, - "sectionDownload": "İndirme", + "sectionDownload": "İndir", "@sectionDownload": { "description": "Settings section header" }, @@ -1305,15 +1369,15 @@ "@sectionApp": { "description": "Settings section header" }, - "sectionData": "Veri Yönetimi", + "sectionData": "Veri", "@sectionData": { "description": "Settings section header" }, - "sectionDebug": "Hata Ayıklama", + "sectionDebug": "Hata ayıklama", "@sectionDebug": { "description": "Settings section header" }, - "sectionService": "Servisler", + "sectionService": "Servis", "@sectionService": { "description": "Settings section header" }, @@ -1325,15 +1389,15 @@ "@sectionFileSettings": { "description": "Settings section header" }, - "sectionLyrics": "Şarkı Sözleri", + "sectionLyrics": "Şarkı sözleri", "@sectionLyrics": { "description": "Settings section header" }, - "lyricsMode": "Şarkı Sözü Formatı", + "lyricsMode": "Şarkı Sözü Modu", "@lyricsMode": { "description": "Setting - how to save lyrics" }, - "lyricsModeDescription": "Şarkı sözlerinin nasıl kaydedileceğini seçin", + "lyricsModeDescription": "Şarkı sözlerinin indirmelerinizle birlikte nasıl kaydedileceğini seçin", "@lyricsModeDescription": { "description": "Lyrics mode picker description" }, @@ -1341,7 +1405,7 @@ "@lyricsModeEmbed": { "description": "Lyrics mode option - embed in audio file" }, - "lyricsModeEmbedSubtitle": "Şarkı sözleri FLAC dosyasının içine işlenir", + "lyricsModeEmbedSubtitle": "Şarkı sözleri FLAC meta verilerinin içinde saklanır", "@lyricsModeEmbedSubtitle": { "description": "Subtitle for embed option" }, @@ -1349,7 +1413,7 @@ "@lyricsModeExternal": { "description": "Lyrics mode option - separate LRC file" }, - "lyricsModeExternalSubtitle": "Bazı müzik çalarlar için şarkının yanına ayrı bir .lrc dosyası açar", + "lyricsModeExternalSubtitle": "Samsung Music gibi oynatıcılar için ayrı .lrc dosyası", "@lyricsModeExternalSubtitle": { "description": "Subtitle for external option" }, @@ -1357,11 +1421,11 @@ "@lyricsModeBoth": { "description": "Lyrics mode option - embed and external" }, - "lyricsModeBothSubtitle": "Hem dosyaya gömer hem de .lrc dosyası olarak kaydeder", + "lyricsModeBothSubtitle": "Hem göm hem de .lrc dosyası olarak kaydet", "@lyricsModeBothSubtitle": { "description": "Subtitle for both option" }, - "sectionColor": "Renkler", + "sectionColor": "Renk", "@sectionColor": { "description": "Settings section header" }, @@ -1369,7 +1433,7 @@ "@sectionTheme": { "description": "Settings section header" }, - "sectionLayout": "Tasarım", + "sectionLayout": "Düzen", "@sectionLayout": { "description": "Settings section header" }, @@ -1381,23 +1445,23 @@ "@appearanceLanguage": { "description": "Language setting title" }, - "settingsAppearanceSubtitle": "Temalar, renkler, görünümler", + "settingsAppearanceSubtitle": "Tema, renkler, görünüm", "@settingsAppearanceSubtitle": { "description": "Appearance settings description" }, - "settingsDownloadSubtitle": "İndirme servisi, ses kalitesi, dosya adı düzeni", + "settingsDownloadSubtitle": "Servis, kalite, dosya adı formatı", "@settingsDownloadSubtitle": { "description": "Download settings description" }, - "settingsOptionsSubtitle": "İndirme limitleri, şarkı sözleri, güncellemeler", + "settingsOptionsSubtitle": "Yedekleme, sözler, kapak resmi, güncellemeler", "@settingsOptionsSubtitle": { "description": "Options settings description" }, - "settingsExtensionsSubtitle": "Yeni müzik kaynakları ve eklentileri yönetin", + "settingsExtensionsSubtitle": "İndirme sağlayıcılarını yönet", "@settingsExtensionsSubtitle": { "description": "Extensions settings description" }, - "settingsLogsSubtitle": "Sorun tespiti için uygulama kayıtlarına göz atın", + "settingsLogsSubtitle": "Hata ayıklama için uygulama günlüklerini görüntüle", "@settingsLogsSubtitle": { "description": "Logs settings description" }, @@ -1405,7 +1469,7 @@ "@loadingSharedLink": { "description": "Status when opening shared URL" }, - "pressBackAgainToExit": "Çıkmak için tekrar geri dokunun", + "pressBackAgainToExit": "Çıkmak için tekrar geri basın", "@pressBackAgainToExit": { "description": "Exit confirmation message" }, @@ -1418,7 +1482,7 @@ } } }, - "tracksCount": "{count, plural, =1{1 şarkı} other{{count} şarkı}}", + "tracksCount": "{count, plural, one {}=1{1 parça} other{{count} parça}}", "@tracksCount": { "description": "Track count display", "placeholders": { @@ -1431,15 +1495,15 @@ "@trackCopyFilePath": { "description": "Action - copy file path" }, - "trackRemoveFromDevice": "Cihazdan sil", + "trackRemoveFromDevice": "Cihazdan kaldır", "@trackRemoveFromDevice": { "description": "Action - delete downloaded file" }, - "trackLoadLyrics": "Sözleri Yükle", + "trackLoadLyrics": "Şarkı Sözlerini Yükle", "@trackLoadLyrics": { "description": "Action - fetch lyrics" }, - "trackMetadata": "Şarkı Künyesi", + "trackMetadata": "Meta Veri", "@trackMetadata": { "description": "Tab title - track metadata" }, @@ -1447,7 +1511,7 @@ "@trackFileInfo": { "description": "Tab title - file information" }, - "trackLyrics": "Sözler", + "trackLyrics": "Şarkı Sözleri", "@trackLyrics": { "description": "Tab title - lyrics" }, @@ -1455,15 +1519,15 @@ "@trackFileNotFound": { "description": "Error - file doesn't exist" }, - "trackOpenInDeezer": "Deezer'da Aç", + "trackOpenInDeezer": "Deezer'da aç", "@trackOpenInDeezer": { "description": "Action - open track in Deezer app" }, - "trackOpenInSpotify": "Spotify'da Aç", + "trackOpenInSpotify": "Spotify'da aç", "@trackOpenInSpotify": { "description": "Action - open track in Spotify app" }, - "trackTrackName": "Şarkı Adı", + "trackTrackName": "Parça adı", "@trackTrackName": { "description": "Metadata label - track title" }, @@ -1471,7 +1535,7 @@ "@trackArtist": { "description": "Metadata label - artist name" }, - "trackAlbumArtist": "Albüm Sanatçısı", + "trackAlbumArtist": "Albüm sanatçısı", "@trackAlbumArtist": { "description": "Metadata label - album artist" }, @@ -1495,7 +1559,7 @@ "@trackAudioQuality": { "description": "Metadata label - audio quality" }, - "trackReleaseDate": "Çıkış tarihi", + "trackReleaseDate": "Yayın tarihi", "@trackReleaseDate": { "description": "Metadata label - release date" }, @@ -1503,7 +1567,7 @@ "@trackGenre": { "description": "Metadata label - music genre" }, - "trackLabel": "Plak Şirketi", + "trackLabel": "Etiket / Müzik Şirketi", "@trackLabel": { "description": "Metadata label - record label" }, @@ -1511,19 +1575,27 @@ "@trackCopyright": { "description": "Metadata label - copyright information" }, - "trackDownloaded": "İndirilme tarihi", + "trackDownloaded": "İndirildi", "@trackDownloaded": { "description": "Metadata label - download date" }, - "trackCopyLyrics": "Sözleri kopyala", + "trackCopyLyrics": "Şarkı sözlerini kopyala", "@trackCopyLyrics": { "description": "Action - copy lyrics to clipboard" }, - "trackLyricsNotAvailable": "Bu şarkının sözleri bulunamadı", + "trackLyricsNotAvailable": "Bu parça için şarkı sözü mevcut değil", "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, - "trackLyricsTimeout": "Zaman aşımına uğradı. Lütfen daha sonra tekrar deneyin.", + "trackLyricsNotInFile": "Bu dosyada şarkı sözü bulunamadı", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "İnternetten Getir", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, + "trackLyricsTimeout": "İstek zaman aşımına uğradı. Daha sonra tekrar deneyin.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" }, @@ -1531,15 +1603,15 @@ "@trackLyricsLoadFailed": { "description": "Message when lyrics loading fails" }, - "trackEmbedLyrics": "Şarkı Sözlerini Gömer", + "trackEmbedLyrics": "Şarkı Sözlerini Göm", "@trackEmbedLyrics": { "description": "Action - embed lyrics into audio file" }, - "trackLyricsEmbedded": "Şarkı sözleri dosyaya başarıyla eklendi", + "trackLyricsEmbedded": "Şarkı sözleri başarıyla gömüldü", "@trackLyricsEmbedded": { "description": "Snackbar - lyrics saved to file" }, - "trackInstrumental": "Enstrümantal parça (Sözsüz)", + "trackInstrumental": "Enstrümantal parça", "@trackInstrumental": { "description": "Message when track is instrumental (no lyrics)" }, @@ -1547,11 +1619,11 @@ "@trackCopiedToClipboard": { "description": "Snackbar - content copied" }, - "trackDeleteConfirmTitle": "Cihazdan silinsin mi?", + "trackDeleteConfirmTitle": "Cihazdan kaldırılsın mı?", "@trackDeleteConfirmTitle": { "description": "Delete confirmation title" }, - "trackDeleteConfirmMessage": "Bu işlem indirdiğiniz dosyayı tamamen silecek ve geçmişinizden kaldıracak.", + "trackDeleteConfirmMessage": "Bu işlem, indirilen dosyayı kalıcı olarak silecek ve geçmişinizden kaldıracaktır.", "@trackDeleteConfirmMessage": { "description": "Delete confirmation message" }, @@ -1594,19 +1666,19 @@ "@storeFilterAll": { "description": "Store filter - all extensions" }, - "storeFilterMetadata": "Şarkı Verisi", + "storeFilterMetadata": "Meta Veri", "@storeFilterMetadata": { "description": "Store filter - metadata providers" }, - "storeFilterDownload": "İndirme", + "storeFilterDownload": "İndir", "@storeFilterDownload": { "description": "Store filter - download providers" }, - "storeFilterUtility": "Araçlar", + "storeFilterUtility": "Araç", "@storeFilterUtility": { "description": "Store filter - utility extensions" }, - "storeFilterLyrics": "Şarkı Sözü", + "storeFilterLyrics": "Şarkı Sözleri", "@storeFilterLyrics": { "description": "Store filter - lyrics providers" }, @@ -1618,27 +1690,27 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "storeAddRepoTitle": "Eklenti Deposu (Repository) Ekle", + "storeAddRepoTitle": "Uzantı Deposu Ekle", "@storeAddRepoTitle": { "description": "Store setup screen - heading when no repo is configured" }, - "storeAddRepoDescription": "Eklentilere göz atmak ve yüklemek için içinde registry.json dosyası olan bir GitHub depo bağlantısı girin.", + "storeAddRepoDescription": "Uzantılara göz atmak ve yüklemek için registry.json dosyası içeren bir GitHub depo URL'si girin.", "@storeAddRepoDescription": { "description": "Store setup screen - explanatory text" }, - "storeRepoUrlLabel": "Depo Bağlantısı (URL)", + "storeRepoUrlLabel": "Depo URL'si", "@storeRepoUrlLabel": { "description": "Label for the repository URL input field" }, - "storeRepoUrlHint": "https://github.com/kullaniciadi/depo", + "storeRepoUrlHint": "https://github.com/user/repo", "@storeRepoUrlHint": { "description": "Hint/placeholder for the repository URL input field" }, - "storeRepoUrlHelper": "Örn: https://github.com/spoti/extensions-repo", + "storeRepoUrlHelper": "örn. https://github.com/user/extensions-repo", "@storeRepoUrlHelper": { "description": "Helper text below the repository URL input field" }, - "storeAddRepoButton": "Depoyu Ekle", + "storeAddRepoButton": "Depo Ekle", "@storeAddRepoButton": { "description": "Button to submit a new repository URL" }, @@ -1646,7 +1718,7 @@ "@storeChangeRepoTooltip": { "description": "Tooltip for the change-repository icon button in the app bar" }, - "storeRepoDialogTitle": "Eklenti Deposu", + "storeRepoDialogTitle": "Uzantı Deposu", "@storeRepoDialogTitle": { "description": "Title of the change/remove repository dialog" }, @@ -1654,19 +1726,19 @@ "@storeRepoDialogCurrent": { "description": "Label shown above the current repository URL in the dialog" }, - "storeNewRepoUrlLabel": "Yeni Depo Bağlantısı", + "storeNewRepoUrlLabel": "Yeni Depo URL'si", "@storeNewRepoUrlLabel": { "description": "Label for the new repository URL field inside the dialog" }, - "storeLoadError": "Mağaza yüklenemedi", + "storeLoadError": "Depo yüklenemedi", "@storeLoadError": { "description": "Error heading when the store cannot be loaded" }, - "storeEmptyNoExtensions": "Kullanılabilir eklenti yok", + "storeEmptyNoExtensions": "Uygun uzantı yok", "@storeEmptyNoExtensions": { "description": "Message when store has no extensions" }, - "storeEmptyNoResults": "Aramanıza uygun eklenti bulunamadı", + "storeEmptyNoResults": "Uzantı bulunamadı", "@storeEmptyNoResults": { "description": "Message when search/filter returns no results" }, @@ -1674,15 +1746,15 @@ "@extensionDefaultProvider": { "description": "Default search provider option" }, - "extensionDefaultProviderSubtitle": "Uygulamanın kendi aramasını kullan", + "extensionDefaultProviderSubtitle": "Yerleşik aramayı kullan", "@extensionDefaultProviderSubtitle": { "description": "Subtitle for default provider" }, - "extensionAuthor": "Geliştirici", + "extensionAuthor": "Oluşturan", "@extensionAuthor": { "description": "Extension detail - author" }, - "extensionId": "Kimlik (ID)", + "extensionId": "ID", "@extensionId": { "description": "Extension detail - unique ID" }, @@ -1690,23 +1762,23 @@ "@extensionError": { "description": "Extension detail - error message" }, - "extensionCapabilities": "Yetenekler", + "extensionCapabilities": "Özellikler", "@extensionCapabilities": { "description": "Section header - extension features" }, - "extensionMetadataProvider": "Şarkı Verisi (Metadata) Kaynağı", + "extensionMetadataProvider": "Meta Veri Sağlayıcı", "@extensionMetadataProvider": { "description": "Capability - provides metadata" }, - "extensionDownloadProvider": "İndirme Sağlayıcısı", + "extensionDownloadProvider": "İndirme Sağlayıcı", "@extensionDownloadProvider": { "description": "Capability - provides downloads" }, - "extensionLyricsProvider": "Şarkı Sözü Sağlayıcısı", + "extensionLyricsProvider": "Şarkı Sözü Sağlayıcı", "@extensionLyricsProvider": { "description": "Capability - provides lyrics" }, - "extensionUrlHandler": "Bağlantı Okuyucu", + "extensionUrlHandler": "URL İşleyici", "@extensionUrlHandler": { "description": "Capability - handles URLs" }, @@ -1714,7 +1786,7 @@ "@extensionQualityOptions": { "description": "Capability - quality selection" }, - "extensionPostProcessingHooks": "İndirme Sonrası İşlemler", + "extensionPostProcessingHooks": "Son İşlem Kancaları", "@extensionPostProcessingHooks": { "description": "Capability - post-processing" }, @@ -1726,11 +1798,11 @@ "@extensionSettings": { "description": "Section header - extension settings" }, - "extensionRemoveButton": "Eklentiyi Kaldır", + "extensionRemoveButton": "Uzantıyı Kaldır", "@extensionRemoveButton": { "description": "Button to uninstall extension" }, - "extensionUpdated": "Son Güncelleme", + "extensionUpdated": "Güncellendi", "@extensionUpdated": { "description": "Extension detail - last update" }, @@ -1738,15 +1810,15 @@ "@extensionMinAppVersion": { "description": "Extension detail - minimum app version" }, - "extensionCustomTrackMatching": "Özel Eşleştirme Algoritması", + "extensionCustomTrackMatching": "Özel Parça Eşleştirme", "@extensionCustomTrackMatching": { "description": "Capability - custom track matching algorithm" }, - "extensionPostProcessing": "İşlem Sonrası Özellikleri", + "extensionPostProcessing": "Son İşlem", "@extensionPostProcessing": { "description": "Capability - post-download processing" }, - "extensionHooksAvailable": "{count} özel kanca (hook) mevcut", + "extensionHooksAvailable": "{count} kanca kullanılabilir", "@extensionHooksAvailable": { "description": "Post-processing hooks count", "placeholders": { @@ -1755,7 +1827,7 @@ } } }, - "extensionPatternsCount": "{count} bağlantı kalıbı", + "extensionPatternsCount": "{count} desen", "@extensionPatternsCount": { "description": "URL patterns count", "placeholders": { @@ -1764,7 +1836,7 @@ } } }, - "extensionStrategy": "Eşleştirme Stratejisi: {strategy}", + "extensionStrategy": "Strateji: {strategy}", "@extensionStrategy": { "description": "Track matching strategy name", "placeholders": { @@ -1777,27 +1849,27 @@ "@extensionsProviderPrioritySection": { "description": "Section header - provider priority" }, - "extensionsInstalledSection": "Yüklü Eklentiler", + "extensionsInstalledSection": "Kurulu uzantılar", "@extensionsInstalledSection": { "description": "Section header - installed extensions" }, - "extensionsNoExtensions": "Henüz eklenti yüklenmemiş", + "extensionsNoExtensions": "Hiçbir eklenti kurulmamış", "@extensionsNoExtensions": { "description": "Empty state - no extensions" }, - "extensionsNoExtensionsSubtitle": "Yeni müzik kaynakları eklemek için .spotiflac-ext dosyalarını yükleyin", + "extensionsNoExtensionsSubtitle": "Yeni sağlayıcılar eklemek için .spotiflac-ext dosyalarını yükleyin", "@extensionsNoExtensionsSubtitle": { "description": "Empty state subtitle" }, - "extensionsInstallButton": "Eklenti Yükle", + "extensionsInstallButton": "Uzantı Yükle", "@extensionsInstallButton": { "description": "Button to install extension from file" }, - "extensionsInfoTip": "Eklentiler yeni veri ve indirme kaynakları ekleyebilir. Lütfen eklentileri sadece güvendiğiniz kaynaklardan yükleyin.", + "extensionsInfoTip": "Uzantılar yeni meta veri ve indirme sağlayıcıları ekleyebilir. Yalnızca güvenilir kaynaklardan gelen uzantıları yükleyin.", "@extensionsInfoTip": { "description": "Security warning about extensions" }, - "extensionsInstalledSuccess": "Eklenti başarıyla yüklendi", + "extensionsInstalledSuccess": "Uzantı başarıyla yüklendi", "@extensionsInstalledSuccess": { "description": "Success message after install" }, @@ -1805,35 +1877,43 @@ "@extensionsDownloadPriority": { "description": "Setting - download provider order" }, - "extensionsDownloadPrioritySubtitle": "İndirme servislerinin deneneceği sırayı belirleyin", + "extensionsDownloadPrioritySubtitle": "İndirme servisi sırasını ayarla", "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, - "extensionsNoDownloadProvider": "İndirme sağlayıcısı barındıran bir eklenti yok", + "extensionsFallbackTitle": "Yedekleme Uzantıları", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Hangi yüklü indirme uzantılarının yedekleme olarak kullanılabileceğini seçin", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, + "extensionsNoDownloadProvider": "İndirme sağlayıcısı olan uzantı yok", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" }, - "extensionsMetadataPriority": "Arama Kaynağı Önceliği", + "extensionsMetadataPriority": "Meta Veri Önceliği", "@extensionsMetadataPriority": { "description": "Setting - metadata provider order" }, - "extensionsMetadataPrioritySubtitle": "Arama ve veri kaynaklarının sırasını belirleyin", + "extensionsMetadataPrioritySubtitle": "Arama ve meta veri kaynağı sırasını ayarla", "@extensionsMetadataPrioritySubtitle": { "description": "Subtitle for metadata priority" }, - "extensionsNoMetadataProvider": "Şarkı verisi (metadata) barındıran bir eklenti yok", + "extensionsNoMetadataProvider": "Meta veri sağlayıcısı içeren uzantı bulunamadı", "@extensionsNoMetadataProvider": { "description": "Empty state - no metadata providers" }, - "extensionsSearchProvider": "Arama Servisi", + "extensionsSearchProvider": "Arama Sağlayıcısı", "@extensionsSearchProvider": { "description": "Setting - search provider selection" }, - "extensionsNoCustomSearch": "Özel arama özelliği olan bir eklenti yok", + "extensionsNoCustomSearch": "Özel arama içeren uzantı bulunamadı", "@extensionsNoCustomSearch": { "description": "Empty state - no search providers" }, - "extensionsSearchProviderDescription": "Şarkı aramak için kullanılacak servisi seçin", + "extensionsSearchProviderDescription": "Parça aramak için hangi servisin kullanılacağını seçin", "@extensionsSearchProviderDescription": { "description": "Search provider setting description" }, @@ -1841,7 +1921,7 @@ "@extensionsCustomSearch": { "description": "Label for custom search provider" }, - "extensionsErrorLoading": "Eklenti yüklenirken hata oluştu", + "extensionsErrorLoading": "Uzantı yüklenirken hata oluştu", "@extensionsErrorLoading": { "description": "Error message when extension fails to load" }, @@ -1853,7 +1933,7 @@ "@qualityFlacLosslessSubtitle": { "description": "Technical spec for lossless" }, - "qualityHiResFlac": "Hi-Res FLAC (Yüksek Çözünürlüklü)", + "qualityHiResFlac": "Hi-Res FLAC", "@qualityHiResFlac": { "description": "Quality option - high resolution FLAC" }, @@ -1861,7 +1941,7 @@ "@qualityHiResFlacSubtitle": { "description": "Technical spec for hi-res" }, - "qualityHiResFlacMax": "Hi-Res FLAC Maksimum", + "qualityHiResFlacMax": "Hi-Res FLAC Max", "@qualityHiResFlacMax": { "description": "Quality option - maximum resolution FLAC" }, @@ -1869,19 +1949,19 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, - "downloadLossy320": "Kayıplı (Lossy) 320kbps", + "downloadLossy320": "Kayıplı 320kbps", "@downloadLossy320": { "description": "Quality option label for Tidal lossy 320kbps" }, - "downloadLossyFormat": "Kayıplı Formatı", + "downloadLossyFormat": "Kayıplı Format", "@downloadLossyFormat": { "description": "Setting title to pick output format for Tidal lossy downloads" }, - "downloadLossy320Format": "Kayıplı (Lossy) 320kbps Formatı", + "downloadLossy320Format": "Kayıplı 320kbps Formatı", "@downloadLossy320Format": { "description": "Title of the Tidal lossy format picker bottom sheet" }, - "downloadLossy320FormatDesc": "Tidal'dan 320kbps kalitesinde indirirken kullanılacak formatı seçin. Orijinal AAC yayını seçtiğiniz formata dönüştürülecektir.", + "downloadLossy320FormatDesc": "Tidal 320kbps kayıplı indirmeler için çıktı formatını seçin. Orijinal AAC akışı seçtiğiniz formata dönüştürülecektir.", "@downloadLossy320FormatDesc": { "description": "Description in the Tidal lossy format picker" }, @@ -1889,7 +1969,7 @@ "@downloadLossyMp3": { "description": "Tidal lossy format option - MP3 320kbps" }, - "downloadLossyMp3Subtitle": "En iyi uyumluluk, şarkı başı ~10MB", + "downloadLossyMp3Subtitle": "En iyi uyumluluk, parça başına ~10 Mb", "@downloadLossyMp3Subtitle": { "description": "Subtitle for MP3 320kbps Tidal lossy option" }, @@ -1897,7 +1977,7 @@ "@downloadLossyOpus256": { "description": "Tidal lossy format option - Opus 256kbps" }, - "downloadLossyOpus256Subtitle": "En iyi Opus kalitesi, şarkı başı ~8MB", + "downloadLossyOpus256Subtitle": "En iyi Opus kalitesi, parça başına ~8 Mb", "@downloadLossyOpus256Subtitle": { "description": "Subtitle for Opus 256kbps Tidal lossy option" }, @@ -1905,11 +1985,11 @@ "@downloadLossyOpus128": { "description": "Tidal lossy format option - Opus 128kbps" }, - "downloadLossyOpus128Subtitle": "En küçük boyut, şarkı başı ~4MB", + "downloadLossyOpus128Subtitle": "En küçük boyut, parça başına ~4 Mb", "@downloadLossyOpus128Subtitle": { "description": "Subtitle for Opus 128kbps Tidal lossy option" }, - "qualityNote": "Gerçek kalite, şarkının serviste hangi kalitede bulunduğuna bağlıdır.", + "qualityNote": "Gerçek kalite, parçanın servisteki uygunluğuna bağlıdır", "@qualityNote": { "description": "Note about quality availability" }, @@ -1917,47 +1997,47 @@ "@downloadAskBeforeDownload": { "description": "Setting - show quality picker" }, - "downloadDirectory": "İndirme Klasörü", + "downloadDirectory": "İndirme Dizini", "@downloadDirectory": { "description": "Setting - download folder" }, - "downloadSeparateSinglesFolder": "Single'ları Ayrı Klasöre Koy", + "downloadSeparateSinglesFolder": "Ayrı Single Klasörü", "@downloadSeparateSinglesFolder": { "description": "Setting - separate folder for singles" }, - "downloadAlbumFolderStructure": "Albüm Klasörü Düzeni", + "downloadAlbumFolderStructure": "Albüm Klasör Yapısı", "@downloadAlbumFolderStructure": { "description": "Setting - album folder organization" }, - "downloadUseAlbumArtistForFolders": "Klasörler için Albüm Sanatçısını Kullan", + "downloadUseAlbumArtistForFolders": "Klasörler için Albüm Sanatçısı'nı kullan", "@downloadUseAlbumArtistForFolders": { "description": "Setting - choose whether artist folders use Album Artist or Track Artist" }, - "downloadUsePrimaryArtistOnly": "Klasörlerde Sadece Ana Sanatçı (Düetleri Gizle)", + "downloadUsePrimaryArtistOnly": "Klasörler için yalnızca birincil sanatçıyı kullan", "@downloadUsePrimaryArtistOnly": { "description": "Setting - strip featured artists from folder name" }, - "downloadUsePrimaryArtistOnlyEnabled": "Konuk sanatçılar klasör adından silinir (Örn: Justin Bieber, Quavo → Justin Bieber)", + "downloadUsePrimaryArtistOnlyEnabled": "Düet sanatçıları klasör adından kaldırılır (örn. Justin Bieber, Quavo → Justin Bieber)", "@downloadUsePrimaryArtistOnlyEnabled": { "description": "Subtitle when primary artist only is enabled" }, - "downloadUsePrimaryArtistOnlyDisabled": "Klasör adına tüm sanatçılar yazılır", + "downloadUsePrimaryArtistOnlyDisabled": "Klasör adı için tam sanatçı dizesi kullanılır", "@downloadUsePrimaryArtistOnlyDisabled": { "description": "Subtitle when primary artist only is disabled" }, - "downloadSelectQuality": "Kaliteyi Seçin", + "downloadSelectQuality": "Kalite seçin", "@downloadSelectQuality": { "description": "Dialog title - choose audio quality" }, - "downloadFrom": "İndirme Kaynağı:", + "downloadFrom": "İndirme Kaynağı", "@downloadFrom": { "description": "Label - download source" }, - "appearanceAmoledDark": "AMOLED Koyu (Tam Siyah)", + "appearanceAmoledDark": "AMOLED Koyu", "@appearanceAmoledDark": { "description": "Theme option - pure black" }, - "appearanceAmoledDarkSubtitle": "Tamamen siyah arka plan (OLED ekranlar için)", + "appearanceAmoledDarkSubtitle": "Saf siyah arka plan", "@appearanceAmoledDarkSubtitle": { "description": "Subtitle for AMOLED dark" }, @@ -1965,31 +2045,31 @@ "@queueClearAll": { "description": "Button - clear all queue items" }, - "queueClearAllMessage": "Tüm indirme sırasını temizlemek istediğinize emin misiniz?", + "queueClearAllMessage": "Tüm indirmeleri temizlemek istediğinizden emin misiniz?", "@queueClearAllMessage": { "description": "Clear queue confirmation" }, - "settingsAutoExportFailed": "Başarısız İndirmeleri Otomatik Dışa Aktar", + "settingsAutoExportFailed": "Başarısız indirmeleri otomatik dışa aktar", "@settingsAutoExportFailed": { "description": "Setting toggle for auto-export" }, - "settingsAutoExportFailedSubtitle": "İndirilemeyen şarkıların listesini TXT dosyası olarak kaydeder", + "settingsAutoExportFailedSubtitle": "Başarısız indirmeleri otomatik olarak TXT dosyasına kaydet", "@settingsAutoExportFailedSubtitle": { "description": "Subtitle for auto-export setting" }, - "settingsDownloadNetwork": "İndirme İçin Kullanılacak Ağ", + "settingsDownloadNetwork": "İndirme Ağı", "@settingsDownloadNetwork": { "description": "Setting for network type preference" }, - "settingsDownloadNetworkAny": "Wi-Fi + Mobil Veri", + "settingsDownloadNetworkAny": "WiFi + Mobil Veri", "@settingsDownloadNetworkAny": { "description": "Network option - use any connection" }, - "settingsDownloadNetworkWifiOnly": "Sadece Wi-Fi", + "settingsDownloadNetworkWifiOnly": "Yalnızca WiFi", "@settingsDownloadNetworkWifiOnly": { "description": "Network option - only use WiFi" }, - "settingsDownloadNetworkSubtitle": "Sadece Wi-Fi seçildiğinde, mobil verideyken indirmeler otomatik duraklatılır.", + "settingsDownloadNetworkSubtitle": "İndirmeler için hangi ağın kullanılacağını seçin. Yalnızca WiFi olarak ayarlandığında, mobil veriye geçildiğinde indirmeler duraklatılır.", "@settingsDownloadNetworkSubtitle": { "description": "Subtitle explaining network preference" }, @@ -2009,7 +2089,7 @@ "@albumFolderArtistYearAlbumSubtitle": { "description": "Folder structure example" }, - "albumFolderAlbumOnly": "Sadece Albüm", + "albumFolderAlbumOnly": "Yalnızca Albüm", "@albumFolderAlbumOnly": { "description": "Album folder option" }, @@ -2025,19 +2105,19 @@ "@albumFolderYearAlbumSubtitle": { "description": "Folder structure example" }, - "albumFolderArtistAlbumSingles": "Sanatçı / Albüm + Single'lar", + "albumFolderArtistAlbumSingles": "Sanatçı / Albüm + Singlelar", "@albumFolderArtistAlbumSingles": { "description": "Album folder option with singles inside artist" }, - "albumFolderArtistAlbumSinglesSubtitle": "Sanatçı/Albüm/ ve Sanatçı/Single'lar/", + "albumFolderArtistAlbumSinglesSubtitle": "Sanatçı/Albüm/ ve Sanatçı/Singlelar/", "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, - "albumFolderArtistAlbumFlat": "Sanatçı / Albüm (Single'lar ayrı klasörsüz)", + "albumFolderArtistAlbumFlat": "Sanatçı / Albüm (Singlelar alt klasörsüz)", "@albumFolderArtistAlbumFlat": { "description": "Album folder option with singles directly in artist folder" }, - "albumFolderArtistAlbumFlatSubtitle": "Sanatçı/Albüm/ ve Sanatçı/sarki.flac", + "albumFolderArtistAlbumFlatSubtitle": "Sanatçı/Albüm/ ve Sanatçı/şarkı.flac", "@albumFolderArtistAlbumFlatSubtitle": { "description": "Folder structure example for flat singles" }, @@ -2045,7 +2125,7 @@ "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" }, - "downloadedAlbumDeleteMessage": "Bu albümden {count} {count, plural, =1{şarkı} other{şarkı}} silinsin mi?\n\nBu işlem, dosyaları cihazınızdan da tamamen silecek.", + "downloadedAlbumDeleteMessage": "Bu albümden {count} {count, plural, one {}=1{parça} other{parça}} parça silinsin mi?\n\nBu işlem dosyaları depolama alanından da kalıcı olarak silecektir.", "@downloadedAlbumDeleteMessage": { "description": "Delete confirmation with count", "placeholders": { @@ -2063,15 +2143,15 @@ } } }, - "downloadedAlbumAllSelected": "Tüm şarkılar seçildi", + "downloadedAlbumAllSelected": "Tüm parçalar seçildi", "@downloadedAlbumAllSelected": { "description": "Status - all items selected" }, - "downloadedAlbumTapToSelect": "Seçmek için şarkılara dokunun", + "downloadedAlbumTapToSelect": "Seçmek için parçalara dokunun", "@downloadedAlbumTapToSelect": { "description": "Selection hint" }, - "downloadedAlbumDeleteCount": "{count} {count, plural, =1{Şarkıyı} other{Şarkıyı}} Sil", + "downloadedAlbumDeleteCount": "{count} {count, plural, one {}=1{parçayı} other{parçayı}} sil", "@downloadedAlbumDeleteCount": { "description": "Delete button text with count", "placeholders": { @@ -2080,7 +2160,7 @@ } } }, - "downloadedAlbumSelectToDelete": "Silinecek şarkıları seçin", + "downloadedAlbumSelectToDelete": "Silinecek parçaları seçin", "@downloadedAlbumSelectToDelete": { "description": "Placeholder when nothing selected" }, @@ -2110,7 +2190,7 @@ "@recentTypePlaylist": { "description": "Recent access item type - playlist" }, - "recentEmpty": "Henüz yeni bir arama yok", + "recentEmpty": "Henüz son kullanılan öğe yok", "@recentEmpty": { "description": "Empty state text for recent access list" }, @@ -2128,7 +2208,7 @@ } } }, - "discographyDownload": "Tüm Diskografiyi İndir", + "discographyDownload": "Diskografiyi İndir", "@discographyDownload": { "description": "Button - download artist discography" }, @@ -2136,7 +2216,7 @@ "@discographyDownloadAll": { "description": "Option - download entire discography" }, - "discographyDownloadAllSubtitle": "{albumCount} albüm/single üzerinden toplam {count} şarkı", + "discographyDownloadAllSubtitle": "{albumCount} yayından {count} parça", "@discographyDownloadAllSubtitle": { "description": "Subtitle showing total tracks and albums", "placeholders": { @@ -2148,11 +2228,11 @@ } } }, - "discographyAlbumsOnly": "Sadece Albümler", + "discographyAlbumsOnly": "Yalnızca Albümler", "@discographyAlbumsOnly": { "description": "Option - download only albums" }, - "discographyAlbumsOnlySubtitle": "{albumCount} albümden toplam {count} şarkı", + "discographyAlbumsOnlySubtitle": "{albumCount} albümden {count} parça", "@discographyAlbumsOnlySubtitle": { "description": "Subtitle showing album tracks count", "placeholders": { @@ -2164,11 +2244,11 @@ } } }, - "discographySinglesOnly": "Sadece Single'lar ve EP'ler", + "discographySinglesOnly": "Yalnızca Single'lar ve EP'ler", "@discographySinglesOnly": { "description": "Option - download only singles" }, - "discographySinglesOnlySubtitle": "{albumCount} single üzerinden toplam {count} şarkı", + "discographySinglesOnlySubtitle": "{albumCount} tekliden {count} parça", "@discographySinglesOnlySubtitle": { "description": "Subtitle showing singles tracks count", "placeholders": { @@ -2184,15 +2264,15 @@ "@discographySelectAlbums": { "description": "Option - manually select albums to download" }, - "discographySelectAlbumsSubtitle": "İstediğiniz albümleri veya single'ları kendiniz seçin", + "discographySelectAlbumsSubtitle": "Belirli albümleri veya single'ları seçin", "@discographySelectAlbumsSubtitle": { "description": "Subtitle for select albums option" }, - "discographyFetchingTracks": "Şarkılar alınıyor...", + "discographyFetchingTracks": "Parçalar getiriliyor...", "@discographyFetchingTracks": { "description": "Progress - fetching album tracks" }, - "discographyFetchingAlbum": "Alınıyor: {current} / {total}...", + "discographyFetchingAlbum": "{total} üzerinden {current} getiriliyor...", "@discographyFetchingAlbum": { "description": "Progress - fetching specific album", "placeholders": { @@ -2217,7 +2297,7 @@ "@discographyDownloadSelected": { "description": "Button - download selected albums" }, - "discographyAddedToQueue": "{count} şarkı indirme sırasına eklendi", + "discographyAddedToQueue": "{count} parça kuyruğa eklendi", "@discographyAddedToQueue": { "description": "Snackbar - tracks added from discography", "placeholders": { @@ -2226,7 +2306,7 @@ } } }, - "discographySkippedDownloaded": "{added} şarkı eklendi, zaten inmiş olan {skipped} şarkı atlandı", + "discographySkippedDownloaded": "{added} eklendi, {skipped} zaten indirilmiş", "@discographySkippedDownloaded": { "description": "Snackbar - with skipped tracks count", "placeholders": { @@ -2238,11 +2318,11 @@ } } }, - "discographyNoAlbums": "Bu sanatçıya ait albüm bulunamadı", + "discographyNoAlbums": "Kullanılabilir albüm yok", "@discographyNoAlbums": { "description": "Error - no albums found for artist" }, - "discographyFailedToFetch": "Bazı albümler yüklenemedi", + "discographyFailedToFetch": "Bazı albümler getirilemedi", "@discographyFailedToFetch": { "description": "Error - some albums failed to load" }, @@ -2254,23 +2334,23 @@ "@allFilesAccess": { "description": "Toggle for MANAGE_EXTERNAL_STORAGE permission" }, - "allFilesAccessEnabledSubtitle": "Cihazdaki herhangi bir klasöre yazabilir", + "allFilesAccessEnabledSubtitle": "Herhangi bir klasöre yazabilir", "@allFilesAccessEnabledSubtitle": { "description": "Subtitle when all files access is enabled" }, - "allFilesAccessDisabledSubtitle": "Sadece medya klasörleriyle sınırlı", + "allFilesAccessDisabledSubtitle": "Yalnızca medya klasörleriyle sınırlı", "@allFilesAccessDisabledSubtitle": { "description": "Subtitle when all files access is disabled" }, - "allFilesAccessDescription": "Özel klasörlere kaydederken yazma hatası alıyorsanız bunu açın. Android 13 ve sonrasında bazı klasörlere erişim varsayılan olarak kısıtlanmıştır.", + "allFilesAccessDescription": "Özel klasörlere kaydederken yazma hatalarıyla karşılaşırsanız bunu etkinleştirin. Android 13 ve üzeri, varsayılan olarak belirli dizinlere erişimi kısıtlar.", "@allFilesAccessDescription": { "description": "Description explaining when to enable all files access" }, - "allFilesAccessDeniedMessage": "İzin reddedildi. Lütfen sistem ayarlarından 'Tüm dosyalara erişim' iznini manuel olarak verin.", + "allFilesAccessDeniedMessage": "İzin reddedildi. Lütfen sistem ayarlarından 'Tüm dosyalara erişim' iznini manuel olarak etkinleştirin.", "@allFilesAccessDeniedMessage": { "description": "Message when permission is permanently denied" }, - "allFilesAccessDisabledMessage": "Tüm Dosyalara Erişim devre dışı. Uygulama sınırlı depolama izniyle çalışacak.", + "allFilesAccessDisabledMessage": "Tüm Dosyalara Erişim devre dışı bırakıldı. Uygulama kısıtlı depolama erişimi kullanacak.", "@allFilesAccessDisabledMessage": { "description": "Snackbar message when user disables all files access" }, @@ -2278,15 +2358,15 @@ "@settingsLocalLibrary": { "description": "Settings menu item - local library" }, - "settingsLocalLibrarySubtitle": "Telefonunuzdaki müzikleri tarayıp kopyaları bulun", + "settingsLocalLibrarySubtitle": "Müziği tara ve kopyaları tespit et", "@settingsLocalLibrarySubtitle": { "description": "Subtitle for local library settings" }, - "settingsCache": "Önbellek ve Depolama", + "settingsCache": "Depolama ve Önbellek", "@settingsCache": { "description": "Settings menu item - cache management" }, - "settingsCacheSubtitle": "Boyutu görüntüleyin ve gereksiz dosyaları temizleyin", + "settingsCacheSubtitle": "Boyutu görüntüle ve önbelleğe alınmış verileri temizle", "@settingsCacheSubtitle": { "description": "Subtitle for cache management menu" }, @@ -2298,15 +2378,15 @@ "@libraryScanSettings": { "description": "Section header for scan settings" }, - "libraryEnableLocalLibrary": "Yerel Kitaplık Taramasını Aç", + "libraryEnableLocalLibrary": "Yerel Kitaplığı Etkinleştir", "@libraryEnableLocalLibrary": { "description": "Toggle to enable library scanning" }, - "libraryEnableLocalLibrarySubtitle": "İndirme yaparken elinizde olan şarkıları takip eder", + "libraryEnableLocalLibrarySubtitle": "Mevcut müziğinizi tarayın ve takip edin", "@libraryEnableLocalLibrarySubtitle": { "description": "Subtitle for enable toggle" }, - "libraryFolder": "Taranacak Klasör", + "libraryFolder": "Kitaplık Klasörü", "@libraryFolder": { "description": "Folder selection setting" }, @@ -2314,11 +2394,11 @@ "@libraryFolderHint": { "description": "Placeholder when no folder selected" }, - "libraryShowDuplicateIndicator": "Kopya İndikatörünü Göster", + "libraryShowDuplicateIndicator": "Kopya Belirtecini Göster", "@libraryShowDuplicateIndicator": { "description": "Toggle for duplicate indicator in search" }, - "libraryShowDuplicateIndicatorSubtitle": "Zaten indirmiş olduğunuz şarkıların yanında belirteç gösterir", + "libraryShowDuplicateIndicatorSubtitle": "Mevcut parçalar aranırken göster", "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, @@ -2326,7 +2406,7 @@ "@libraryAutoScan": { "description": "Setting for automatic library scanning" }, - "libraryAutoScanSubtitle": "Cihazınıza yeni eklenen müzikleri otomatik olarak bulur", + "libraryAutoScanSubtitle": "Kitaplığınızı yeni dosyalar için otomatik olarak tarayın", "@libraryAutoScanSubtitle": { "description": "Subtitle for auto scan setting" }, @@ -2334,19 +2414,19 @@ "@libraryAutoScanOff": { "description": "Auto scan disabled" }, - "libraryAutoScanOnOpen": "Uygulama her açıldığında", + "libraryAutoScanOnOpen": "Her uygulama açılışında", "@libraryAutoScanOnOpen": { "description": "Auto scan when app opens" }, - "libraryAutoScanDaily": "Günde bir", + "libraryAutoScanDaily": "Günlük", "@libraryAutoScanDaily": { "description": "Auto scan once per day" }, - "libraryAutoScanWeekly": "Haftada bir", + "libraryAutoScanWeekly": "Haftalık", "@libraryAutoScanWeekly": { "description": "Auto scan once per week" }, - "libraryActions": "İşlemler", + "libraryActions": "Eylemler", "@libraryActions": { "description": "Section header for library actions" }, @@ -2354,11 +2434,11 @@ "@libraryScan": { "description": "Button to start library scan" }, - "libraryScanSubtitle": "Klasördeki müzik dosyalarını tarar", + "libraryScanSubtitle": "Ses dosyaları için tara", "@libraryScanSubtitle": { "description": "Subtitle for scan button" }, - "libraryScanSelectFolderFirst": "Lütfen önce taranacak bir klasör seçin", + "libraryScanSelectFolderFirst": "Önce bir klasör seçin", "@libraryScanSelectFolderFirst": { "description": "Message when trying to scan without folder" }, @@ -2366,35 +2446,35 @@ "@libraryCleanupMissingFiles": { "description": "Button to remove entries for missing files" }, - "libraryCleanupMissingFilesSubtitle": "Artık cihazınızda olmayan dosyaların kayıtlarını kaldırır", + "libraryCleanupMissingFilesSubtitle": "Eski dosya kalıntılarını temizleyin", "@libraryCleanupMissingFilesSubtitle": { "description": "Subtitle for cleanup button" }, - "libraryClear": "Kitaplığı Temizle", + "libraryClear": "Kitaplığı temizle", "@libraryClear": { "description": "Button to clear all library entries" }, - "libraryClearSubtitle": "Taranmış tüm şarkı kayıtlarını sıfırlar", + "libraryClearSubtitle": "Taranan tüm parçaları sil", "@libraryClearSubtitle": { "description": "Subtitle for clear button" }, - "libraryClearConfirmTitle": "Kitaplık Temizlensin mi?", + "libraryClearConfirmTitle": "Kütüphaneyi temizle", "@libraryClearConfirmTitle": { "description": "Dialog title for clear confirmation" }, - "libraryClearConfirmMessage": "Uygulamanın kaydettiği tüm taranmış şarkı verileri silinecek. (Gerçek müzik dosyalarınız SİLİNMEYECEK).", + "libraryClearConfirmMessage": "Bu işlem, kitaplığınızdaki tüm taranmış parçaları siler. Asıl müzik dosyalarınız silinmez.", "@libraryClearConfirmMessage": { "description": "Dialog message for clear confirmation" }, - "libraryAbout": "Yerel Kitaplık Hakkında", + "libraryAbout": "Yerel Kütüphane Hakkında", "@libraryAbout": { "description": "Section header for about info" }, - "libraryAboutDescription": "İndirme yaparken kopyaları (zaten inmiş olanları) tespit etmek için mevcut müzik arşivinizi tarar. FLAC, M4A, MP3, Opus ve OGG formatlarını destekler. Bilgiler şarkı dosyalarının kendi etiketlerinden (ID3 tag vb.) okunur.", + "libraryAboutDescription": "İndirme işlemi sırasında mevcut müzik koleksiyonunuzu tarayarak yinelenen dosyaları tespit eder. FLAC, M4A, MP3, Opus ve OGG formatlarını destekler. Varsa, meta veriler dosya etiketlerinden okunur.", "@libraryAboutDescription": { "description": "Description of local library feature" }, - "libraryTracksUnit": "{count, plural, =1{şarkı} other{şarkı}}", + "libraryTracksUnit": "{count, plural, =1{track} other{tracks}}", "@libraryTracksUnit": { "description": "Unit label for tracks count (without the number itself)", "placeholders": { @@ -2403,7 +2483,16 @@ } } }, - "libraryLastScanned": "Son tarama: {time}", + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", "placeholders": { @@ -2412,15 +2501,19 @@ } } }, - "libraryLastScannedNever": "Hiç taranmadı", + "libraryLastScannedNever": "Never", "@libraryLastScannedNever": { "description": "Shown when library has never been scanned" }, - "libraryScanning": "Taranıyor...", + "libraryScanning": "Scanning...", "@libraryScanning": { "description": "Status during scan" }, - "libraryScanProgress": "%{progress} (Toplam {total} dosya)", + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, + "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", "placeholders": { @@ -2432,11 +2525,11 @@ } } }, - "libraryInLibrary": "Cihazda Var", + "libraryInLibrary": "In Library", "@libraryInLibrary": { "description": "Badge shown on tracks that exist in local library" }, - "libraryRemovedMissingFiles": "Cihazda olmayan {count} dosyanın kaydı temizlendi", + "libraryRemovedMissingFiles": "Removed {count} missing files from library", "@libraryRemovedMissingFiles": { "description": "Snackbar after cleanup", "placeholders": { @@ -2445,39 +2538,39 @@ } } }, - "libraryCleared": "Kitaplık kayıtları temizlendi", + "libraryCleared": "Library cleared", "@libraryCleared": { "description": "Snackbar after clearing library" }, - "libraryStorageAccessRequired": "Depolama İzni Gerekli", + "libraryStorageAccessRequired": "Storage Access Required", "@libraryStorageAccessRequired": { "description": "Dialog title for storage permission" }, - "libraryStorageAccessMessage": "Müzik kitaplığınızı taramak için SpotiFLAC'ın depolama iznine ihtiyacı var. Lütfen ayarlardan izin verin.", + "libraryStorageAccessMessage": "SpotiFLAC needs storage access to scan your music library. Please grant permission in settings.", "@libraryStorageAccessMessage": { "description": "Dialog message for storage permission" }, - "libraryFolderNotExist": "Seçilen klasör artık mevcut değil", + "libraryFolderNotExist": "Selected folder does not exist", "@libraryFolderNotExist": { "description": "Error when folder doesn't exist" }, - "librarySourceDownloaded": "İndirildi", + "librarySourceDownloaded": "Downloaded", "@librarySourceDownloaded": { "description": "Badge for tracks downloaded via SpotiFLAC" }, - "librarySourceLocal": "Cihazdan", + "librarySourceLocal": "Local", "@librarySourceLocal": { "description": "Badge for tracks from local library scan" }, - "libraryFilterAll": "Tümü", + "libraryFilterAll": "All", "@libraryFilterAll": { "description": "Filter chip - show all library items" }, - "libraryFilterDownloaded": "Uygulama İle İndirilenler", + "libraryFilterDownloaded": "Downloaded", "@libraryFilterDownloaded": { "description": "Filter chip - show only downloaded items" }, - "libraryFilterLocal": "Yerel Dosyalar", + "libraryFilterLocal": "Local", "@libraryFilterLocal": { "description": "Filter chip - show only local library items" }, @@ -2485,31 +2578,31 @@ "@libraryFilterTitle": { "description": "Filter bottom sheet title" }, - "libraryFilterReset": "Sıfırla", + "libraryFilterReset": "Reset", "@libraryFilterReset": { "description": "Reset all filters button" }, - "libraryFilterApply": "Uygula", + "libraryFilterApply": "Apply", "@libraryFilterApply": { "description": "Apply filters button" }, - "libraryFilterSource": "Kaynak", + "libraryFilterSource": "Source", "@libraryFilterSource": { "description": "Filter section - source type" }, - "libraryFilterQuality": "Kalite", + "libraryFilterQuality": "Quality", "@libraryFilterQuality": { "description": "Filter section - audio quality" }, - "libraryFilterQualityHiRes": "Hi-Res (24-bit)", + "libraryFilterQualityHiRes": "Hi-Res (24bit)", "@libraryFilterQualityHiRes": { "description": "Filter option - high resolution audio" }, - "libraryFilterQualityCD": "CD Kalitesi (16-bit)", + "libraryFilterQualityCD": "CD (16bit)", "@libraryFilterQualityCD": { "description": "Filter option - CD quality audio" }, - "libraryFilterQualityLossy": "Kayıplı (Lossy)", + "libraryFilterQualityLossy": "Lossy", "@libraryFilterQualityLossy": { "description": "Filter option - lossy compressed audio" }, @@ -2517,23 +2610,63 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, - "libraryFilterSort": "Sıralama", + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, + "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" }, - "libraryFilterSortLatest": "En Yeniler", + "libraryFilterSortLatest": "Latest", "@libraryFilterSortLatest": { "description": "Sort option - newest first" }, - "libraryFilterSortOldest": "En Eskiler", + "libraryFilterSortOldest": "Oldest", "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, - "timeJustNow": "Az önce", + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, + "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" }, - "timeMinutesAgo": "{count, plural, =1{1 dakika önce} other{{count} dakika önce}}", + "timeMinutesAgo": "{count, plural, =1{1 minute ago} other{{count} minutes ago}}", "@timeMinutesAgo": { "description": "Relative time - minutes ago", "placeholders": { @@ -2542,7 +2675,7 @@ } } }, - "timeHoursAgo": "{count, plural, =1{1 saat önce} other{{count} saat önce}}", + "timeHoursAgo": "{count, plural, =1{1 hour ago} other{{count} hours ago}}", "@timeHoursAgo": { "description": "Relative time - hours ago", "placeholders": { @@ -2551,123 +2684,123 @@ } } }, - "tutorialWelcomeTitle": "SpotiFLAC'a Hoş Geldiniz!", + "tutorialWelcomeTitle": "Welcome to SpotiFLAC!", "@tutorialWelcomeTitle": { "description": "Tutorial welcome page title" }, - "tutorialWelcomeDesc": "En sevdiğiniz müzikleri kayıpsız kalitede nasıl indireceğinizi öğrenelim. Bu kısa rehber size temelleri gösterecek.", + "tutorialWelcomeDesc": "En sevdiğiniz müzikleri kayıpsız kalitede nasıl indirebileceğinizi öğrenelim. Bu kısa eğitim size temel bilgileri gösterecek.", "@tutorialWelcomeDesc": { "description": "Tutorial welcome page description" }, - "tutorialWelcomeTip1": "Müzikleri bulmak için bir Spotify ya da Deezer bağlantısı yapıştırabilir veya adıyla arayabilirsiniz", + "tutorialWelcomeTip1": "Spotify, Deezer'dan müzik indirin veya desteklenen herhangi bir URL'yi yapıştırın", "@tutorialWelcomeTip1": { "description": "Tutorial welcome tip 1" }, - "tutorialWelcomeTip2": "Şarkıları Tidal, Qobuz veya Deezer altyapısıyla en yüksek kalitede (FLAC) indirin", + "tutorialWelcomeTip2": "Tidal, Qobuz veya Deezer'dan FLAC kalitesinde ses alın", "@tutorialWelcomeTip2": { "description": "Tutorial welcome tip 2" }, - "tutorialWelcomeTip3": "Albüm kapağı, şarkı sözleri ve tüm şarkı verileri dosyanın içine otomatik olarak gömülür", + "tutorialWelcomeTip3": "Otomatik meta veri, kapak resmi ve şarkı sözü gömme", "@tutorialWelcomeTip3": { "description": "Tutorial welcome tip 3" }, - "tutorialSearchTitle": "Müzik Bulmak Çok Kolay", + "tutorialSearchTitle": "Müzik Bulma", "@tutorialSearchTitle": { "description": "Tutorial search page title" }, - "tutorialSearchDesc": "İstediğiniz müzikleri bulmanın iki basit yolu var.", + "tutorialSearchDesc": "İndirmek istediğiniz müziği bulmanın iki kolay yolu vardır.", "@tutorialSearchDesc": { "description": "Tutorial search page description" }, - "tutorialDownloadTitle": "Müzikleri İndirme", + "tutorialDownloadTitle": "Müzik İndirme", "@tutorialDownloadTitle": { "description": "Tutorial download page title" }, - "tutorialDownloadDesc": "Şarkıları indirmek hızlı ve pürüzsüzdür. İşte süreç böyle işliyor:", + "tutorialDownloadDesc": "Müzik indirmek basit ve hızlıdır. İşte nasıl çalıştığı.", "@tutorialDownloadDesc": { "description": "Tutorial download page description" }, - "tutorialLibraryTitle": "Kişisel Kitaplığınız", + "tutorialLibraryTitle": "Kitaplığınız", "@tutorialLibraryTitle": { "description": "Tutorial library page title" }, - "tutorialLibraryDesc": "İndirdiğiniz tüm müzikler Kitaplık sekmesinde düzenli bir şekilde tutulur.", + "tutorialLibraryDesc": "İndirdiğiniz tüm müzikler Kitaplık sekmesinde düzenlenir.", "@tutorialLibraryDesc": { "description": "Tutorial library page description" }, - "tutorialLibraryTip1": "İndirme ilerlemenizi ve sırayı Kitaplık sekmesinden takip edin", + "tutorialLibraryTip1": "Kitaplık sekmesinden indirme ilerlemesini ve kuyruğu görüntüleyin", "@tutorialLibraryTip1": { "description": "Tutorial library tip 1" }, - "tutorialLibraryTip2": "İndirdiğiniz şarkıyı favori müzik çalarınızda açmak için üzerine dokunun", + "tutorialLibraryTip2": "Müzik çalarınızla oynatmak için herhangi bir parçaya dokunun", "@tutorialLibraryTip2": { "description": "Tutorial library tip 2" }, - "tutorialLibraryTip3": "Daha rahat göz atmak için liste ve ızgara görünümleri arasında geçiş yapın", + "tutorialLibraryTip3": "Daha iyi göz atmak için liste ve ızgara görünümü arasında geçiş yapın", "@tutorialLibraryTip3": { "description": "Tutorial library tip 3" }, - "tutorialExtensionsTitle": "Eklentilerle Güçlendirin", + "tutorialExtensionsTitle": "Uzantılar", "@tutorialExtensionsTitle": { "description": "Tutorial extensions page title" }, - "tutorialExtensionsDesc": "Topluluğun geliştirdiği eklentilerle uygulamanın sınırlarını aşın.", + "tutorialExtensionsDesc": "Topluluk uzantılarıyla uygulamanın yeteneklerini artırın.", "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "İlginizi çekebilecek eklentileri keşfetmek için Mağaza sekmesine göz atın", + "tutorialExtensionsTip1": "Faydalı uzantıları keşfetmek için Depo sekmesine göz atın", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, - "tutorialExtensionsTip2": "Uygulamaya yepyeni indirme ve arama kaynakları ekleyin", + "tutorialExtensionsTip2": "Yeni indirme sağlayıcıları veya arama kaynakları ekleyin", "@tutorialExtensionsTip2": { "description": "Tutorial extensions tip 2" }, - "tutorialExtensionsTip3": "Farklı şarkı sözü sağlayıcıları ve yepyeni özellikler kazanın", + "tutorialExtensionsTip3": "Şarkı sözleri, gelişmiş meta veriler ve daha fazla özellik edinin", "@tutorialExtensionsTip3": { "description": "Tutorial extensions tip 3" }, - "tutorialSettingsTitle": "Deneyiminizi Kişiselleştirin", + "tutorialSettingsTitle": "Deneyiminizi Özelleştirin", "@tutorialSettingsTitle": { "description": "Tutorial settings page title" }, - "tutorialSettingsDesc": "Uygulamanın nasıl davranacağını Ayarlar menüsünden zevkinize göre özelleştirin.", + "tutorialSettingsDesc": "Uygulamayı Ayarlar'dan tercihlerinize göre kişiselleştirin.", "@tutorialSettingsDesc": { "description": "Tutorial settings page description" }, - "tutorialSettingsTip1": "İndirme konumunu ve klasörleme biçimini değiştirin", + "tutorialSettingsTip1": "İndirme konumunu ve klasör düzenini değiştirin", "@tutorialSettingsTip1": { "description": "Tutorial settings tip 1" }, - "tutorialSettingsTip2": "Varsayılan ses kalitesini ve indirme formatınızı belirleyin", + "tutorialSettingsTip2": "Varsayılan ses kalitesi ve format tercihlerini ayarlayın", "@tutorialSettingsTip2": { "description": "Tutorial settings tip 2" }, - "tutorialSettingsTip3": "Temayı, renkleri ve uygulamanın görünümünü ayarlayın", + "tutorialSettingsTip3": "Customize app theme and appearance", "@tutorialSettingsTip3": { "description": "Tutorial settings tip 3" }, - "tutorialReadyMessage": "İşte bu kadar! Artık favori müziklerinizi indirmeye hazırsınız.", + "tutorialReadyMessage": "You're all set! Start downloading your favorite music now.", "@tutorialReadyMessage": { "description": "Tutorial completion message" }, - "libraryForceFullScan": "Tam Taramaya Zorla", + "libraryForceFullScan": "Force Full Scan", "@libraryForceFullScan": { "description": "Button to force a complete rescan of library" }, - "libraryForceFullScanSubtitle": "Önbelleği yoksayarak klasördeki tüm dosyaları baştan tarar", + "libraryForceFullScanSubtitle": "Rescan all files, ignoring cache", "@libraryForceFullScanSubtitle": { "description": "Subtitle for force full scan button" }, - "cleanupOrphanedDownloads": "Geçersiz İndirmeleri Temizle", + "cleanupOrphanedDownloads": "Cleanup Orphaned Downloads", "@cleanupOrphanedDownloads": { "description": "Button to remove history entries for deleted files" }, - "cleanupOrphanedDownloadsSubtitle": "Cihazdan silinmiş dosyalara ait eski geçmiş kayıtlarını kaldırır", + "cleanupOrphanedDownloadsSubtitle": "Remove history entries for files that no longer exist", "@cleanupOrphanedDownloadsSubtitle": { "description": "Subtitle for orphaned cleanup button" }, - "cleanupOrphanedDownloadsResult": "Geçmişten {count} geçersiz kayıt kaldırıldı", + "cleanupOrphanedDownloadsResult": "Removed {count} orphaned entries from history", "@cleanupOrphanedDownloadsResult": { "description": "Snackbar after orphan cleanup", "placeholders": { @@ -2676,23 +2809,23 @@ } } }, - "cleanupOrphanedDownloadsNone": "Temizlenecek geçersiz kayıt bulunamadı", + "cleanupOrphanedDownloadsNone": "No orphaned entries found", "@cleanupOrphanedDownloadsNone": { "description": "Snackbar when no orphans found" }, - "cacheTitle": "Önbellek ve Depolama", + "cacheTitle": "Storage & Cache", "@cacheTitle": { "description": "Cache management page title" }, - "cacheSummaryTitle": "Önbellek Özeti", + "cacheSummaryTitle": "Cache overview", "@cacheSummaryTitle": { "description": "Heading for cache summary card" }, - "cacheSummarySubtitle": "Önbelleği temizlemek indirdiğiniz müzik dosyalarını SİLMEZ.", + "cacheSummarySubtitle": "Clearing cache will not remove downloaded music files.", "@cacheSummarySubtitle": { "description": "Helper text for cache summary card" }, - "cacheEstimatedTotal": "Tahmini önbellek kullanımı: {size}", + "cacheEstimatedTotal": "Estimated cache usage: {size}", "@cacheEstimatedTotal": { "description": "Total cache size shown in summary", "placeholders": { @@ -2701,71 +2834,71 @@ } } }, - "cacheSectionStorage": "Önbelleğe Alınan Veriler", + "cacheSectionStorage": "Cached Data", "@cacheSectionStorage": { "description": "Section header for cache entries" }, - "cacheSectionMaintenance": "Bakım ve Temizlik", + "cacheSectionMaintenance": "Maintenance", "@cacheSectionMaintenance": { "description": "Section header for cleanup actions" }, - "cacheAppDirectory": "Uygulama Önbelleği", + "cacheAppDirectory": "App cache directory", "@cacheAppDirectory": { "description": "Cache item title for app cache directory" }, - "cacheAppDirectoryDesc": "İnternet yanıtları, küçük resimler ve uygulamanın tuttuğu geçici dosyalar.", + "cacheAppDirectoryDesc": "HTTP responses, WebView data, and other temporary app data.", "@cacheAppDirectoryDesc": { "description": "Description of what app cache directory contains" }, - "cacheTempDirectory": "Geçici Klasör", + "cacheTempDirectory": "Temporary directory", "@cacheTempDirectory": { "description": "Cache item title for temporary files directory" }, - "cacheTempDirectoryDesc": "İndirme ve ses dönüştürme işlemleri sırasında oluşan artık dosyalar.", + "cacheTempDirectoryDesc": "Temporary files from downloads and audio conversion.", "@cacheTempDirectoryDesc": { "description": "Description of what temporary directory contains" }, - "cacheCoverImage": "Kapak Resmi Önbelleği", + "cacheCoverImage": "Cover image cache", "@cacheCoverImage": { "description": "Cache item title for persistent cover images" }, - "cacheCoverImageDesc": "Önceden yüklenmiş albüm kapakları. Silinirse tekrar görüntülediğinizde yeniden indirilir.", + "cacheCoverImageDesc": "Downloaded album and track cover art. Will re-download when viewed.", "@cacheCoverImageDesc": { "description": "Description of what cover image cache contains" }, - "cacheLibraryCover": "Kitaplık Kapağı Önbelleği", + "cacheLibraryCover": "Library cover cache", "@cacheLibraryCover": { "description": "Cache item title for local library cover art images" }, - "cacheLibraryCoverDesc": "Yerel müzik dosyalarınızdan çıkarılmış kapaklar. Silinirse sonraki taramada yeniden oluşturulur.", + "cacheLibraryCoverDesc": "Cover art extracted from local music files. Will re-extract on next scan.", "@cacheLibraryCoverDesc": { "description": "Description of what library cover cache contains" }, - "cacheExploreFeed": "Keşfet Akışı Önbelleği", + "cacheExploreFeed": "Explore feed cache", "@cacheExploreFeed": { "description": "Cache item title for explore home feed cache" }, - "cacheExploreFeedDesc": "Keşfet sekmesindeki (yeni çıkanlar vb.) içerikler. Silerseniz sayfayı açtığınızda yenilenir.", + "cacheExploreFeedDesc": "Explore tab content (new releases, trending). Will refresh on next visit.", "@cacheExploreFeedDesc": { "description": "Description of what explore feed cache contains" }, - "cacheTrackLookup": "Şarkı Kimliği Önbelleği", + "cacheTrackLookup": "Track lookup cache", "@cacheTrackLookup": { "description": "Cache item title for track ID lookup cache" }, - "cacheTrackLookupDesc": "Spotify/Deezer ID eşleşmeleri. Temizlerseniz ilk birkaç aramanız biraz yavaşlayabilir.", + "cacheTrackLookupDesc": "Spotify/Deezer track ID lookups. Clearing may slow next few searches.", "@cacheTrackLookupDesc": { "description": "Description of what track lookup cache contains" }, - "cacheCleanupUnusedDesc": "Artık cihazınızda var olmayan dosyaların geçmiş kayıtlarını ve kitaplık verilerini temizler.", + "cacheCleanupUnusedDesc": "Remove orphaned download history and library entries for missing files.", "@cacheCleanupUnusedDesc": { "description": "Description of what cleanup unused data does" }, - "cacheNoData": "Veri yok", + "cacheNoData": "No cached data", "@cacheNoData": { "description": "Label when cache category has no data" }, - "cacheSizeWithFiles": "{size} ({count} dosya)", + "cacheSizeWithFiles": "{size} in {count} files", "@cacheSizeWithFiles": { "description": "Cache size and file count", "placeholders": { @@ -2786,7 +2919,7 @@ } } }, - "cacheEntries": "{count} kayıt", + "cacheEntries": "{count} entries", "@cacheEntries": { "description": "Track cache entry count", "placeholders": { @@ -2795,7 +2928,7 @@ } } }, - "cacheClearSuccess": "Temizlendi: {target}", + "cacheClearSuccess": "Cleared: {target}", "@cacheClearSuccess": { "description": "Snackbar after clearing selected cache", "placeholders": { @@ -2804,11 +2937,11 @@ } } }, - "cacheClearConfirmTitle": "Önbelleği Temizle?", + "cacheClearConfirmTitle": "Clear cache?", "@cacheClearConfirmTitle": { "description": "Dialog title before clearing one cache category" }, - "cacheClearConfirmMessage": "Sadece \"{target}\" için olan önbellek silinecek. İndirdiğiniz hiçbir müzik dosyasına dokunulmayacak.", + "cacheClearConfirmMessage": "This will clear cached data for {target}. Downloaded music files will not be deleted.", "@cacheClearConfirmMessage": { "description": "Dialog message before clearing selected cache", "placeholders": { @@ -2817,27 +2950,27 @@ } } }, - "cacheClearAllConfirmTitle": "Tüm Önbelleği Temizle?", + "cacheClearAllConfirmTitle": "Clear all cache?", "@cacheClearAllConfirmTitle": { "description": "Dialog title before clearing all caches" }, - "cacheClearAllConfirmMessage": "Bu sayfadaki tüm önbellek kategorileri temizlenecek. İndirdiğiniz müzik dosyaları kesinlikle SİLİNMEYECEK.", + "cacheClearAllConfirmMessage": "This will clear all cache categories on this page. Downloaded music files will not be deleted.", "@cacheClearAllConfirmMessage": { "description": "Dialog message before clearing all caches" }, - "cacheClearAll": "Tüm Önbelleği Temizle", + "cacheClearAll": "Clear all cache", "@cacheClearAll": { "description": "Button label to clear all caches" }, - "cacheCleanupUnused": "Gereksiz Dosyaları Temizle", + "cacheCleanupUnused": "Cleanup unused data", "@cacheCleanupUnused": { "description": "Action title for cleaning unused entries" }, - "cacheCleanupUnusedSubtitle": "Cihazda olmayan dosyalara ait geçmiş ve kitaplık kayıtlarını kaldırır", + "cacheCleanupUnusedSubtitle": "Remove orphaned download history and missing library entries", "@cacheCleanupUnusedSubtitle": { "description": "Subtitle for cleanup unused data action" }, - "cacheCleanupResult": "Temizlik Bitti: {downloadCount} geçersiz geçmiş, {libraryCount} eksik kitaplık kaydı kaldırıldı", + "cacheCleanupResult": "Cleanup completed: {downloadCount} orphaned downloads, {libraryCount} missing library entries", "@cacheCleanupResult": { "description": "Snackbar after unused data cleanup", "placeholders": { @@ -2849,43 +2982,75 @@ } } }, - "cacheRefreshStats": "Boyutları Yenile", + "cacheRefreshStats": "Refresh stats", "@cacheRefreshStats": { "description": "Button label to refresh cache statistics" }, - "trackSaveCoverArt": "Albüm Kapağını Kaydet", + "trackSaveCoverArt": "Save Cover Art", "@trackSaveCoverArt": { "description": "Menu action - save album cover art as file" }, - "trackSaveCoverArtSubtitle": "Albüm kapağını resim (.jpg) dosyası olarak dışa aktar", + "trackSaveCoverArtSubtitle": "Save album art as .jpg file", "@trackSaveCoverArtSubtitle": { "description": "Subtitle for save cover art action" }, - "trackSaveLyrics": "Şarkı Sözlerini Kaydet (.lrc)", + "trackSaveLyrics": "Save Lyrics (.lrc)", "@trackSaveLyrics": { "description": "Menu action - save lyrics as .lrc file" }, - "trackSaveLyricsSubtitle": "Şarkı sözlerini çekip .lrc dosyası olarak kaydeder", + "trackSaveLyricsSubtitle": "Fetch and save lyrics as .lrc file", "@trackSaveLyricsSubtitle": { "description": "Subtitle for save lyrics action" }, - "trackSaveLyricsProgress": "Şarkı sözleri kaydediliyor...", + "trackSaveLyricsProgress": "Saving lyrics...", "@trackSaveLyricsProgress": { "description": "Snackbar while saving lyrics to file" }, - "trackReEnrich": "Bilgileri İnternetten Güncelle (Re-enrich)", + "trackReEnrich": "Re-enrich", "@trackReEnrich": { "description": "Menu action - re-embed metadata into audio file" }, - "trackReEnrichOnlineSubtitle": "İnternetten şarkı verilerini (metadata) bulup dosyaya yeniden işler", + "trackReEnrichOnlineSubtitle": "Search metadata online and embed into file", "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, - "trackEditMetadata": "Şarkı Bilgilerini Düzenle", + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, + "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" }, - "trackCoverSaved": "Kapak resmi \"{fileName}\" adıyla kaydedildi", + "trackCoverSaved": "Cover art saved to {fileName}", "@trackCoverSaved": { "description": "Snackbar after cover art saved", "placeholders": { @@ -2894,11 +3059,11 @@ } } }, - "trackCoverNoSource": "Geçerli bir kapak resmi kaynağı bulunamadı", + "trackCoverNoSource": "No cover art source available", "@trackCoverNoSource": { "description": "Snackbar when no cover art URL or embedded cover" }, - "trackLyricsSaved": "Sözler \"{fileName}\" adıyla kaydedildi", + "trackLyricsSaved": "Lyrics saved to {fileName}", "@trackLyricsSaved": { "description": "Snackbar after lyrics saved", "placeholders": { @@ -2907,27 +3072,27 @@ } } }, - "trackReEnrichProgress": "Şarkı bilgileri (metadata) güncelleniyor...", + "trackReEnrichProgress": "Re-enriching metadata...", "@trackReEnrichProgress": { "description": "Snackbar while re-enriching metadata" }, - "trackReEnrichSearching": "İnternette şarkı bilgisi (metadata) aranıyor...", + "trackReEnrichSearching": "Searching metadata online...", "@trackReEnrichSearching": { "description": "Snackbar while searching metadata from internet for local items" }, - "trackReEnrichSuccess": "Şarkı bilgileri dosyaya başarıyla işlendi", + "trackReEnrichSuccess": "Metadata re-enriched successfully", "@trackReEnrichSuccess": { "description": "Snackbar after successful re-enrichment" }, - "trackReEnrichFfmpegFailed": "Sözleri (veya verileri) dosyaya yazarken hata oluştu", + "trackReEnrichFfmpegFailed": "FFmpeg metadata embed failed", "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, - "queueFlacAction": "Bunu FLAC Olarak İndir", + "queueFlacAction": "Queue FLAC", "@queueFlacAction": { "description": "Action/button label for queueing FLAC redownloads for local tracks" }, - "queueFlacConfirmMessage": "Seçilen şarkılar için internette FLAC eşleşmesi aranacak ve indirme sırasına eklenecek.\n\nMevcut dosyalarınıza dokunulmayacak veya silinmeyecek.\n\nSadece yüksek oranda eşleşenler otomatik olarak sıraya eklenir.\n\n{count} şarkı seçildi", + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", "@queueFlacConfirmMessage": { "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", "placeholders": { @@ -2936,7 +3101,7 @@ } } }, - "queueFlacFindingProgress": "FLAC eşleşmeleri aranıyor... ({current}/{total})", + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", "@queueFlacFindingProgress": { "description": "Snackbar while resolving remote matches for local FLAC redownloads", "placeholders": { @@ -2948,11 +3113,11 @@ } } }, - "queueFlacNoReliableMatches": "Seçiminiz için internette güvenilir bir eşleşme bulunamadı", + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", "@queueFlacNoReliableMatches": { "description": "Snackbar when no safe FLAC redownload matches were found" }, - "queueFlacQueuedWithSkipped": "{addedCount} şarkı sıraya eklendi, {skippedCount} şarkı eşleşmediği için atlandı", + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", "@queueFlacQueuedWithSkipped": { "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", "placeholders": { @@ -2964,7 +3129,7 @@ } } }, - "trackSaveFailed": "İşlem başarısız: {error}", + "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", "placeholders": { @@ -2973,31 +3138,31 @@ } } }, - "trackConvertFormat": "Ses Formatını Dönüştür", + "trackConvertFormat": "Convert Format", "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Dosyayı MP3, Opus, ALAC veya FLAC formatına çevirin", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, - "trackConvertTitle": "Sesi Dönüştür", + "trackConvertTitle": "Convert Audio", "@trackConvertTitle": { "description": "Title of convert bottom sheet" }, - "trackConvertTargetFormat": "Hedef Format", + "trackConvertTargetFormat": "Target Format", "@trackConvertTargetFormat": { "description": "Label for format selection" }, - "trackConvertBitrate": "Bit Hızı (Kalite)", + "trackConvertBitrate": "Bitrate", "@trackConvertBitrate": { "description": "Label for bitrate selection" }, - "trackConvertConfirmTitle": "Dönüşümü Onayla", + "trackConvertConfirmTitle": "Confirm Conversion", "@trackConvertConfirmTitle": { "description": "Confirmation dialog title" }, - "trackConvertConfirmMessage": "{sourceFormat} formatından {targetFormat} formatına ({bitrate}) dönüştürülsün mü?\n\nDönüşüm bittikten sonra orijinal dosya tamamen silinecektir.", + "trackConvertConfirmMessage": "Convert from {sourceFormat} to {targetFormat} at {bitrate}?\n\nThe original file will be deleted after conversion.", "@trackConvertConfirmMessage": { "description": "Confirmation dialog message", "placeholders": { @@ -3012,7 +3177,7 @@ } } }, - "trackConvertConfirmMessageLossless": "{sourceFormat} formatından {targetFormat} formatına dönüştürülsün mü? (Kayıpsız format, kalite kaybı yaşanmaz)\n\nDönüşüm bittikten sonra orijinal dosya tamamen silinecektir.", + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", "@trackConvertConfirmMessageLossless": { "description": "Confirmation dialog message for lossless-to-lossless conversion", "placeholders": { @@ -3024,15 +3189,15 @@ } } }, - "trackConvertLosslessHint": "Kayıpsız bir formata dönüştürülüyor (Kalite düşüşü olmaz)", + "trackConvertLosslessHint": "Lossless conversion — no quality loss", "@trackConvertLosslessHint": { "description": "Hint shown when converting between lossless formats" }, - "trackConvertConverting": "Ses dönüştürülüyor...", + "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" }, - "trackConvertSuccess": "Dosya başarıyla {format} formatına çevrildi", + "trackConvertSuccess": "Converted to {format} successfully", "@trackConvertSuccess": { "description": "Snackbar after successful conversion", "placeholders": { @@ -3041,19 +3206,19 @@ } } }, - "trackConvertFailed": "Dönüşüm işlemi başarısız oldu", + "trackConvertFailed": "Conversion failed", "@trackConvertFailed": { "description": "Snackbar when conversion fails" }, - "cueSplitTitle": "CUE Dosyasını Parçalara Böl", + "cueSplitTitle": "Split CUE Sheet", "@cueSplitTitle": { "description": "Title for CUE split bottom sheet" }, - "cueSplitSubtitle": "Tek parça olan CUE+FLAC dosyasını ayrı şarkılara böler", + "cueSplitSubtitle": "Split CUE+FLAC into individual tracks", "@cueSplitSubtitle": { "description": "Subtitle for CUE split menu item" }, - "cueSplitAlbum": "Albüm: {album}", + "cueSplitAlbum": "Album: {album}", "@cueSplitAlbum": { "description": "Album name in CUE split sheet", "placeholders": { @@ -3062,7 +3227,7 @@ } } }, - "cueSplitArtist": "Sanatçı: {artist}", + "cueSplitArtist": "Artist: {artist}", "@cueSplitArtist": { "description": "Artist name in CUE split sheet", "placeholders": { @@ -3071,7 +3236,7 @@ } } }, - "cueSplitTrackCount": "{count} şarkı var", + "cueSplitTrackCount": "{count} tracks", "@cueSplitTrackCount": { "description": "Number of tracks in CUE sheet", "placeholders": { @@ -3080,11 +3245,11 @@ } } }, - "cueSplitConfirmTitle": "CUE Dosyasını Böl", + "cueSplitConfirmTitle": "Split CUE Album", "@cueSplitConfirmTitle": { "description": "CUE split confirmation dialog title" }, - "cueSplitConfirmMessage": "\"{album}\" albümünü {count} ayrı FLAC dosyasına bölmek istiyor musunuz?\n\nYeni dosyalar orijinal dosyanın bulunduğu klasöre kaydedilecektir.", + "cueSplitConfirmMessage": "Split \"{album}\" into {count} individual FLAC files?\n\nFiles will be saved to the same directory.", "@cueSplitConfirmMessage": { "description": "CUE split confirmation dialog message", "placeholders": { @@ -3096,7 +3261,7 @@ } } }, - "cueSplitSplitting": "CUE dosyası ayrıştırılıyor... ({current}/{total})", + "cueSplitSplitting": "Splitting CUE sheet... ({current}/{total})", "@cueSplitSplitting": { "description": "Snackbar while splitting CUE", "placeholders": { @@ -3108,7 +3273,7 @@ } } }, - "cueSplitSuccess": "Dosya başarıyla {count} şarkıya bölündü", + "cueSplitSuccess": "Split into {count} tracks successfully", "@cueSplitSuccess": { "description": "Snackbar after successful CUE split", "placeholders": { @@ -3117,59 +3282,59 @@ } } }, - "cueSplitFailed": "CUE bölme işlemi başarısız", + "cueSplitFailed": "CUE split failed", "@cueSplitFailed": { "description": "Snackbar when CUE split fails" }, - "cueSplitNoAudioFile": "Bu CUE ile eşleşen bir ses dosyası bulunamadı", + "cueSplitNoAudioFile": "Audio file not found for this CUE sheet", "@cueSplitNoAudioFile": { "description": "Error when CUE audio file is missing" }, - "cueSplitButton": "Şarkılara Böl", + "cueSplitButton": "Split into Tracks", "@cueSplitButton": { "description": "Button text to start CUE splitting" }, - "actionCreate": "Oluştur", + "actionCreate": "Create", "@actionCreate": { "description": "Generic action button - create" }, - "collectionFoldersTitle": "Klasörlerim", + "collectionFoldersTitle": "My folders", "@collectionFoldersTitle": { "description": "Library section title for custom folders" }, - "collectionWishlist": "İstek Listesi", + "collectionWishlist": "Wishlist", "@collectionWishlist": { "description": "Custom folder for saved tracks to download later" }, - "collectionLoved": "Favoriler", + "collectionLoved": "Loved", "@collectionLoved": { "description": "Custom folder for favorite tracks" }, - "collectionPlaylists": "Çalma Listeleri", + "collectionPlaylists": "Playlists", "@collectionPlaylists": { "description": "Custom user playlists folder" }, - "collectionPlaylist": "Çalma Listesi", + "collectionPlaylist": "Playlist", "@collectionPlaylist": { "description": "Single playlist label" }, - "collectionAddToPlaylist": "Çalma listesine ekle", + "collectionAddToPlaylist": "Add to playlist", "@collectionAddToPlaylist": { "description": "Action to add a track to user playlist" }, - "collectionCreatePlaylist": "Yeni çalma listesi oluştur", + "collectionCreatePlaylist": "Create playlist", "@collectionCreatePlaylist": { "description": "Action to create a new playlist" }, - "collectionNoPlaylistsYet": "Henüz listeniz yok", + "collectionNoPlaylistsYet": "No playlists yet", "@collectionNoPlaylistsYet": { "description": "Empty state title when user has no playlists" }, - "collectionNoPlaylistsSubtitle": "Müziklerinizi kategorize etmek için bir çalma listesi oluşturun", + "collectionNoPlaylistsSubtitle": "Create a playlist to start categorizing tracks", "@collectionNoPlaylistsSubtitle": { "description": "Empty state subtitle when user has no playlists" }, - "collectionPlaylistTracks": "{count, plural, =1{1 şarkı} other{{count} şarkı}}", + "collectionPlaylistTracks": "{count, plural, =1{1 track} other{{count} tracks}}", "@collectionPlaylistTracks": { "description": "Track count label for custom playlists", "placeholders": { @@ -3178,7 +3343,7 @@ } } }, - "collectionAddedToPlaylist": "\"{playlistName}\" listesine eklendi", + "collectionAddedToPlaylist": "Added to \"{playlistName}\"", "@collectionAddedToPlaylist": { "description": "Snackbar after adding track to playlist", "placeholders": { @@ -3187,7 +3352,7 @@ } } }, - "collectionAlreadyInPlaylist": "Zaten \"{playlistName}\" listesinde var", + "collectionAlreadyInPlaylist": "Already in \"{playlistName}\"", "@collectionAlreadyInPlaylist": { "description": "Snackbar when track already exists in playlist", "placeholders": { @@ -3196,27 +3361,27 @@ } } }, - "collectionPlaylistCreated": "Çalma listesi oluşturuldu", + "collectionPlaylistCreated": "Playlist created", "@collectionPlaylistCreated": { "description": "Snackbar after creating playlist" }, - "collectionPlaylistNameHint": "Çalma listesi adı", + "collectionPlaylistNameHint": "Playlist name", "@collectionPlaylistNameHint": { "description": "Hint text for playlist name input" }, - "collectionPlaylistNameRequired": "Lütfen liste için bir isim girin", + "collectionPlaylistNameRequired": "Playlist name is required", "@collectionPlaylistNameRequired": { "description": "Validation error for empty playlist name" }, - "collectionRenamePlaylist": "Yeniden adlandır", + "collectionRenamePlaylist": "Rename playlist", "@collectionRenamePlaylist": { "description": "Action to rename playlist" }, - "collectionDeletePlaylist": "Listeyi sil", + "collectionDeletePlaylist": "Delete playlist", "@collectionDeletePlaylist": { "description": "Action to delete playlist" }, - "collectionDeletePlaylistMessage": "\"{playlistName}\" listesini ve içindeki tüm şarkıları silmek istiyor musunuz?", + "collectionDeletePlaylistMessage": "Delete \"{playlistName}\" and all tracks inside it?", "@collectionDeletePlaylistMessage": { "description": "Confirmation message for deleting playlist", "placeholders": { @@ -3225,47 +3390,47 @@ } } }, - "collectionPlaylistDeleted": "Çalma listesi silindi", + "collectionPlaylistDeleted": "Playlist deleted", "@collectionPlaylistDeleted": { "description": "Snackbar after deleting playlist" }, - "collectionPlaylistRenamed": "Çalma listesi adı değiştirildi", + "collectionPlaylistRenamed": "Playlist renamed", "@collectionPlaylistRenamed": { "description": "Snackbar after renaming playlist" }, - "collectionWishlistEmptyTitle": "İstek Listeniz boş", + "collectionWishlistEmptyTitle": "Wishlist is empty", "@collectionWishlistEmptyTitle": { "description": "Wishlist empty state title" }, - "collectionWishlistEmptySubtitle": "Daha sonra indirmek istediğiniz şarkıların yanındaki (+) simgesine dokunun", + "collectionWishlistEmptySubtitle": "Tap + on tracks to save what you want to download later", "@collectionWishlistEmptySubtitle": { "description": "Wishlist empty state subtitle" }, - "collectionLovedEmptyTitle": "Favori klasörünüz boş", + "collectionLovedEmptyTitle": "Loved folder is empty", "@collectionLovedEmptyTitle": { "description": "Loved empty state title" }, - "collectionLovedEmptySubtitle": "Sevdiğiniz şarkıları burada toplamak için kalp ikonuna dokunun", + "collectionLovedEmptySubtitle": "Tap love on tracks to keep your favorites", "@collectionLovedEmptySubtitle": { "description": "Loved empty state subtitle" }, - "collectionPlaylistEmptyTitle": "Bu çalma listesi boş", + "collectionPlaylistEmptyTitle": "Playlist is empty", "@collectionPlaylistEmptyTitle": { "description": "Playlist empty state title" }, - "collectionPlaylistEmptySubtitle": "Buraya eklemek için istediğiniz şarkının üzerindeki (+) butonuna basılı tutun", + "collectionPlaylistEmptySubtitle": "Long-press + on any track to add it here", "@collectionPlaylistEmptySubtitle": { "description": "Playlist empty state subtitle" }, - "collectionRemoveFromPlaylist": "Çalma listesinden çıkar", + "collectionRemoveFromPlaylist": "Remove from playlist", "@collectionRemoveFromPlaylist": { "description": "Tooltip for removing track from playlist" }, - "collectionRemoveFromFolder": "Klasörden çıkar", + "collectionRemoveFromFolder": "Remove from folder", "@collectionRemoveFromFolder": { "description": "Tooltip for removing track from wishlist/loved folder" }, - "collectionRemoved": "\"{trackName}\" listeden çıkarıldı", + "collectionRemoved": "\"{trackName}\" removed", "@collectionRemoved": { "description": "Snackbar after removing a track from a collection", "placeholders": { @@ -3274,7 +3439,7 @@ } } }, - "collectionAddedToLoved": "\"{trackName}\" Favoriler klasörüne eklendi", + "collectionAddedToLoved": "\"{trackName}\" added to Loved", "@collectionAddedToLoved": { "description": "Snackbar after adding track to loved folder", "placeholders": { @@ -3283,7 +3448,7 @@ } } }, - "collectionRemovedFromLoved": "\"{trackName}\" Favorilerinizden çıkarıldı", + "collectionRemovedFromLoved": "\"{trackName}\" removed from Loved", "@collectionRemovedFromLoved": { "description": "Snackbar after removing track from loved folder", "placeholders": { @@ -3292,7 +3457,7 @@ } } }, - "collectionAddedToWishlist": "\"{trackName}\" İstek Listenize eklendi", + "collectionAddedToWishlist": "\"{trackName}\" added to Wishlist", "@collectionAddedToWishlist": { "description": "Snackbar after adding track to wishlist", "placeholders": { @@ -3301,7 +3466,7 @@ } } }, - "collectionRemovedFromWishlist": "\"{trackName}\" İstek Listenizden çıkarıldı", + "collectionRemovedFromWishlist": "\"{trackName}\" removed from Wishlist", "@collectionRemovedFromWishlist": { "description": "Snackbar after removing track from wishlist", "placeholders": { @@ -3310,31 +3475,31 @@ } } }, - "trackOptionAddToLoved": "Favorilere Ekle", + "trackOptionAddToLoved": "Add to Loved", "@trackOptionAddToLoved": { "description": "Bottom sheet action label - add track to loved folder" }, - "trackOptionRemoveFromLoved": "Favorilerden Çıkar", + "trackOptionRemoveFromLoved": "Remove from Loved", "@trackOptionRemoveFromLoved": { "description": "Bottom sheet action label - remove track from loved folder" }, - "trackOptionAddToWishlist": "İstek Listesine Ekle", + "trackOptionAddToWishlist": "Add to Wishlist", "@trackOptionAddToWishlist": { "description": "Bottom sheet action label - add track to wishlist" }, - "trackOptionRemoveFromWishlist": "İstek Listesinden Çıkar", + "trackOptionRemoveFromWishlist": "Remove from Wishlist", "@trackOptionRemoveFromWishlist": { "description": "Bottom sheet action label - remove track from wishlist" }, - "collectionPlaylistChangeCover": "Kapak resmini değiştir", + "collectionPlaylistChangeCover": "Change cover image", "@collectionPlaylistChangeCover": { "description": "Bottom sheet action to pick a custom cover image for a playlist" }, - "collectionPlaylistRemoveCover": "Kapak resmini kaldır", + "collectionPlaylistRemoveCover": "Remove cover image", "@collectionPlaylistRemoveCover": { "description": "Bottom sheet action to remove custom cover image from a playlist" }, - "selectionShareCount": "{count} {count, plural, =1{şarkıyı} other{şarkıyı}} paylaş", + "selectionShareCount": "Share {count} {count, plural, =1{track} other{tracks}}", "@selectionShareCount": { "description": "Share button text with count in selection mode", "placeholders": { @@ -3343,11 +3508,11 @@ } } }, - "selectionShareNoFiles": "Paylaşılabilir bir dosya bulunamadı", + "selectionShareNoFiles": "No shareable files found", "@selectionShareNoFiles": { "description": "Snackbar when no selected files exist on disk" }, - "selectionConvertCount": "{count} {count, plural, =1{şarkıyı} other{şarkıyı}} dönüştür", + "selectionConvertCount": "Convert {count} {count, plural, =1{track} other{tracks}}", "@selectionConvertCount": { "description": "Convert button text with count in selection mode", "placeholders": { @@ -3356,15 +3521,15 @@ } } }, - "selectionConvertNoConvertible": "Dönüştürülebilir formatta bir şarkı seçilmedi", + "selectionConvertNoConvertible": "No convertible tracks selected", "@selectionConvertNoConvertible": { "description": "Snackbar when no selected tracks support conversion" }, - "selectionBatchConvertConfirmTitle": "Toplu Dönüştürme", + "selectionBatchConvertConfirmTitle": "Batch Convert", "@selectionBatchConvertConfirmTitle": { "description": "Confirmation dialog title for batch conversion" }, - "selectionBatchConvertConfirmMessage": "{count} {count, plural, =1{şarkıyı} other{şarkıyı}} {format} formatına ({bitrate}) dönüştürmek istiyor musunuz?\n\nDönüşüm işlemi bittikten sonra orijinal dosyalar tamamen silinecektir.", + "selectionBatchConvertConfirmMessage": "Convert {count} {count, plural, =1{track} other{tracks}} to {format} at {bitrate}?\n\nOriginal files will be deleted after conversion.", "@selectionBatchConvertConfirmMessage": { "description": "Confirmation dialog message for batch conversion", "placeholders": { @@ -3379,7 +3544,7 @@ } } }, - "selectionBatchConvertConfirmMessageLossless": "{count} {count, plural, =1{şarkıyı} other{şarkıyı}} {format} formatına dönüştürmek istiyor musunuz? (Kayıpsız işlem — kalite kaybı olmaz)\n\nDönüşüm işlemi bittikten sonra orijinal dosyalar tamamen silinecektir.", + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", "@selectionBatchConvertConfirmMessageLossless": { "description": "Confirmation dialog message for lossless batch conversion", "placeholders": { @@ -3391,7 +3556,7 @@ } } }, - "selectionBatchConvertProgress": "Dönüştürülüyor: {current} / {total}...", + "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", "placeholders": { @@ -3403,7 +3568,7 @@ } } }, - "selectionBatchConvertSuccess": "{total} şarkıdan {success} tanesi {format} formatına dönüştürüldü", + "selectionBatchConvertSuccess": "Converted {success} of {total} tracks to {format}", "@selectionBatchConvertSuccess": { "description": "Snackbar after batch conversion completes", "placeholders": { @@ -3418,7 +3583,7 @@ } } }, - "downloadedAlbumDownloadedCount": "{count} tanesi indirildi", + "downloadedAlbumDownloadedCount": "{count} downloaded", "@downloadedAlbumDownloadedCount": { "description": "Downloaded tracks count badge", "placeholders": { @@ -3427,27 +3592,27 @@ } } }, - "downloadUseAlbumArtistForFoldersAlbumSubtitle": "Sanatçı klasörleri için Albüm Sanatçısı adı kullanılır", + "downloadUseAlbumArtistForFoldersAlbumSubtitle": "Artist folders use Album Artist when available", "@downloadUseAlbumArtistForFoldersAlbumSubtitle": { "description": "Subtitle when Album Artist is used for folder naming" }, - "downloadUseAlbumArtistForFoldersTrackSubtitle": "Sanatçı klasörleri için sadece Şarkı Sanatçısı adı kullanılır", + "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" }, - "lyricsProvidersTitle": "Şarkı Sözü Sağlayıcıları", + "lyricsProvidersTitle": "Lyrics Providers", "@lyricsProvidersTitle": { "description": "Title for the lyrics provider priority page" }, - "lyricsProvidersDescription": "Şarkı sözü kaynaklarını açıp kapatın veya sıralamalarını değiştirin. Uygulama sözleri bulana kadar sağlayıcıları yukarıdan aşağıya doğru sırayla dener.", + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", "@lyricsProvidersDescription": { "description": "Description on the lyrics provider priority page" }, - "lyricsProvidersInfoText": "Mağazadan yüklediğiniz eklentiler her zaman varsayılan yerleşik sağlayıcılardan önce çalışır. En az bir sağlayıcı her zaman açık kalmalıdır.", + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", "@lyricsProvidersInfoText": { "description": "Info tip on lyrics provider priority page" }, - "lyricsProvidersEnabledSection": "Açık ({count})", + "lyricsProvidersEnabledSection": "Enabled ({count})", "@lyricsProvidersEnabledSection": { "description": "Section header for enabled providers", "placeholders": { @@ -3456,7 +3621,7 @@ } } }, - "lyricsProvidersDisabledSection": "Kapalı ({count})", + "lyricsProvidersDisabledSection": "Disabled ({count})", "@lyricsProvidersDisabledSection": { "description": "Section header for disabled providers", "placeholders": { @@ -3465,79 +3630,75 @@ } } }, - "lyricsProvidersAtLeastOne": "En az bir sağlayıcı her zaman açık kalmalıdır", + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", "@lyricsProvidersAtLeastOne": { "description": "Snackbar when user tries to disable the last enabled provider" }, - "lyricsProvidersSaved": "Şarkı sözü sağlayıcılarının sıralaması kaydedildi", + "lyricsProvidersSaved": "Lyrics provider priority saved", "@lyricsProvidersSaved": { "description": "Snackbar after saving lyrics provider priority" }, - "lyricsProvidersDiscardContent": "Kaydedilmemiş değişiklikleriniz iptal edilecek.", + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", "@lyricsProvidersDiscardContent": { "description": "Body text of the discard-changes dialog on lyrics provider page" }, - "lyricsProviderSpotifyApiDesc": "Topluluk API'si üzerinden senkronize Spotify sözleri", - "@lyricsProviderSpotifyApiDesc": { - "description": "Description for Spotify Lyrics API provider" - }, - "lyricsProviderLrclibDesc": "Açık kaynaklı, senkronize şarkı sözü veritabanı", + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", "@lyricsProviderLrclibDesc": { "description": "Description for LRCLIB provider" }, - "lyricsProviderNeteaseDesc": "NetEase Cloud Music (Özellikle Asya müzikleri için ideal)", + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", "@lyricsProviderNeteaseDesc": { "description": "Description for Netease provider" }, - "lyricsProviderMusixmatchDesc": "En geniş şarkı sözü arşivi (Çok dilli)", + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", "@lyricsProviderMusixmatchDesc": { "description": "Description for Musixmatch provider" }, - "lyricsProviderAppleMusicDesc": "Kelime kelime akan senkronize sözler (Proxy üzerinden)", + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", "@lyricsProviderAppleMusicDesc": { "description": "Description for Apple Music provider" }, - "lyricsProviderQqMusicDesc": "QQ Music (Özellikle Çince şarkılar için, Proxy üzerinden)", + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", "@lyricsProviderQqMusicDesc": { "description": "Description for QQ Music provider" }, - "lyricsProviderExtensionDesc": "Eklenti ile sağlanan kaynak", + "lyricsProviderExtensionDesc": "Extension provider", "@lyricsProviderExtensionDesc": { "description": "Generic description for extension-based lyrics providers" }, - "safMigrationTitle": "Depolama Sistem Güncellemesi", + "safMigrationTitle": "Storage Update Required", "@safMigrationTitle": { "description": "Title of SAF migration dialog" }, - "safMigrationMessage1": "SpotiFLAC artık indirme işlemleri için Android'in yeni Depolama Erişim Çerçevesi'ni (SAF) kullanıyor. Bu sayede Android 10 ve üzeri sürümlerdeki \"izin reddedildi\" hataları ortadan kalkıyor.", + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", "@safMigrationMessage1": { "description": "First paragraph of SAF migration dialog" }, - "safMigrationMessage2": "Yeni depolama sistemine geçiş yapmak için lütfen indirme klasörünüzü tekrar seçin.", + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", "@safMigrationMessage2": { "description": "Second paragraph of SAF migration dialog" }, - "safMigrationSuccess": "İndirme klasörü başarıyla yeni (SAF) moda geçirildi", + "safMigrationSuccess": "Download folder updated to SAF mode", "@safMigrationSuccess": { "description": "Snackbar after successfully migrating to SAF" }, - "settingsDonate": "Bağış Yap", + "settingsDonate": "Donate", "@settingsDonate": { "description": "Settings menu item - donate" }, - "settingsDonateSubtitle": "SpotiFLAC-Mobile gelişimine destek olun", + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", "@settingsDonateSubtitle": { "description": "Subtitle for donate menu item" }, - "tooltipLoveAll": "Tümünü Favorilere Ekle", + "tooltipLoveAll": "Love All", "@tooltipLoveAll": { "description": "Tooltip for the Love All button on album/playlist screens" }, - "tooltipAddToPlaylist": "Çalma Listesine Ekle", + "tooltipAddToPlaylist": "Add to Playlist", "@tooltipAddToPlaylist": { "description": "Tooltip for the Add to Playlist button" }, - "snackbarRemovedTracksFromLoved": "{count} şarkı Favoriler'den çıkarıldı", + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", "@snackbarRemovedTracksFromLoved": { "description": "Snackbar after removing multiple tracks from Loved folder", "placeholders": { @@ -3546,7 +3707,7 @@ } } }, - "snackbarAddedTracksToLoved": "{count} şarkı Favoriler'e eklendi", + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", "@snackbarAddedTracksToLoved": { "description": "Snackbar after adding multiple tracks to Loved folder", "placeholders": { @@ -3555,11 +3716,11 @@ } } }, - "dialogDownloadAllTitle": "Tümünü İndir", + "dialogDownloadAllTitle": "Download All", "@dialogDownloadAllTitle": { - "description": "Title of the Download All confirmation dialog" + "description": "Dialog title for bulk download confirmation" }, - "dialogDownloadAllMessage": "Bu listedeki {count} şarkı indirilsin mi?", + "dialogDownloadAllMessage": "Download {count} tracks?", "@dialogDownloadAllMessage": { "description": "Body of the Download All confirmation dialog", "placeholders": { @@ -3568,39 +3729,35 @@ } } }, - "dialogDownload": "İndir", - "@dialogDownload": { - "description": "Confirm button in Download All dialog" - }, - "homeSkipAlreadyDownloaded": "Daha önce inmiş olan şarkıları atla", + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", "@homeSkipAlreadyDownloaded": { "description": "Checkbox label in import dialog to skip already-downloaded songs" }, - "homeGoToAlbum": "Albüme Git", + "homeGoToAlbum": "Go to Album", "@homeGoToAlbum": { "description": "Context menu item to navigate to the album page" }, - "homeAlbumInfoUnavailable": "Albüm bilgisine ulaşılamıyor", + "homeAlbumInfoUnavailable": "Album info not available", "@homeAlbumInfoUnavailable": { "description": "Snackbar when album info cannot be loaded" }, - "snackbarLoadingCueSheet": "CUE dosyası yükleniyor...", + "snackbarLoadingCueSheet": "Loading CUE sheet...", "@snackbarLoadingCueSheet": { "description": "Snackbar while loading a CUE sheet file" }, - "snackbarMetadataSaved": "Şarkı verileri dosyaya başarıyla kaydedildi", + "snackbarMetadataSaved": "Metadata saved successfully", "@snackbarMetadataSaved": { "description": "Snackbar after successfully saving track metadata" }, - "snackbarFailedToEmbedLyrics": "Şarkı sözleri dosyaya eklenemedi", + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", "@snackbarFailedToEmbedLyrics": { "description": "Snackbar when lyrics embedding fails" }, - "snackbarFailedToWriteStorage": "Değişiklikler asıl dosyaya yazılamadı", + "snackbarFailedToWriteStorage": "Failed to write back to storage", "@snackbarFailedToWriteStorage": { "description": "Snackbar when writing metadata back to file fails" }, - "snackbarError": "Hata: {error}", + "snackbarError": "Error: {error}", "@snackbarError": { "description": "Generic error snackbar with error detail", "placeholders": { @@ -3609,199 +3766,195 @@ } } }, - "snackbarNoActionDefined": "Bu buton için henüz bir işlev tanımlanmamış", + "snackbarNoActionDefined": "No action defined for this button", "@snackbarNoActionDefined": { "description": "Snackbar when an extension button has no action configured" }, - "noTracksFoundForAlbum": "Bu albümün içinde hiç şarkı bulunamadı", + "noTracksFoundForAlbum": "No tracks found for this album", "@noTracksFoundForAlbum": { "description": "Empty state message when an album has no tracks" }, - "downloadLocationSubtitle": "İndirdiğiniz dosyaların cihazınızda nasıl tutulacağını seçin.", + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", "@downloadLocationSubtitle": { "description": "Subtitle text in Android download location bottom sheet" }, - "storageModeAppFolder": "Uygulama Klasörü", + "storageModeAppFolder": "App folder (non-SAF)", "@storageModeAppFolder": { "description": "Storage mode option - use legacy app folder" }, - "storageModeAppFolderSubtitle": "Telefonunuzdaki varsayılan Müzik klasörünü kullanır", + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", "@storageModeAppFolderSubtitle": { "description": "Subtitle for app folder storage mode" }, - "storageModeSaf": "SAF ile Özel Klasör (Önerilen)", + "storageModeSaf": "SAF folder", "@storageModeSaf": { "description": "Storage mode option - use Android SAF picker" }, - "storageModeSafSubtitle": "Android dosya seçicisi ile cihazınızdan dilediğiniz klasörü seçin", + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", "@storageModeSafSubtitle": { "description": "Subtitle for SAF storage mode" }, - "downloadFilenameDescription": "Şarkıların cihazınızda hangi dosya adıyla kaydedileceğini özelleştirin.", + "downloadFilenameDescription": "Customize how your files are named.", "@downloadFilenameDescription": { "description": "Description text in filename format bottom sheet" }, - "downloadFilenameInsertTag": "Eklemek için dokunun:", + "downloadFilenameInsertTag": "Tap to insert tag:", "@downloadFilenameInsertTag": { "description": "Label above filename tag chips" }, - "downloadSeparateSinglesEnabled": "Sanatçı klasörünün içinde Single'ları ayrı bir klasöre ayırır", + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", "@downloadSeparateSinglesEnabled": { "description": "Subtitle when separate singles folder is enabled" }, - "downloadSeparateSinglesDisabled": "Single'lar ile albümler aynı yerde durur", + "downloadSeparateSinglesDisabled": "All files in same structure", "@downloadSeparateSinglesDisabled": { "description": "Subtitle when separate singles folder is disabled" }, - "downloadArtistNameFilters": "Sanatçı Adı Filtreleri", + "downloadArtistNameFilters": "Artist Name Filters", "@downloadArtistNameFilters": { "description": "Setting title for artist folder filter options" }, - "downloadCreatePlaylistSourceFolder": "Çalma Listeleri İçin Ana Klasör Oluştur", + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", "@downloadCreatePlaylistSourceFolder": { "description": "Setting title for adding a playlist folder prefix before the normal organization structure" }, - "downloadCreatePlaylistSourceFolderEnabled": "Çalma listesi indirildiğinde en dışa 'Çalma Listesi Adı' isimli bir klasör oluşturur ve içini normal düzeninize göre dizer.", + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", "@downloadCreatePlaylistSourceFolderEnabled": { "description": "Subtitle when playlist source folder prefix is enabled" }, - "downloadCreatePlaylistSourceFolderDisabled": "Çalma listesindeki şarkılar da diğerleri gibi doğrudan albüm ve sanatçı klasörlerinize atılır.", + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", "@downloadCreatePlaylistSourceFolderDisabled": { "description": "Subtitle when playlist source folder prefix is disabled" }, - "downloadCreatePlaylistSourceFolderRedundant": "Klasör Düzeni zaten 'Çalma Listesine Göre' ayarlı olduğu için bu seçenek pasiftir.", + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", "@downloadCreatePlaylistSourceFolderRedundant": { "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" }, - "downloadSongLinkRegion": "SongLink Arama Bölgesi", + "downloadSongLinkRegion": "SongLink Region", "@downloadSongLinkRegion": { "description": "Setting title for SongLink country region" }, - "downloadNetworkCompatibilityMode": "Ağ Uyumluluk Modu", + "downloadNetworkCompatibilityMode": "Network compatibility mode", "@downloadNetworkCompatibilityMode": { "description": "Setting title for network compatibility toggle" }, - "downloadNetworkCompatibilityModeEnabled": "Açık: Bağlantı HTTP ile denenir ve geçersiz sertifikalar kabul edilir (Güvensiz ama çözümleyici)", + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", "@downloadNetworkCompatibilityModeEnabled": { "description": "Subtitle when network compatibility mode is enabled" }, - "downloadNetworkCompatibilityModeDisabled": "Kapalı: Katı HTTPS kuralları uygulanır (Önerilen)", + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", "@downloadNetworkCompatibilityModeDisabled": { "description": "Subtitle when network compatibility mode is disabled" }, - "downloadSelectServiceToEnable": "Seçenekleri açmak için yerleşik bir sağlayıcı seçin", + "downloadSelectServiceToEnable": "Select a built-in service to enable", "@downloadSelectServiceToEnable": { "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" }, - "downloadSelectTidalQobuz": "Kaliteyi ayarlamak için lütfen yukarıdan Tidal veya Qobuz seçin", + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", "@downloadSelectTidalQobuz": { "description": "Info hint when non-Tidal/Qobuz service is selected" }, - "downloadEmbedLyricsDisabled": "Şarkı Verilerini Dosyaya Gömme ayarı kapalıyken kullanılamaz", + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", "@downloadEmbedLyricsDisabled": { "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" }, - "downloadNeteaseIncludeTranslation": "Netease: Çevirileri Dahil Et", + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", "@downloadNeteaseIncludeTranslation": { "description": "Toggle title for including Netease translated lyrics" }, - "downloadNeteaseIncludeTranslationEnabled": "Varsa, orijinal sözlere çevirilerini ekler", + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", "@downloadNeteaseIncludeTranslationEnabled": { "description": "Subtitle when Netease translation is enabled" }, - "downloadNeteaseIncludeTranslationDisabled": "Sadece şarkının kendi sözleri kullanılır", + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", "@downloadNeteaseIncludeTranslationDisabled": { "description": "Subtitle when Netease translation is disabled" }, - "downloadNeteaseIncludeRomanization": "Netease: Okunuşları (Romanizasyon) Dahil Et", + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", "@downloadNeteaseIncludeRomanization": { "description": "Toggle title for including Netease romanized lyrics" }, - "downloadNeteaseIncludeRomanizationEnabled": "Varsa, Asya şarkıları için Latin alfabesi okunuşlarını ekler", + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", "@downloadNeteaseIncludeRomanizationEnabled": { "description": "Subtitle when Netease romanization is enabled" }, - "downloadNeteaseIncludeRomanizationDisabled": "Kapalı", + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", "@downloadNeteaseIncludeRomanizationDisabled": { "description": "Subtitle when Netease romanization is disabled" }, - "downloadAppleQqMultiPerson": "Apple/QQ: Çoklu Sanatçı Düzeni (Kelime kelime akan sözler)", + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", "@downloadAppleQqMultiPerson": { "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" }, - "downloadAppleQqMultiPersonEnabled": "Gelişmiş v1/v2 ve arka plan [bg:] etiketlerini açık tutar", + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", "@downloadAppleQqMultiPersonEnabled": { "description": "Subtitle when multi-person word-by-word is enabled" }, - "downloadAppleQqMultiPersonDisabled": "Standart kelime kelime senkronizasyon kullanır", + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", "@downloadAppleQqMultiPersonDisabled": { "description": "Subtitle when multi-person word-by-word is disabled" }, - "downloadMusixmatchLanguage": "Musixmatch Tercih Edilen Dil", + "downloadMusixmatchLanguage": "Musixmatch Language", "@downloadMusixmatchLanguage": { "description": "Setting title for Musixmatch language preference" }, - "downloadMusixmatchLanguageAuto": "Otomatik (Orijinal Dil)", + "downloadMusixmatchLanguageAuto": "Auto (original)", "@downloadMusixmatchLanguageAuto": { "description": "Option label when Musixmatch uses original language" }, - "downloadFilterContributing": "Albüm Sanatçısı etiketinde konuk sanatçıları filtrele", + "downloadFilterContributing": "Filter contributing artists in Album Artist", "@downloadFilterContributing": { "description": "Toggle title for filtering contributing artists in Album Artist metadata" }, - "downloadFilterContributingEnabled": "Albüm Sanatçısı verisinde sadece ana sanatçı ismi tutulur", + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", "@downloadFilterContributingEnabled": { "description": "Subtitle when contributing artist filter is enabled" }, - "downloadFilterContributingDisabled": "Tüm sanatçı isimlerini olduğu gibi korur", + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", "@downloadFilterContributingDisabled": { "description": "Subtitle when contributing artist filter is disabled" }, - "downloadProvidersNoneEnabled": "Hiçbir sağlayıcı açık değil", + "downloadProvidersNoneEnabled": "None enabled", "@downloadProvidersNoneEnabled": { "description": "Subtitle for lyrics providers setting when no providers are enabled" }, - "downloadMusixmatchLanguageCode": "Dil Kodu", + "downloadMusixmatchLanguageCode": "Language code", "@downloadMusixmatchLanguageCode": { "description": "Label for the Musixmatch language code text field" }, - "downloadMusixmatchLanguageHint": "auto / tr / en / es", + "downloadMusixmatchLanguageHint": "auto / en / es / ja", "@downloadMusixmatchLanguageHint": { "description": "Hint text for the Musixmatch language code field" }, - "downloadMusixmatchLanguageDesc": "Tercih ettiğiniz söz dilini belirleyin (örnek: tr, en, es). Otomatik seçim için boş bırakın.", + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", "@downloadMusixmatchLanguageDesc": { "description": "Description in the Musixmatch language picker" }, - "downloadMusixmatchAuto": "Otomatik", + "downloadMusixmatchAuto": "Auto", "@downloadMusixmatchAuto": { "description": "Button to reset Musixmatch language to automatic" }, - "downloadNetworkAnySubtitle": "Wi-Fi + Mobil Veri üzerinden indir", + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", "@downloadNetworkAnySubtitle": { "description": "Subtitle for 'Any' network mode option" }, - "downloadNetworkWifiOnlySubtitle": "Wi-Fi'dan çıkarsanız indirmeler duraklatılır", + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", "@downloadNetworkWifiOnlySubtitle": { "description": "Subtitle for 'WiFi only' network mode option" }, - "downloadSongLinkRegionDesc": "Şarkı aramalarında SongLink API'ye iletilecek ülke kodunu belirler.", + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", "@downloadSongLinkRegionDesc": { "description": "Description in the SongLink region picker" }, - "downloadFolderOrganization": "Klasör Düzeni Seçimi", - "@downloadFolderOrganization": { - "description": "Title of the folder organization picker bottom sheet" - }, - "snackbarUnsupportedAudioFormat": "Bu ses formatı desteklenmiyor", + "snackbarUnsupportedAudioFormat": "Unsupported audio format", "@snackbarUnsupportedAudioFormat": { "description": "Snackbar when the audio format is not supported for the requested operation" }, - "cacheRefresh": "Yenile", + "cacheRefresh": "Refresh", "@cacheRefresh": { "description": "Tooltip for refresh button on cache management page" }, - "dialogDownloadPlaylistsMessage": "{playlistCount} {playlistCount, plural, =1{listeden} other{listeden}} toplam {trackCount} şarkı indirilsin mi?", + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", "@dialogDownloadPlaylistsMessage": { "description": "Dialog message for bulk playlist download confirmation", "placeholders": { @@ -3813,7 +3966,7 @@ } } }, - "bulkDownloadPlaylistsButton": "Seçili {count} {count, plural, =1{listeyi} other{listeyi}} indir", + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", "@bulkDownloadPlaylistsButton": { "description": "Button label for bulk downloading selected playlists", "placeholders": { @@ -3822,15 +3975,15 @@ } } }, - "bulkDownloadSelectPlaylists": "İndirilecek çalma listelerini seçin", + "bulkDownloadSelectPlaylists": "Select playlists to download", "@bulkDownloadSelectPlaylists": { "description": "Button label when no playlists are selected for download" }, - "snackbarSelectedPlaylistsEmpty": "Seçilen çalma listelerinde şarkı yok", + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", "@snackbarSelectedPlaylistsEmpty": { "description": "Snackbar when selected playlists contain no tracks" }, - "playlistsCount": "{count, plural, =1{1 çalma listesi} other{{count} çalma listesi}}", + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", "@playlistsCount": { "description": "Playlist count display", "placeholders": { @@ -3839,27 +3992,27 @@ } } }, - "editMetadataAutoFill": "İnternetten Otomatik Doldur", + "editMetadataAutoFill": "Auto-fill from online", "@editMetadataAutoFill": { "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" }, - "editMetadataAutoFillDesc": "İnternetteki verilerle otomatik doldurulmasını istediğiniz alanları seçin", + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", "@editMetadataAutoFillDesc": { "description": "Description for the auto-fill section" }, - "editMetadataAutoFillFetch": "Bul ve Doldur", + "editMetadataAutoFillFetch": "Fetch & Fill", "@editMetadataAutoFillFetch": { "description": "Button label to fetch online metadata and fill selected fields" }, - "editMetadataAutoFillSearching": "İnternette eşleşme aranıyor...", + "editMetadataAutoFillSearching": "Searching online...", "@editMetadataAutoFillSearching": { "description": "Snackbar shown while searching for online metadata" }, - "editMetadataAutoFillNoResults": "İnternette bu şarkıya uygun bir veri bulunamadı", + "editMetadataAutoFillNoResults": "No matching metadata found online", "@editMetadataAutoFillNoResults": { "description": "Snackbar when online metadata search returns no results" }, - "editMetadataAutoFillDone": "Şarkı verilerinden {count} {count, plural, =1{alan} other{alan}} internetten çekilerek dolduruldu", + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", "@editMetadataAutoFillDone": { "description": "Snackbar confirming how many fields were auto-filled", "placeholders": { @@ -3868,39 +4021,39 @@ } } }, - "editMetadataAutoFillNoneSelected": "Lütfen otomatik doldurulacak en az bir alan seçin", + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", "@editMetadataAutoFillNoneSelected": { "description": "Snackbar when user taps Fetch without selecting any fields" }, - "editMetadataFieldTitle": "Şarkı Adı", + "editMetadataFieldTitle": "Title", "@editMetadataFieldTitle": { "description": "Chip label for title field in auto-fill selector" }, - "editMetadataFieldArtist": "Sanatçı", + "editMetadataFieldArtist": "Artist", "@editMetadataFieldArtist": { "description": "Chip label for artist field in auto-fill selector" }, - "editMetadataFieldAlbum": "Albüm", + "editMetadataFieldAlbum": "Album", "@editMetadataFieldAlbum": { "description": "Chip label for album field in auto-fill selector" }, - "editMetadataFieldAlbumArtist": "Albüm Sanatçısı", + "editMetadataFieldAlbumArtist": "Album Artist", "@editMetadataFieldAlbumArtist": { "description": "Chip label for album artist field in auto-fill selector" }, - "editMetadataFieldDate": "Tarih", + "editMetadataFieldDate": "Date", "@editMetadataFieldDate": { "description": "Chip label for date field in auto-fill selector" }, - "editMetadataFieldTrackNum": "Şarkı Sırası", + "editMetadataFieldTrackNum": "Track #", "@editMetadataFieldTrackNum": { "description": "Chip label for track number field in auto-fill selector" }, - "editMetadataFieldDiscNum": "Disk #", + "editMetadataFieldDiscNum": "Disc #", "@editMetadataFieldDiscNum": { "description": "Chip label for disc number field in auto-fill selector" }, - "editMetadataFieldGenre": "Tür", + "editMetadataFieldGenre": "Genre", "@editMetadataFieldGenre": { "description": "Chip label for genre field in auto-fill selector" }, @@ -3908,27 +4061,27 @@ "@editMetadataFieldIsrc": { "description": "Chip label for ISRC field in auto-fill selector" }, - "editMetadataFieldLabel": "Plak Şirketi", + "editMetadataFieldLabel": "Label", "@editMetadataFieldLabel": { "description": "Chip label for label field in auto-fill selector" }, - "editMetadataFieldCopyright": "Telif Hakkı", + "editMetadataFieldCopyright": "Copyright", "@editMetadataFieldCopyright": { "description": "Chip label for copyright field in auto-fill selector" }, - "editMetadataFieldCover": "Albüm Kapağı", + "editMetadataFieldCover": "Cover Art", "@editMetadataFieldCover": { "description": "Chip label for cover art field in auto-fill selector" }, - "editMetadataSelectAll": "Tümü", + "editMetadataSelectAll": "All", "@editMetadataSelectAll": { "description": "Button to select all fields for auto-fill" }, - "editMetadataSelectEmpty": "Sadece boşlar", + "editMetadataSelectEmpty": "Empty only", "@editMetadataSelectEmpty": { "description": "Button to select only fields that are currently empty" }, - "queueDownloadingCount": "Şu An İnenler ({count})", + "queueDownloadingCount": "Downloading ({count})", "@queueDownloadingCount": { "description": "Header for active downloads section with count", "placeholders": { @@ -3937,15 +4090,15 @@ } } }, - "queueDownloadedHeader": "İnenler", + "queueDownloadedHeader": "Downloaded", "@queueDownloadedHeader": { "description": "Header label for downloaded items section in library" }, - "queueFilteringIndicator": "Filtreleniyor...", + "queueFilteringIndicator": "Filtering...", "@queueFilteringIndicator": { "description": "Shown while filter results are being computed" }, - "queueTrackCount": "{count, plural, =1{1 şarkı} other{{count} şarkı}}", + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", "@queueTrackCount": { "description": "Track count label with plural support", "placeholders": { @@ -3954,7 +4107,7 @@ } } }, - "queueAlbumCount": "{count, plural, =1{1 albüm} other{{count} albüm}}", + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", "@queueAlbumCount": { "description": "Album count label with plural support", "placeholders": { @@ -3963,92 +4116,398 @@ } } }, - "queueEmptyAlbums": "İndirilmiş bir albüm yok", + "queueEmptyAlbums": "No album downloads", "@queueEmptyAlbums": { "description": "Empty state title when no album downloads exist" }, - "queueEmptyAlbumsSubtitle": "Bir albümden birden fazla şarkı indirdiğinizde burada görünecektir.", + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", "@queueEmptyAlbumsSubtitle": { "description": "Empty state subtitle for album downloads" }, - "queueEmptySingles": "İndirilmiş bir şarkı yok", + "queueEmptySingles": "No single downloads", "@queueEmptySingles": { "description": "Empty state title when no single track downloads exist" }, - "queueEmptySinglesSubtitle": "Tek tek indirdiğiniz şarkılar burada görünecektir.", + "queueEmptySinglesSubtitle": "Single track downloads will appear here", "@queueEmptySinglesSubtitle": { "description": "Empty state subtitle for single track downloads" }, - "queueEmptyHistory": "İndirme geçmişi boş", + "queueEmptyHistory": "No download history", "@queueEmptyHistory": { "description": "Empty state title when download history is empty" }, - "queueEmptyHistorySubtitle": "İndirdiğiniz şarkılar başarıyla tamamlandığında burada görünecektir.", + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", "@queueEmptyHistorySubtitle": { "description": "Empty state subtitle for download history" }, - "selectionAllPlaylistsSelected": "Tüm listeler seçildi", + "selectionAllPlaylistsSelected": "All playlists selected", "@selectionAllPlaylistsSelected": { "description": "Shown when all playlists are selected in selection mode" }, - "selectionTapPlaylistsToSelect": "Seçmek için listelere dokunun", + "selectionTapPlaylistsToSelect": "Tap playlists to select", "@selectionTapPlaylistsToSelect": { "description": "Hint shown in playlist selection mode" }, - "selectionSelectPlaylistsToDelete": "Silinecek çalma listelerini seçin", + "selectionSelectPlaylistsToDelete": "Select playlists to delete", "@selectionSelectPlaylistsToDelete": { "description": "Hint shown when no playlists are selected for deletion" }, - "audioAnalysisTitle": "Ses Kalitesi Analizi", + "audioAnalysisTitle": "Audio Quality Analysis", "@audioAnalysisTitle": { "description": "Title for audio analysis section" }, - "audioAnalysisDescription": "Kayıpsız kalite doğrulaması için spektrum analizi yapın", + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", "@audioAnalysisDescription": { "description": "Description for audio analysis tap-to-analyze prompt" }, - "audioAnalysisAnalyzing": "Ses dosyası analiz ediliyor...", + "audioAnalysisAnalyzing": "Analyzing audio...", "@audioAnalysisAnalyzing": { "description": "Loading text while analyzing audio" }, - "audioAnalysisSampleRate": "Örnekleme Hızı (Sample Rate)", + "audioAnalysisSampleRate": "Sample Rate", "@audioAnalysisSampleRate": { "description": "Sample rate metric label" }, - "audioAnalysisBitDepth": "Bit Derinliği", + "audioAnalysisBitDepth": "Bit Depth", "@audioAnalysisBitDepth": { "description": "Bit depth metric label" }, - "audioAnalysisChannels": "Kanal", + "audioAnalysisChannels": "Channels", "@audioAnalysisChannels": { "description": "Channels metric label" }, - "audioAnalysisDuration": "Süre", + "audioAnalysisDuration": "Duration", "@audioAnalysisDuration": { "description": "Duration metric label" }, - "audioAnalysisNyquist": "Nyquist Frekansı", + "audioAnalysisNyquist": "Nyquist", "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, - "audioAnalysisFileSize": "Boyut", + "audioAnalysisFileSize": "Size", "@audioAnalysisFileSize": { "description": "File size metric label" }, - "audioAnalysisDynamicRange": "Dinamik Aralık", + "audioAnalysisDynamicRange": "Dynamic Range", "@audioAnalysisDynamicRange": { "description": "Dynamic range metric label" }, - "audioAnalysisPeak": "Tepe Değeri (Peak)", + "audioAnalysisPeak": "Peak", "@audioAnalysisPeak": { "description": "Peak amplitude metric label" }, - "audioAnalysisRms": "Ortalama Değer (RMS)", + "audioAnalysisRms": "RMS", "@audioAnalysisRms": { "description": "RMS level metric label" }, - "audioAnalysisSamples": "Toplam Örneklem (Samples)", + "audioAnalysisSamples": "Samples", "@audioAnalysisSamples": { "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } -} +} \ No newline at end of file diff --git a/lib/l10n/arb/app_zh_CN.arb b/lib/l10n/arb/app_zh_CN.arb index 928e2b4..5b27136 100644 --- a/lib/l10n/arb/app_zh_CN.arb +++ b/lib/l10n/arb/app_zh_CN.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "商店", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "粘贴 Spotify 链接或按名称搜索", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "文件夹结构", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "外观", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "点击 Deezer 或 Spotify 即可从扩展程序切换回来", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "并行下载数", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "扩展商店", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "在导航中显示商店标签", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "扩展商店", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Discard", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Play", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Built-in", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Request timed out. Try again later.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Default (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "No extensions with download provider", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Actual quality depends on track availability from the service", "@qualityNote": { "description": "Note about quality availability" @@ -1897,6 +2113,14 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Delete Selected", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Convert to MP3 or Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } -} \ No newline at end of file +} diff --git a/lib/l10n/arb/app_zh_TW.arb b/lib/l10n/arb/app_zh_TW.arb index 3f883b8..4d9a042 100644 --- a/lib/l10n/arb/app_zh_TW.arb +++ b/lib/l10n/arb/app_zh_TW.arb @@ -17,7 +17,7 @@ "@navSettings": { "description": "Bottom navigation - Settings tab" }, - "navStore": "Store", + "navStore": "Repo", "@navStore": { "description": "Bottom navigation - Extension store tab" }, @@ -25,7 +25,7 @@ "@homeTitle": { "description": "Home screen title" }, - "homeSubtitle": "Paste a Spotify link or search by name", + "homeSubtitle": "Paste a supported URL or search by name", "@homeSubtitle": { "description": "Subtitle shown below search box" }, @@ -89,9 +89,17 @@ "@downloadFilenameFormat": { "description": "Setting for output filename pattern" }, + "downloadSingleFilenameFormat": "Single Filename Format", + "@downloadSingleFilenameFormat": { + "description": "Setting for output filename pattern for singles/EPs" + }, + "downloadSingleFilenameFormatDescription": "Filename pattern for singles and EPs. Uses the same tags as the album format.", + "@downloadSingleFilenameFormatDescription": { + "description": "Subtitle description for single filename format setting" + }, "downloadFolderOrganization": "Folder Organization", "@downloadFolderOrganization": { - "description": "Setting for folder structure" + "description": "Title of the folder organization picker bottom sheet" }, "appearanceTitle": "Appearance", "@appearanceTitle": { @@ -150,6 +158,14 @@ } } }, + "optionsDefaultSearchTab": "Default Search Tab", + "@optionsDefaultSearchTab": { + "description": "Title for the preferred default search tab setting" + }, + "optionsDefaultSearchTabSubtitle": "Choose which tab opens first for new search results.", + "@optionsDefaultSearchTabSubtitle": { + "description": "Subtitle for the preferred default search tab setting" + }, "optionsSwitchBack": "Tap Deezer or Spotify to switch back from extension", "@optionsSwitchBack": { "description": "Hint to switch back to built-in providers" @@ -190,6 +206,42 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, + "optionsReplayGain": "ReplayGain", + "@optionsReplayGain": { + "description": "Title for ReplayGain setting toggle" + }, + "optionsReplayGainSubtitleOn": "Scan loudness and embed ReplayGain tags (EBU R128)", + "@optionsReplayGainSubtitleOn": { + "description": "Subtitle when ReplayGain is enabled" + }, + "optionsReplayGainSubtitleOff": "Disabled: no loudness normalization tags", + "@optionsReplayGainSubtitleOff": { + "description": "Subtitle when ReplayGain is disabled" + }, + "optionsArtistTagMode": "Artist Tag Mode", + "@optionsArtistTagMode": { + "description": "Setting title for how artist metadata is written into files" + }, + "optionsArtistTagModeDescription": "Choose how multiple artists are written into embedded tags.", + "@optionsArtistTagModeDescription": { + "description": "Bottom-sheet description for artist tag mode setting" + }, + "optionsArtistTagModeJoined": "Single joined value", + "@optionsArtistTagModeJoined": { + "description": "Artist tag mode option that joins multiple artists into one value" + }, + "optionsArtistTagModeJoinedSubtitle": "Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.", + "@optionsArtistTagModeJoinedSubtitle": { + "description": "Subtitle for joined artist tag mode" + }, + "optionsArtistTagModeSplitVorbis": "Split tags for FLAC/Opus", + "@optionsArtistTagModeSplitVorbis": { + "description": "Artist tag mode option that writes repeated ARTIST tags for Vorbis formats" + }, + "optionsArtistTagModeSplitVorbisSubtitle": "Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.", + "@optionsArtistTagModeSplitVorbisSubtitle": { + "description": "Subtitle for split Vorbis artist tag mode" + }, "optionsConcurrentDownloads": "Concurrent Downloads", "@optionsConcurrentDownloads": { "description": "Number of parallel downloads" @@ -211,11 +263,11 @@ "@optionsConcurrentWarning": { "description": "Warning about rate limits" }, - "optionsExtensionStore": "Extension Store", + "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" }, - "optionsExtensionStoreSubtitle": "Show Store tab in navigation", + "optionsExtensionStoreSubtitle": "Show Repo tab in navigation", "@optionsExtensionStoreSubtitle": { "description": "Subtitle for extension store toggle" }, @@ -318,7 +370,7 @@ "@extensionsUninstall": { "description": "Uninstall extension button" }, - "storeTitle": "Extension Store", + "storeTitle": "Extension Repo", "@storeTitle": { "description": "Store screen title" }, @@ -675,6 +727,10 @@ "@dialogImport": { "description": "Dialog button - import data" }, + "dialogDownload": "Download", + "@dialogDownload": { + "description": "Confirm button in Download All dialog" + }, "dialogDiscard": "Discard", "@dialogDiscard": { "description": "Dialog button - discard changes" @@ -999,6 +1055,46 @@ "@searchPlaylists": { "description": "Search result category - playlists" }, + "searchSortTitle": "Sort Results", + "@searchSortTitle": { + "description": "Bottom sheet title for search sort options" + }, + "searchSortDefault": "Default", + "@searchSortDefault": { + "description": "Sort option - default API order" + }, + "searchSortTitleAZ": "Title (A-Z)", + "@searchSortTitleAZ": { + "description": "Sort option - title ascending" + }, + "searchSortTitleZA": "Title (Z-A)", + "@searchSortTitleZA": { + "description": "Sort option - title descending" + }, + "searchSortArtistAZ": "Artist (A-Z)", + "@searchSortArtistAZ": { + "description": "Sort option - artist ascending" + }, + "searchSortArtistZA": "Artist (Z-A)", + "@searchSortArtistZA": { + "description": "Sort option - artist descending" + }, + "searchSortDurationShort": "Duration (Shortest)", + "@searchSortDurationShort": { + "description": "Sort option - shortest duration first" + }, + "searchSortDurationLong": "Duration (Longest)", + "@searchSortDurationLong": { + "description": "Sort option - longest duration first" + }, + "searchSortDateOldest": "Release Date (Oldest)", + "@searchSortDateOldest": { + "description": "Sort option - oldest release first" + }, + "searchSortDateNewest": "Release Date (Newest)", + "@searchSortDateNewest": { + "description": "Sort option - newest release first" + }, "tooltipPlay": "Play", "@tooltipPlay": { "description": "Tooltip - play button" @@ -1119,6 +1215,18 @@ "@providerPriorityInfo": { "description": "Info tip about fallback behavior" }, + "providerPriorityFallbackExtensionsTitle": "Extension Fallback", + "@providerPriorityFallbackExtensionsTitle": { + "description": "Section title for choosing which download extensions can be used as fallback providers" + }, + "providerPriorityFallbackExtensionsDescription": "Choose which installed download extensions can be used during automatic fallback. Built-in providers still follow the priority order above.", + "@providerPriorityFallbackExtensionsDescription": { + "description": "Section description for extension fallback selection" + }, + "providerPriorityFallbackExtensionsHint": "Only enabled extensions with download-provider capability are listed here.", + "@providerPriorityFallbackExtensionsHint": { + "description": "Hint below the extension fallback selection list" + }, "providerBuiltIn": "Built-in", "@providerBuiltIn": { "description": "Label for built-in providers (Tidal/Qobuz)" @@ -1479,6 +1587,14 @@ "@trackLyricsNotAvailable": { "description": "Message when lyrics not found" }, + "trackLyricsNotInFile": "No lyrics found in this file", + "@trackLyricsNotInFile": { + "description": "Message when no embedded lyrics in audio file" + }, + "trackFetchOnlineLyrics": "Fetch from Online", + "@trackFetchOnlineLyrics": { + "description": "Action - fetch lyrics from online providers" + }, "trackLyricsTimeout": "Request timed out. Try again later.", "@trackLyricsTimeout": { "description": "Message when lyrics request times out" @@ -1574,7 +1690,59 @@ "@storeClearFilters": { "description": "Button to clear all filters" }, - "extensionDefaultProvider": "Default (Deezer/Spotify)", + "storeAddRepoTitle": "Add Extension Repository", + "@storeAddRepoTitle": { + "description": "Store setup screen - heading when no repo is configured" + }, + "storeAddRepoDescription": "Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.", + "@storeAddRepoDescription": { + "description": "Store setup screen - explanatory text" + }, + "storeRepoUrlLabel": "Repository URL", + "@storeRepoUrlLabel": { + "description": "Label for the repository URL input field" + }, + "storeRepoUrlHint": "https://github.com/user/repo", + "@storeRepoUrlHint": { + "description": "Hint/placeholder for the repository URL input field" + }, + "storeRepoUrlHelper": "e.g. https://github.com/user/extensions-repo", + "@storeRepoUrlHelper": { + "description": "Helper text below the repository URL input field" + }, + "storeAddRepoButton": "Add Repository", + "@storeAddRepoButton": { + "description": "Button to submit a new repository URL" + }, + "storeChangeRepoTooltip": "Change repository", + "@storeChangeRepoTooltip": { + "description": "Tooltip for the change-repository icon button in the app bar" + }, + "storeRepoDialogTitle": "Extension Repository", + "@storeRepoDialogTitle": { + "description": "Title of the change/remove repository dialog" + }, + "storeRepoDialogCurrent": "Current repository:", + "@storeRepoDialogCurrent": { + "description": "Label shown above the current repository URL in the dialog" + }, + "storeNewRepoUrlLabel": "New Repository URL", + "@storeNewRepoUrlLabel": { + "description": "Label for the new repository URL field inside the dialog" + }, + "storeLoadError": "Failed to load repository", + "@storeLoadError": { + "description": "Error heading when the store cannot be loaded" + }, + "storeEmptyNoExtensions": "No extensions available", + "@storeEmptyNoExtensions": { + "description": "Message when store has no extensions" + }, + "storeEmptyNoResults": "No extensions found", + "@storeEmptyNoResults": { + "description": "Message when search/filter returns no results" + }, + "extensionDefaultProvider": "Default (Deezer)", "@extensionDefaultProvider": { "description": "Default search provider option" }, @@ -1713,6 +1881,14 @@ "@extensionsDownloadPrioritySubtitle": { "description": "Subtitle for download priority" }, + "extensionsFallbackTitle": "Fallback Extensions", + "@extensionsFallbackTitle": { + "description": "Setting and page title for choosing which download extensions can be used during fallback" + }, + "extensionsFallbackSubtitle": "Choose which installed download extensions can be used as fallback", + "@extensionsFallbackSubtitle": { + "description": "Subtitle for download fallback extensions menu" + }, "extensionsNoDownloadProvider": "No extensions with download provider", "@extensionsNoDownloadProvider": { "description": "Empty state - no download providers" @@ -1773,6 +1949,46 @@ "@qualityHiResFlacMaxSubtitle": { "description": "Technical spec for hi-res max" }, + "downloadLossy320": "Lossy 320kbps", + "@downloadLossy320": { + "description": "Quality option label for Tidal lossy 320kbps" + }, + "downloadLossyFormat": "Lossy Format", + "@downloadLossyFormat": { + "description": "Setting title to pick output format for Tidal lossy downloads" + }, + "downloadLossy320Format": "Lossy 320kbps Format", + "@downloadLossy320Format": { + "description": "Title of the Tidal lossy format picker bottom sheet" + }, + "downloadLossy320FormatDesc": "Choose the output format for Tidal 320kbps lossy downloads. The original AAC stream will be converted to your selected format.", + "@downloadLossy320FormatDesc": { + "description": "Description in the Tidal lossy format picker" + }, + "downloadLossyMp3": "MP3 320kbps", + "@downloadLossyMp3": { + "description": "Tidal lossy format option - MP3 320kbps" + }, + "downloadLossyMp3Subtitle": "Best compatibility, ~10MB per track", + "@downloadLossyMp3Subtitle": { + "description": "Subtitle for MP3 320kbps Tidal lossy option" + }, + "downloadLossyOpus256": "Opus 256kbps", + "@downloadLossyOpus256": { + "description": "Tidal lossy format option - Opus 256kbps" + }, + "downloadLossyOpus256Subtitle": "Best quality Opus, ~8MB per track", + "@downloadLossyOpus256Subtitle": { + "description": "Subtitle for Opus 256kbps Tidal lossy option" + }, + "downloadLossyOpus128": "Opus 128kbps", + "@downloadLossyOpus128": { + "description": "Tidal lossy format option - Opus 128kbps" + }, + "downloadLossyOpus128Subtitle": "Smallest size, ~4MB per track", + "@downloadLossyOpus128Subtitle": { + "description": "Subtitle for Opus 128kbps Tidal lossy option" + }, "qualityNote": "Actual quality depends on track availability from the service", "@qualityNote": { "description": "Note about quality availability" @@ -1897,6 +2113,14 @@ "@albumFolderArtistAlbumSinglesSubtitle": { "description": "Folder structure example" }, + "albumFolderArtistAlbumFlat": "Artist / Album (Singles flat)", + "@albumFolderArtistAlbumFlat": { + "description": "Album folder option with singles directly in artist folder" + }, + "albumFolderArtistAlbumFlatSubtitle": "Artist/Album/ and Artist/song.flac", + "@albumFolderArtistAlbumFlatSubtitle": { + "description": "Folder structure example for flat singles" + }, "downloadedAlbumDeleteSelected": "Delete Selected", "@downloadedAlbumDeleteSelected": { "description": "Button - delete selected tracks" @@ -2178,6 +2402,30 @@ "@libraryShowDuplicateIndicatorSubtitle": { "description": "Subtitle for duplicate indicator toggle" }, + "libraryAutoScan": "Auto Scan", + "@libraryAutoScan": { + "description": "Setting for automatic library scanning" + }, + "libraryAutoScanSubtitle": "Automatically scan your library for new files", + "@libraryAutoScanSubtitle": { + "description": "Subtitle for auto scan setting" + }, + "libraryAutoScanOff": "Off", + "@libraryAutoScanOff": { + "description": "Auto scan disabled" + }, + "libraryAutoScanOnOpen": "Every app open", + "@libraryAutoScanOnOpen": { + "description": "Auto scan when app opens" + }, + "libraryAutoScanDaily": "Daily", + "@libraryAutoScanDaily": { + "description": "Auto scan once per day" + }, + "libraryAutoScanWeekly": "Weekly", + "@libraryAutoScanWeekly": { + "description": "Auto scan once per week" + }, "libraryActions": "Actions", "@libraryActions": { "description": "Section header for library actions" @@ -2235,6 +2483,15 @@ } } }, + "libraryFilesUnit": "{count, plural, =1{file} other{files}}", + "@libraryFilesUnit": { + "description": "Unit label for files count during library scanning", + "placeholders": { + "count": { + "type": "int" + } + } + }, "libraryLastScanned": "Last scanned: {time}", "@libraryLastScanned": { "description": "Last scan time display", @@ -2252,6 +2509,10 @@ "@libraryScanning": { "description": "Status during scan" }, + "libraryScanFinalizing": "Finalizing library...", + "@libraryScanFinalizing": { + "description": "Status shown after file scanning finishes but library persistence is still running" + }, "libraryScanProgress": "{progress}% of {total} files", "@libraryScanProgress": { "description": "Scan progress display", @@ -2349,6 +2610,30 @@ "@libraryFilterFormat": { "description": "Filter section - file format" }, + "libraryFilterMetadata": "Metadata", + "@libraryFilterMetadata": { + "description": "Filter section - metadata completeness" + }, + "libraryFilterMetadataComplete": "Complete metadata", + "@libraryFilterMetadataComplete": { + "description": "Filter option - items with complete metadata" + }, + "libraryFilterMetadataMissingAny": "Missing any metadata", + "@libraryFilterMetadataMissingAny": { + "description": "Filter option - items missing any tracked metadata field" + }, + "libraryFilterMetadataMissingYear": "Missing year", + "@libraryFilterMetadataMissingYear": { + "description": "Filter option - items missing release year/date" + }, + "libraryFilterMetadataMissingGenre": "Missing genre", + "@libraryFilterMetadataMissingGenre": { + "description": "Filter option - items missing genre" + }, + "libraryFilterMetadataMissingAlbumArtist": "Missing album artist", + "@libraryFilterMetadataMissingAlbumArtist": { + "description": "Filter option - items missing album artist" + }, "libraryFilterSort": "Sort", "@libraryFilterSort": { "description": "Filter section - sort order" @@ -2361,6 +2646,22 @@ "@libraryFilterSortOldest": { "description": "Sort option - oldest first" }, + "libraryFilterSortAlbumAsc": "Album (A-Z)", + "@libraryFilterSortAlbumAsc": { + "description": "Sort option - album ascending" + }, + "libraryFilterSortAlbumDesc": "Album (Z-A)", + "@libraryFilterSortAlbumDesc": { + "description": "Sort option - album descending" + }, + "libraryFilterSortGenreAsc": "Genre (A-Z)", + "@libraryFilterSortGenreAsc": { + "description": "Sort option - genre ascending" + }, + "libraryFilterSortGenreDesc": "Genre (Z-A)", + "@libraryFilterSortGenreDesc": { + "description": "Sort option - genre descending" + }, "timeJustNow": "Just now", "@timeJustNow": { "description": "Relative time - less than a minute ago" @@ -2447,7 +2748,7 @@ "@tutorialExtensionsDesc": { "description": "Tutorial extensions page description" }, - "tutorialExtensionsTip1": "Browse the Store tab to discover useful extensions", + "tutorialExtensionsTip1": "Browse the Repo tab to discover useful extensions", "@tutorialExtensionsTip1": { "description": "Tutorial extensions tip 1" }, @@ -2713,6 +3014,38 @@ "@trackReEnrichOnlineSubtitle": { "description": "Subtitle for re-enrich metadata action for local items" }, + "trackReEnrichFieldsTitle": "Fields to update", + "@trackReEnrichFieldsTitle": { + "description": "Section title for field selection in re-enrich dialog" + }, + "trackReEnrichFieldCover": "Cover Art", + "@trackReEnrichFieldCover": { + "description": "Checkbox label for cover art field in re-enrich" + }, + "trackReEnrichFieldLyrics": "Lyrics", + "@trackReEnrichFieldLyrics": { + "description": "Checkbox label for lyrics field in re-enrich" + }, + "trackReEnrichFieldBasicTags": "Album, Album Artist", + "@trackReEnrichFieldBasicTags": { + "description": "Checkbox label for basic tags in re-enrich (title/artist are never overwritten)" + }, + "trackReEnrichFieldTrackInfo": "Track & Disc Number", + "@trackReEnrichFieldTrackInfo": { + "description": "Checkbox label for track info in re-enrich" + }, + "trackReEnrichFieldReleaseInfo": "Date & ISRC", + "@trackReEnrichFieldReleaseInfo": { + "description": "Checkbox label for release info in re-enrich" + }, + "trackReEnrichFieldExtra": "Genre, Label, Copyright", + "@trackReEnrichFieldExtra": { + "description": "Checkbox label for extra metadata in re-enrich" + }, + "trackReEnrichSelectAll": "Select All", + "@trackReEnrichSelectAll": { + "description": "Select all fields checkbox in re-enrich" + }, "trackEditMetadata": "Edit Metadata", "@trackEditMetadata": { "description": "Menu action - edit embedded metadata" @@ -2755,6 +3088,47 @@ "@trackReEnrichFfmpegFailed": { "description": "Snackbar when FFmpeg embed fails for MP3/Opus" }, + "queueFlacAction": "Queue FLAC", + "@queueFlacAction": { + "description": "Action/button label for queueing FLAC redownloads for local tracks" + }, + "queueFlacConfirmMessage": "Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected", + "@queueFlacConfirmMessage": { + "description": "Confirmation dialog body before queueing FLAC redownloads for local tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueFlacFindingProgress": "Finding FLAC matches... ({current}/{total})", + "@queueFlacFindingProgress": { + "description": "Snackbar while resolving remote matches for local FLAC redownloads", + "placeholders": { + "current": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "queueFlacNoReliableMatches": "No reliable online matches found for the selection", + "@queueFlacNoReliableMatches": { + "description": "Snackbar when no safe FLAC redownload matches were found" + }, + "queueFlacQueuedWithSkipped": "Added {addedCount} tracks to queue, skipped {skippedCount}", + "@queueFlacQueuedWithSkipped": { + "description": "Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped", + "placeholders": { + "addedCount": { + "type": "int" + }, + "skippedCount": { + "type": "int" + } + } + }, "trackSaveFailed": "Failed: {error}", "@trackSaveFailed": { "description": "Snackbar when save operation fails", @@ -2768,7 +3142,7 @@ "@trackConvertFormat": { "description": "Menu item - convert audio format" }, - "trackConvertFormatSubtitle": "Convert to MP3 or Opus", + "trackConvertFormatSubtitle": "Convert to MP3, Opus, ALAC, or FLAC", "@trackConvertFormatSubtitle": { "description": "Subtitle for convert format menu item" }, @@ -2803,6 +3177,22 @@ } } }, + "trackConvertConfirmMessageLossless": "Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.", + "@trackConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless-to-lossless conversion", + "placeholders": { + "sourceFormat": { + "type": "String" + }, + "targetFormat": { + "type": "String" + } + } + }, + "trackConvertLosslessHint": "Lossless conversion — no quality loss", + "@trackConvertLosslessHint": { + "description": "Hint shown when converting between lossless formats" + }, "trackConvertConverting": "Converting audio...", "@trackConvertConverting": { "description": "Snackbar while converting" @@ -3154,6 +3544,18 @@ } } }, + "selectionBatchConvertConfirmMessageLossless": "Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.", + "@selectionBatchConvertConfirmMessageLossless": { + "description": "Confirmation dialog message for lossless batch conversion", + "placeholders": { + "count": { + "type": "int" + }, + "format": { + "type": "String" + } + } + }, "selectionBatchConvertProgress": "Converting {current} of {total}...", "@selectionBatchConvertProgress": { "description": "Snackbar during batch conversion progress", @@ -3197,5 +3599,915 @@ "downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only", "@downloadUseAlbumArtistForFoldersTrackSubtitle": { "description": "Subtitle when Track Artist is used for folder naming" + }, + "lyricsProvidersTitle": "Lyrics Providers", + "@lyricsProvidersTitle": { + "description": "Title for the lyrics provider priority page" + }, + "lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.", + "@lyricsProvidersDescription": { + "description": "Description on the lyrics provider priority page" + }, + "lyricsProvidersInfoText": "Extension lyrics providers always run before built-in providers. At least one provider must remain enabled.", + "@lyricsProvidersInfoText": { + "description": "Info tip on lyrics provider priority page" + }, + "lyricsProvidersEnabledSection": "Enabled ({count})", + "@lyricsProvidersEnabledSection": { + "description": "Section header for enabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersDisabledSection": "Disabled ({count})", + "@lyricsProvidersDisabledSection": { + "description": "Section header for disabled providers", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "lyricsProvidersAtLeastOne": "At least one provider must remain enabled", + "@lyricsProvidersAtLeastOne": { + "description": "Snackbar when user tries to disable the last enabled provider" + }, + "lyricsProvidersSaved": "Lyrics provider priority saved", + "@lyricsProvidersSaved": { + "description": "Snackbar after saving lyrics provider priority" + }, + "lyricsProvidersDiscardContent": "You have unsaved changes that will be lost.", + "@lyricsProvidersDiscardContent": { + "description": "Body text of the discard-changes dialog on lyrics provider page" + }, + "lyricsProviderLrclibDesc": "Open-source synced lyrics database", + "@lyricsProviderLrclibDesc": { + "description": "Description for LRCLIB provider" + }, + "lyricsProviderNeteaseDesc": "NetEase Cloud Music (good for Asian songs)", + "@lyricsProviderNeteaseDesc": { + "description": "Description for Netease provider" + }, + "lyricsProviderMusixmatchDesc": "Largest lyrics database (multi-language)", + "@lyricsProviderMusixmatchDesc": { + "description": "Description for Musixmatch provider" + }, + "lyricsProviderAppleMusicDesc": "Word-by-word synced lyrics (via proxy)", + "@lyricsProviderAppleMusicDesc": { + "description": "Description for Apple Music provider" + }, + "lyricsProviderQqMusicDesc": "QQ Music (good for Chinese songs, via proxy)", + "@lyricsProviderQqMusicDesc": { + "description": "Description for QQ Music provider" + }, + "lyricsProviderExtensionDesc": "Extension provider", + "@lyricsProviderExtensionDesc": { + "description": "Generic description for extension-based lyrics providers" + }, + "safMigrationTitle": "Storage Update Required", + "@safMigrationTitle": { + "description": "Title of SAF migration dialog" + }, + "safMigrationMessage1": "SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.", + "@safMigrationMessage1": { + "description": "First paragraph of SAF migration dialog" + }, + "safMigrationMessage2": "Please select your download folder again to switch to the new storage system.", + "@safMigrationMessage2": { + "description": "Second paragraph of SAF migration dialog" + }, + "safMigrationSuccess": "Download folder updated to SAF mode", + "@safMigrationSuccess": { + "description": "Snackbar after successfully migrating to SAF" + }, + "settingsDonate": "Donate", + "@settingsDonate": { + "description": "Settings menu item - donate" + }, + "settingsDonateSubtitle": "Support SpotiFLAC-Mobile development", + "@settingsDonateSubtitle": { + "description": "Subtitle for donate menu item" + }, + "tooltipLoveAll": "Love All", + "@tooltipLoveAll": { + "description": "Tooltip for the Love All button on album/playlist screens" + }, + "tooltipAddToPlaylist": "Add to Playlist", + "@tooltipAddToPlaylist": { + "description": "Tooltip for the Add to Playlist button" + }, + "snackbarRemovedTracksFromLoved": "Removed {count} tracks from Loved", + "@snackbarRemovedTracksFromLoved": { + "description": "Snackbar after removing multiple tracks from Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "snackbarAddedTracksToLoved": "Added {count} tracks to Loved", + "@snackbarAddedTracksToLoved": { + "description": "Snackbar after adding multiple tracks to Loved folder", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "dialogDownloadAllTitle": "Download All", + "@dialogDownloadAllTitle": { + "description": "Dialog title for bulk download confirmation" + }, + "dialogDownloadAllMessage": "Download {count} tracks?", + "@dialogDownloadAllMessage": { + "description": "Body of the Download All confirmation dialog", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "homeSkipAlreadyDownloaded": "Skip already downloaded songs", + "@homeSkipAlreadyDownloaded": { + "description": "Checkbox label in import dialog to skip already-downloaded songs" + }, + "homeGoToAlbum": "Go to Album", + "@homeGoToAlbum": { + "description": "Context menu item to navigate to the album page" + }, + "homeAlbumInfoUnavailable": "Album info not available", + "@homeAlbumInfoUnavailable": { + "description": "Snackbar when album info cannot be loaded" + }, + "snackbarLoadingCueSheet": "Loading CUE sheet...", + "@snackbarLoadingCueSheet": { + "description": "Snackbar while loading a CUE sheet file" + }, + "snackbarMetadataSaved": "Metadata saved successfully", + "@snackbarMetadataSaved": { + "description": "Snackbar after successfully saving track metadata" + }, + "snackbarFailedToEmbedLyrics": "Failed to embed lyrics", + "@snackbarFailedToEmbedLyrics": { + "description": "Snackbar when lyrics embedding fails" + }, + "snackbarFailedToWriteStorage": "Failed to write back to storage", + "@snackbarFailedToWriteStorage": { + "description": "Snackbar when writing metadata back to file fails" + }, + "snackbarError": "Error: {error}", + "@snackbarError": { + "description": "Generic error snackbar with error detail", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "snackbarNoActionDefined": "No action defined for this button", + "@snackbarNoActionDefined": { + "description": "Snackbar when an extension button has no action configured" + }, + "noTracksFoundForAlbum": "No tracks found for this album", + "@noTracksFoundForAlbum": { + "description": "Empty state message when an album has no tracks" + }, + "downloadLocationSubtitle": "Choose storage mode for downloaded files.", + "@downloadLocationSubtitle": { + "description": "Subtitle text in Android download location bottom sheet" + }, + "storageModeAppFolder": "App folder (non-SAF)", + "@storageModeAppFolder": { + "description": "Storage mode option - use legacy app folder" + }, + "storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path", + "@storageModeAppFolderSubtitle": { + "description": "Subtitle for app folder storage mode" + }, + "storageModeSaf": "SAF folder", + "@storageModeSaf": { + "description": "Storage mode option - use Android SAF picker" + }, + "storageModeSafSubtitle": "Pick folder via Android Storage Access Framework", + "@storageModeSafSubtitle": { + "description": "Subtitle for SAF storage mode" + }, + "downloadFilenameDescription": "Customize how your files are named.", + "@downloadFilenameDescription": { + "description": "Description text in filename format bottom sheet" + }, + "downloadFilenameInsertTag": "Tap to insert tag:", + "@downloadFilenameInsertTag": { + "description": "Label above filename tag chips" + }, + "downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders", + "@downloadSeparateSinglesEnabled": { + "description": "Subtitle when separate singles folder is enabled" + }, + "downloadSeparateSinglesDisabled": "All files in same structure", + "@downloadSeparateSinglesDisabled": { + "description": "Subtitle when separate singles folder is disabled" + }, + "downloadArtistNameFilters": "Artist Name Filters", + "@downloadArtistNameFilters": { + "description": "Setting title for artist folder filter options" + }, + "downloadCreatePlaylistSourceFolder": "Create playlist source folder", + "@downloadCreatePlaylistSourceFolder": { + "description": "Setting title for adding a playlist folder prefix before the normal organization structure" + }, + "downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.", + "@downloadCreatePlaylistSourceFolderEnabled": { + "description": "Subtitle when playlist source folder prefix is enabled" + }, + "downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.", + "@downloadCreatePlaylistSourceFolderDisabled": { + "description": "Subtitle when playlist source folder prefix is disabled" + }, + "downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.", + "@downloadCreatePlaylistSourceFolderRedundant": { + "description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist" + }, + "downloadSongLinkRegion": "SongLink Region", + "@downloadSongLinkRegion": { + "description": "Setting title for SongLink country region" + }, + "downloadNetworkCompatibilityMode": "Network compatibility mode", + "@downloadNetworkCompatibilityMode": { + "description": "Setting title for network compatibility toggle" + }, + "downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)", + "@downloadNetworkCompatibilityModeEnabled": { + "description": "Subtitle when network compatibility mode is enabled" + }, + "downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)", + "@downloadNetworkCompatibilityModeDisabled": { + "description": "Subtitle when network compatibility mode is disabled" + }, + "downloadSelectServiceToEnable": "Select a built-in service to enable", + "@downloadSelectServiceToEnable": { + "description": "Hint shown instead of Ask-quality subtitle when no built-in service selected" + }, + "downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality", + "@downloadSelectTidalQobuz": { + "description": "Info hint when non-Tidal/Qobuz service is selected" + }, + "downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off", + "@downloadEmbedLyricsDisabled": { + "description": "Subtitle for Embed Lyrics when Embed Metadata is disabled" + }, + "downloadNeteaseIncludeTranslation": "Netease: Include Translation", + "@downloadNeteaseIncludeTranslation": { + "description": "Toggle title for including Netease translated lyrics" + }, + "downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available", + "@downloadNeteaseIncludeTranslationEnabled": { + "description": "Subtitle when Netease translation is enabled" + }, + "downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only", + "@downloadNeteaseIncludeTranslationDisabled": { + "description": "Subtitle when Netease translation is disabled" + }, + "downloadNeteaseIncludeRomanization": "Netease: Include Romanization", + "@downloadNeteaseIncludeRomanization": { + "description": "Toggle title for including Netease romanized lyrics" + }, + "downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available", + "@downloadNeteaseIncludeRomanizationEnabled": { + "description": "Subtitle when Netease romanization is enabled" + }, + "downloadNeteaseIncludeRomanizationDisabled": "Disabled", + "@downloadNeteaseIncludeRomanizationDisabled": { + "description": "Subtitle when Netease romanization is disabled" + }, + "downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word", + "@downloadAppleQqMultiPerson": { + "description": "Toggle title for Apple/QQ multi-person word-by-word lyrics" + }, + "downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags", + "@downloadAppleQqMultiPersonEnabled": { + "description": "Subtitle when multi-person word-by-word is enabled" + }, + "downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting", + "@downloadAppleQqMultiPersonDisabled": { + "description": "Subtitle when multi-person word-by-word is disabled" + }, + "downloadMusixmatchLanguage": "Musixmatch Language", + "@downloadMusixmatchLanguage": { + "description": "Setting title for Musixmatch language preference" + }, + "downloadMusixmatchLanguageAuto": "Auto (original)", + "@downloadMusixmatchLanguageAuto": { + "description": "Option label when Musixmatch uses original language" + }, + "downloadFilterContributing": "Filter contributing artists in Album Artist", + "@downloadFilterContributing": { + "description": "Toggle title for filtering contributing artists in Album Artist metadata" + }, + "downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only", + "@downloadFilterContributingEnabled": { + "description": "Subtitle when contributing artist filter is enabled" + }, + "downloadFilterContributingDisabled": "Keep full Album Artist metadata value", + "@downloadFilterContributingDisabled": { + "description": "Subtitle when contributing artist filter is disabled" + }, + "downloadProvidersNoneEnabled": "None enabled", + "@downloadProvidersNoneEnabled": { + "description": "Subtitle for lyrics providers setting when no providers are enabled" + }, + "downloadMusixmatchLanguageCode": "Language code", + "@downloadMusixmatchLanguageCode": { + "description": "Label for the Musixmatch language code text field" + }, + "downloadMusixmatchLanguageHint": "auto / en / es / ja", + "@downloadMusixmatchLanguageHint": { + "description": "Hint text for the Musixmatch language code field" + }, + "downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.", + "@downloadMusixmatchLanguageDesc": { + "description": "Description in the Musixmatch language picker" + }, + "downloadMusixmatchAuto": "Auto", + "@downloadMusixmatchAuto": { + "description": "Button to reset Musixmatch language to automatic" + }, + "downloadNetworkAnySubtitle": "WiFi + Mobile Data", + "@downloadNetworkAnySubtitle": { + "description": "Subtitle for 'Any' network mode option" + }, + "downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data", + "@downloadNetworkWifiOnlySubtitle": { + "description": "Subtitle for 'WiFi only' network mode option" + }, + "downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.", + "@downloadSongLinkRegionDesc": { + "description": "Description in the SongLink region picker" + }, + "snackbarUnsupportedAudioFormat": "Unsupported audio format", + "@snackbarUnsupportedAudioFormat": { + "description": "Snackbar when the audio format is not supported for the requested operation" + }, + "cacheRefresh": "Refresh", + "@cacheRefresh": { + "description": "Tooltip for refresh button on cache management page" + }, + "dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?", + "@dialogDownloadPlaylistsMessage": { + "description": "Dialog message for bulk playlist download confirmation", + "placeholders": { + "trackCount": { + "type": "int" + }, + "playlistCount": { + "type": "int" + } + } + }, + "bulkDownloadPlaylistsButton": "Download {count} {count, plural, =1{playlist} other{playlists}}", + "@bulkDownloadPlaylistsButton": { + "description": "Button label for bulk downloading selected playlists", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "bulkDownloadSelectPlaylists": "Select playlists to download", + "@bulkDownloadSelectPlaylists": { + "description": "Button label when no playlists are selected for download" + }, + "snackbarSelectedPlaylistsEmpty": "Selected playlists have no tracks", + "@snackbarSelectedPlaylistsEmpty": { + "description": "Snackbar when selected playlists contain no tracks" + }, + "playlistsCount": "{count, plural, =1{1 playlist} other{{count} playlists}}", + "@playlistsCount": { + "description": "Playlist count display", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFill": "Auto-fill from online", + "@editMetadataAutoFill": { + "description": "Section title for selective online metadata auto-fill in the edit metadata sheet" + }, + "editMetadataAutoFillDesc": "Select fields to fill automatically from online metadata", + "@editMetadataAutoFillDesc": { + "description": "Description for the auto-fill section" + }, + "editMetadataAutoFillFetch": "Fetch & Fill", + "@editMetadataAutoFillFetch": { + "description": "Button label to fetch online metadata and fill selected fields" + }, + "editMetadataAutoFillSearching": "Searching online...", + "@editMetadataAutoFillSearching": { + "description": "Snackbar shown while searching for online metadata" + }, + "editMetadataAutoFillNoResults": "No matching metadata found online", + "@editMetadataAutoFillNoResults": { + "description": "Snackbar when online metadata search returns no results" + }, + "editMetadataAutoFillDone": "Filled {count} {count, plural, =1{field} other{fields}} from online metadata", + "@editMetadataAutoFillDone": { + "description": "Snackbar confirming how many fields were auto-filled", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "editMetadataAutoFillNoneSelected": "Select at least one field to auto-fill", + "@editMetadataAutoFillNoneSelected": { + "description": "Snackbar when user taps Fetch without selecting any fields" + }, + "editMetadataFieldTitle": "Title", + "@editMetadataFieldTitle": { + "description": "Chip label for title field in auto-fill selector" + }, + "editMetadataFieldArtist": "Artist", + "@editMetadataFieldArtist": { + "description": "Chip label for artist field in auto-fill selector" + }, + "editMetadataFieldAlbum": "Album", + "@editMetadataFieldAlbum": { + "description": "Chip label for album field in auto-fill selector" + }, + "editMetadataFieldAlbumArtist": "Album Artist", + "@editMetadataFieldAlbumArtist": { + "description": "Chip label for album artist field in auto-fill selector" + }, + "editMetadataFieldDate": "Date", + "@editMetadataFieldDate": { + "description": "Chip label for date field in auto-fill selector" + }, + "editMetadataFieldTrackNum": "Track #", + "@editMetadataFieldTrackNum": { + "description": "Chip label for track number field in auto-fill selector" + }, + "editMetadataFieldDiscNum": "Disc #", + "@editMetadataFieldDiscNum": { + "description": "Chip label for disc number field in auto-fill selector" + }, + "editMetadataFieldGenre": "Genre", + "@editMetadataFieldGenre": { + "description": "Chip label for genre field in auto-fill selector" + }, + "editMetadataFieldIsrc": "ISRC", + "@editMetadataFieldIsrc": { + "description": "Chip label for ISRC field in auto-fill selector" + }, + "editMetadataFieldLabel": "Label", + "@editMetadataFieldLabel": { + "description": "Chip label for label field in auto-fill selector" + }, + "editMetadataFieldCopyright": "Copyright", + "@editMetadataFieldCopyright": { + "description": "Chip label for copyright field in auto-fill selector" + }, + "editMetadataFieldCover": "Cover Art", + "@editMetadataFieldCover": { + "description": "Chip label for cover art field in auto-fill selector" + }, + "editMetadataSelectAll": "All", + "@editMetadataSelectAll": { + "description": "Button to select all fields for auto-fill" + }, + "editMetadataSelectEmpty": "Empty only", + "@editMetadataSelectEmpty": { + "description": "Button to select only fields that are currently empty" + }, + "queueDownloadingCount": "Downloading ({count})", + "@queueDownloadingCount": { + "description": "Header for active downloads section with count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueDownloadedHeader": "Downloaded", + "@queueDownloadedHeader": { + "description": "Header label for downloaded items section in library" + }, + "queueFilteringIndicator": "Filtering...", + "@queueFilteringIndicator": { + "description": "Shown while filter results are being computed" + }, + "queueTrackCount": "{count, plural, =1{1 track} other{{count} tracks}}", + "@queueTrackCount": { + "description": "Track count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueAlbumCount": "{count, plural, =1{1 album} other{{count} albums}}", + "@queueAlbumCount": { + "description": "Album count label with plural support", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "queueEmptyAlbums": "No album downloads", + "@queueEmptyAlbums": { + "description": "Empty state title when no album downloads exist" + }, + "queueEmptyAlbumsSubtitle": "Download multiple tracks from an album to see them here", + "@queueEmptyAlbumsSubtitle": { + "description": "Empty state subtitle for album downloads" + }, + "queueEmptySingles": "No single downloads", + "@queueEmptySingles": { + "description": "Empty state title when no single track downloads exist" + }, + "queueEmptySinglesSubtitle": "Single track downloads will appear here", + "@queueEmptySinglesSubtitle": { + "description": "Empty state subtitle for single track downloads" + }, + "queueEmptyHistory": "No download history", + "@queueEmptyHistory": { + "description": "Empty state title when download history is empty" + }, + "queueEmptyHistorySubtitle": "Downloaded tracks will appear here", + "@queueEmptyHistorySubtitle": { + "description": "Empty state subtitle for download history" + }, + "selectionAllPlaylistsSelected": "All playlists selected", + "@selectionAllPlaylistsSelected": { + "description": "Shown when all playlists are selected in selection mode" + }, + "selectionTapPlaylistsToSelect": "Tap playlists to select", + "@selectionTapPlaylistsToSelect": { + "description": "Hint shown in playlist selection mode" + }, + "selectionSelectPlaylistsToDelete": "Select playlists to delete", + "@selectionSelectPlaylistsToDelete": { + "description": "Hint shown when no playlists are selected for deletion" + }, + "audioAnalysisTitle": "Audio Quality Analysis", + "@audioAnalysisTitle": { + "description": "Title for audio analysis section" + }, + "audioAnalysisDescription": "Verify lossless quality with spectrum analysis", + "@audioAnalysisDescription": { + "description": "Description for audio analysis tap-to-analyze prompt" + }, + "audioAnalysisAnalyzing": "Analyzing audio...", + "@audioAnalysisAnalyzing": { + "description": "Loading text while analyzing audio" + }, + "audioAnalysisSampleRate": "Sample Rate", + "@audioAnalysisSampleRate": { + "description": "Sample rate metric label" + }, + "audioAnalysisBitDepth": "Bit Depth", + "@audioAnalysisBitDepth": { + "description": "Bit depth metric label" + }, + "audioAnalysisChannels": "Channels", + "@audioAnalysisChannels": { + "description": "Channels metric label" + }, + "audioAnalysisDuration": "Duration", + "@audioAnalysisDuration": { + "description": "Duration metric label" + }, + "audioAnalysisNyquist": "Nyquist", + "@audioAnalysisNyquist": { + "description": "Nyquist frequency metric label" + }, + "audioAnalysisFileSize": "Size", + "@audioAnalysisFileSize": { + "description": "File size metric label" + }, + "audioAnalysisDynamicRange": "Dynamic Range", + "@audioAnalysisDynamicRange": { + "description": "Dynamic range metric label" + }, + "audioAnalysisPeak": "Peak", + "@audioAnalysisPeak": { + "description": "Peak amplitude metric label" + }, + "audioAnalysisRms": "RMS", + "@audioAnalysisRms": { + "description": "RMS level metric label" + }, + "audioAnalysisSamples": "Samples", + "@audioAnalysisSamples": { + "description": "Total samples metric label" + }, + "extensionsSearchWith": "Search with {providerName}", + "@extensionsSearchWith": { + "description": "Extensions page - subtitle for built-in search provider option", + "placeholders": { + "providerName": { + "type": "String" + } + } + }, + "extensionsHomeFeedProvider": "Home Feed Provider", + "@extensionsHomeFeedProvider": { + "description": "Extensions page - label for home feed provider selector" + }, + "extensionsHomeFeedDescription": "Choose which extension provides the home feed on the main screen", + "@extensionsHomeFeedDescription": { + "description": "Extensions page - description for home feed provider picker" + }, + "extensionsHomeFeedAuto": "Auto", + "@extensionsHomeFeedAuto": { + "description": "Extensions page - home feed provider option: auto" + }, + "extensionsHomeFeedAutoSubtitle": "Automatically select the best available", + "@extensionsHomeFeedAutoSubtitle": { + "description": "Extensions page - subtitle for auto home feed option" + }, + "extensionsHomeFeedUse": "Use {extensionName} home feed", + "@extensionsHomeFeedUse": { + "description": "Extensions page - subtitle for a specific extension home feed option", + "placeholders": { + "extensionName": { + "type": "String" + } + } + }, + "extensionsNoHomeFeedExtensions": "No extensions with home feed", + "@extensionsNoHomeFeedExtensions": { + "description": "Extensions page - shown when no installed extension has home feed" + }, + "sortAlphaAsc": "A-Z", + "@sortAlphaAsc": { + "description": "Sort option - alphabetical ascending" + }, + "sortAlphaDesc": "Z-A", + "@sortAlphaDesc": { + "description": "Sort option - alphabetical descending" + }, + "cancelDownloadTitle": "Cancel download?", + "@cancelDownloadTitle": { + "description": "Dialog title when confirming cancellation of an active download" + }, + "cancelDownloadContent": "This will cancel the active download for \"{trackName}\".", + "@cancelDownloadContent": { + "description": "Dialog body when confirming cancellation of an active download", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "cancelDownloadKeep": "Keep", + "@cancelDownloadKeep": { + "description": "Dialog button - keep the active download (do not cancel)" + }, + "metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg", + "@metadataSaveFailedFfmpeg": { + "description": "Snackbar error when FFmpeg fails to write metadata" + }, + "metadataSaveFailedStorage": "Failed to write metadata back to storage", + "@metadataSaveFailedStorage": { + "description": "Snackbar error when writing metadata file back to storage fails" + }, + "snackbarFolderPickerFailed": "Failed to open folder picker: {error}", + "@snackbarFolderPickerFailed": { + "description": "Snackbar shown when folder picker fails to open", + "placeholders": { + "error": { + "type": "String" + } + } + }, + "errorLoadAlbum": "Failed to load album", + "@errorLoadAlbum": { + "description": "Error state shown when album fails to load" + }, + "errorLoadPlaylist": "Failed to load playlist", + "@errorLoadPlaylist": { + "description": "Error state shown when playlist fails to load" + }, + "errorLoadArtist": "Failed to load artist", + "@errorLoadArtist": { + "description": "Error state shown when artist fails to load" + }, + "notifChannelDownloadName": "Download Progress", + "@notifChannelDownloadName": { + "description": "Android notification channel name for download progress" + }, + "notifChannelDownloadDesc": "Shows download progress for tracks", + "@notifChannelDownloadDesc": { + "description": "Android notification channel description for download progress" + }, + "notifChannelLibraryScanName": "Library Scan", + "@notifChannelLibraryScanName": { + "description": "Android notification channel name for library scan" + }, + "notifChannelLibraryScanDesc": "Shows local library scan progress", + "@notifChannelLibraryScanDesc": { + "description": "Android notification channel description for library scan" + }, + "notifDownloadingTrack": "Downloading {trackName}", + "@notifDownloadingTrack": { + "description": "Notification title while downloading a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifFinalizingTrack": "Finalizing {trackName}", + "@notifFinalizingTrack": { + "description": "Notification title while finalizing (embedding metadata) a track", + "placeholders": { + "trackName": { + "type": "String" + } + } + }, + "notifEmbeddingMetadata": "Embedding metadata...", + "@notifEmbeddingMetadata": { + "description": "Notification body while embedding metadata into a downloaded track" + }, + "notifAlreadyInLibraryCount": "Already in Library ({completed}/{total})", + "@notifAlreadyInLibraryCount": { + "description": "Notification title when track is already in library, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifAlreadyInLibrary": "Already in Library", + "@notifAlreadyInLibrary": { + "description": "Notification title when track is already in library" + }, + "notifDownloadCompleteCount": "Download Complete ({completed}/{total})", + "@notifDownloadCompleteCount": { + "description": "Notification title when download is complete, with count", + "placeholders": { + "completed": { + "type": "int" + }, + "total": { + "type": "int" + } + } + }, + "notifDownloadComplete": "Download Complete", + "@notifDownloadComplete": { + "description": "Notification title when a single download is complete" + }, + "notifDownloadsFinished": "Downloads Finished ({completed} done, {failed} failed)", + "@notifDownloadsFinished": { + "description": "Notification title when queue finishes with some failures", + "placeholders": { + "completed": { + "type": "int" + }, + "failed": { + "type": "int" + } + } + }, + "notifAllDownloadsComplete": "All Downloads Complete", + "@notifAllDownloadsComplete": { + "description": "Notification title when all downloads finish successfully" + }, + "notifTracksDownloadedSuccess": "{count} tracks downloaded successfully", + "@notifTracksDownloadedSuccess": { + "description": "Notification body for queue complete - how many tracks were downloaded", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifScanningLibrary": "Scanning local library", + "@notifScanningLibrary": { + "description": "Notification title while scanning local library" + }, + "notifLibraryScanProgressWithTotal": "{scanned}/{total} files • {percentage}%", + "@notifLibraryScanProgressWithTotal": { + "description": "Notification body for library scan progress when total is known", + "placeholders": { + "scanned": { + "type": "int" + }, + "total": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanProgressNoTotal": "{scanned} files scanned • {percentage}%", + "@notifLibraryScanProgressNoTotal": { + "description": "Notification body for library scan progress when total is unknown", + "placeholders": { + "scanned": { + "type": "int" + }, + "percentage": { + "type": "int" + } + } + }, + "notifLibraryScanComplete": "Library scan complete", + "@notifLibraryScanComplete": { + "description": "Notification title when library scan finishes" + }, + "notifLibraryScanCompleteBody": "{count} tracks indexed", + "@notifLibraryScanCompleteBody": { + "description": "Notification body for library scan complete - number of indexed tracks", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanExcluded": "{count} excluded", + "@notifLibraryScanExcluded": { + "description": "Library scan complete suffix - excluded track count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanErrors": "{count} errors", + "@notifLibraryScanErrors": { + "description": "Library scan complete suffix - error count", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "notifLibraryScanFailed": "Library scan failed", + "@notifLibraryScanFailed": { + "description": "Notification title when library scan fails" + }, + "notifLibraryScanCancelled": "Library scan cancelled", + "@notifLibraryScanCancelled": { + "description": "Notification title when library scan is cancelled by the user" + }, + "notifLibraryScanStopped": "Scan stopped before completion.", + "@notifLibraryScanStopped": { + "description": "Notification body when library scan is cancelled" + }, + "notifDownloadingUpdate": "Downloading SpotiFLAC v{version}", + "@notifDownloadingUpdate": { + "description": "Notification title while downloading an app update", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateProgress": "{received} / {total} MB • {percentage}%", + "@notifUpdateProgress": { + "description": "Notification body showing update download progress", + "placeholders": { + "received": { + "type": "String" + }, + "total": { + "type": "String" + }, + "percentage": { + "type": "int" + } + } + }, + "notifUpdateReady": "Update Ready", + "@notifUpdateReady": { + "description": "Notification title when app update download is complete" + }, + "notifUpdateReadyBody": "SpotiFLAC v{version} downloaded. Tap to install.", + "@notifUpdateReadyBody": { + "description": "Notification body when app update is ready to install", + "placeholders": { + "version": { + "type": "String" + } + } + }, + "notifUpdateFailed": "Update Failed", + "@notifUpdateFailed": { + "description": "Notification title when app update download fails" + }, + "notifUpdateFailedBody": "Could not download update. Try again later.", + "@notifUpdateFailedBody": { + "description": "Notification body when app update download fails" } -} \ No newline at end of file +}