Merge pull request #345 from Amonoman/main
Refactor settings into dedicated pages and update icons
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 954 B After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 647 B After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 603 B |
|
Before Width: | Height: | Size: 905 B After Width: | Height: | Size: 966 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 783 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 905 B After Width: | Height: | Size: 966 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.3 KiB |
@@ -121,7 +121,7 @@
|
|||||||
"@appearanceDynamicColor": {
|
"@appearanceDynamicColor": {
|
||||||
"description": "Material You dynamic colors"
|
"description": "Material You dynamic colors"
|
||||||
},
|
},
|
||||||
"appearanceDynamicColorSubtitle": "Farben von Ihrem Hintergrundbild verwenden",
|
"appearanceDynamicColorSubtitle": "Farben deines Hintergrundbilds verwenden",
|
||||||
"@appearanceDynamicColorSubtitle": {
|
"@appearanceDynamicColorSubtitle": {
|
||||||
"description": "Subtitle for dynamic color"
|
"description": "Subtitle for dynamic color"
|
||||||
},
|
},
|
||||||
@@ -178,7 +178,7 @@
|
|||||||
"@optionsAutoFallbackSubtitle": {
|
"@optionsAutoFallbackSubtitle": {
|
||||||
"description": "Subtitle for auto fallback"
|
"description": "Subtitle for auto fallback"
|
||||||
},
|
},
|
||||||
"optionsUseExtensionProviders": "Erweiterungs-Anbieter verwenden",
|
"optionsUseExtensionProviders": "Erweiterungsanbieter verwenden",
|
||||||
"@optionsUseExtensionProviders": {
|
"@optionsUseExtensionProviders": {
|
||||||
"description": "Enable extension download providers"
|
"description": "Enable extension download providers"
|
||||||
},
|
},
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
"@optionsEmbedLyrics": {
|
"@optionsEmbedLyrics": {
|
||||||
"description": "Embed lyrics in audio files"
|
"description": "Embed lyrics in audio files"
|
||||||
},
|
},
|
||||||
"optionsEmbedLyricsSubtitle": "Synchronisierte Lyrics in FLAC-Dateien einbetten",
|
"optionsEmbedLyricsSubtitle": "Synchronisierte Songtexte neben heruntergeladenen Titeln speichern",
|
||||||
"@optionsEmbedLyricsSubtitle": {
|
"@optionsEmbedLyricsSubtitle": {
|
||||||
"description": "Subtitle for embed lyrics"
|
"description": "Subtitle for embed lyrics"
|
||||||
},
|
},
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
"@optionsArtistTagModeJoined": {
|
"@optionsArtistTagModeJoined": {
|
||||||
"description": "Artist tag mode option that joins multiple artists into one value"
|
"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": "Einen Künstler-Wert wie \"Künstler A, Künstler B\" für maximale Player-Kompatibilität schreiben.",
|
||||||
"@optionsArtistTagModeJoinedSubtitle": {
|
"@optionsArtistTagModeJoinedSubtitle": {
|
||||||
"description": "Subtitle for joined artist tag mode"
|
"description": "Subtitle for joined artist tag mode"
|
||||||
},
|
},
|
||||||
@@ -438,7 +438,7 @@
|
|||||||
"@aboutReportIssue": {
|
"@aboutReportIssue": {
|
||||||
"description": "Link to report bugs"
|
"description": "Link to report bugs"
|
||||||
},
|
},
|
||||||
"aboutReportIssueSubtitle": "Melde jedes Problem, die dir auftreten",
|
"aboutReportIssueSubtitle": "Melde Probleme, die dir auffallen",
|
||||||
"@aboutReportIssueSubtitle": {
|
"@aboutReportIssueSubtitle": {
|
||||||
"description": "Subtitle for report issue"
|
"description": "Subtitle for report issue"
|
||||||
},
|
},
|
||||||
@@ -486,7 +486,7 @@
|
|||||||
"@aboutSachinsenalDesc": {
|
"@aboutSachinsenalDesc": {
|
||||||
"description": "Credit description for sachinsenal0x64"
|
"description": "Credit description for sachinsenal0x64"
|
||||||
},
|
},
|
||||||
"aboutSjdonadoDesc": "Ersteller von I Don't Have Spotify (IDHS). Der Fallback-Link-Resolver, der den Tag rettete!",
|
"aboutSjdonadoDesc": "Ersteller von I Don't Have Spotify (IDHS). Der Fallback-Link-Resolver, der den Tag rettet!",
|
||||||
"@aboutSjdonadoDesc": {
|
"@aboutSjdonadoDesc": {
|
||||||
"description": "Credit description for sjdonado"
|
"description": "Credit description for sjdonado"
|
||||||
},
|
},
|
||||||
@@ -576,7 +576,7 @@
|
|||||||
"@setupPermissionDeniedMessage": {
|
"@setupPermissionDeniedMessage": {
|
||||||
"description": "Error when permission denied"
|
"description": "Error when permission denied"
|
||||||
},
|
},
|
||||||
"setupPermissionRequired": "{permissionType} Zugriff verweigert",
|
"setupPermissionRequired": "{permissionType}-Berechtigung erforderlich",
|
||||||
"@setupPermissionRequired": {
|
"@setupPermissionRequired": {
|
||||||
"description": "Generic permission required title",
|
"description": "Generic permission required title",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
@@ -586,7 +586,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"setupPermissionRequiredMessage": "{permissionType} Berechtigung ist erforderlich für\ndie beste Benutzererfahrung. Für kannst dies später in den Einstellungen ändern.",
|
"setupPermissionRequiredMessage": "{permissionType}-Berechtigung ist erforderlich für\ndie beste Benutzererfahrung. Du kannst dies später in den Einstellungen ändern.",
|
||||||
"@setupPermissionRequiredMessage": {
|
"@setupPermissionRequiredMessage": {
|
||||||
"description": "Generic permission required message",
|
"description": "Generic permission required message",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
@@ -603,7 +603,7 @@
|
|||||||
"@setupNoFolderSelected": {
|
"@setupNoFolderSelected": {
|
||||||
"description": "Prompt when no folder selected"
|
"description": "Prompt when no folder selected"
|
||||||
},
|
},
|
||||||
"setupUseDefault": "Standart benutzen",
|
"setupUseDefault": "Standard verwenden",
|
||||||
"@setupUseDefault": {
|
"@setupUseDefault": {
|
||||||
"description": "Button to use default folder"
|
"description": "Button to use default folder"
|
||||||
},
|
},
|
||||||
@@ -663,7 +663,7 @@
|
|||||||
"@setupNotificationEnable": {
|
"@setupNotificationEnable": {
|
||||||
"description": "Button to enable notifications"
|
"description": "Button to enable notifications"
|
||||||
},
|
},
|
||||||
"setupFolderChoose": "Speicherort auwählen",
|
"setupFolderChoose": "Speicherort auswählen",
|
||||||
"@setupFolderChoose": {
|
"@setupFolderChoose": {
|
||||||
"description": "Button to choose folder"
|
"description": "Button to choose folder"
|
||||||
},
|
},
|
||||||
@@ -747,7 +747,7 @@
|
|||||||
"@dialogDiscardChanges": {
|
"@dialogDiscardChanges": {
|
||||||
"description": "Dialog title - unsaved changes warning"
|
"description": "Dialog title - unsaved changes warning"
|
||||||
},
|
},
|
||||||
"dialogUnsavedChanges": "Hast du noch nicht alle Änderungen gespeichert. Möchtest du die Änderungen verwerfen?",
|
"dialogUnsavedChanges": "Du hast ungespeicherte Änderungen. Möchtest du sie verwerfen?",
|
||||||
"@dialogUnsavedChanges": {
|
"@dialogUnsavedChanges": {
|
||||||
"description": "Dialog message - unsaved changes"
|
"description": "Dialog message - unsaved changes"
|
||||||
},
|
},
|
||||||
@@ -759,7 +759,7 @@
|
|||||||
"@dialogRemoveExtension": {
|
"@dialogRemoveExtension": {
|
||||||
"description": "Dialog title - uninstall extension"
|
"description": "Dialog title - uninstall extension"
|
||||||
},
|
},
|
||||||
"dialogRemoveExtensionMessage": "Bist Du sicher, dass Du diese Erweiterung entfernen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.",
|
"dialogRemoveExtensionMessage": "Bist du sicher, dass du diese Erweiterung entfernen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||||
"@dialogRemoveExtensionMessage": {
|
"@dialogRemoveExtensionMessage": {
|
||||||
"description": "Dialog message - uninstall confirmation"
|
"description": "Dialog message - uninstall confirmation"
|
||||||
},
|
},
|
||||||
@@ -767,7 +767,7 @@
|
|||||||
"@dialogUninstallExtension": {
|
"@dialogUninstallExtension": {
|
||||||
"description": "Dialog title - uninstall extension"
|
"description": "Dialog title - uninstall extension"
|
||||||
},
|
},
|
||||||
"dialogUninstallExtensionMessage": "Bist du dir sicher, dass du {extensionName} entfernen möchtest?",
|
"dialogUninstallExtensionMessage": "Bist du sicher, dass du {extensionName} entfernen möchtest?",
|
||||||
"@dialogUninstallExtensionMessage": {
|
"@dialogUninstallExtensionMessage": {
|
||||||
"description": "Dialog message - uninstall specific extension",
|
"description": "Dialog message - uninstall specific extension",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
@@ -780,7 +780,7 @@
|
|||||||
"@dialogClearHistoryTitle": {
|
"@dialogClearHistoryTitle": {
|
||||||
"description": "Dialog title - clear download history"
|
"description": "Dialog title - clear download history"
|
||||||
},
|
},
|
||||||
"dialogClearHistoryMessage": "Bist du dir sicher, dass du den gesamten Download verlauf löschen möchten? Dies kann nicht rückgängig gemacht werden.",
|
"dialogClearHistoryMessage": "Bist du sicher, dass du den gesamten Downloadverlauf löschen möchtest? Dies kann nicht rückgängig gemacht werden.",
|
||||||
"@dialogClearHistoryMessage": {
|
"@dialogClearHistoryMessage": {
|
||||||
"description": "Dialog message - clear history confirmation"
|
"description": "Dialog message - clear history confirmation"
|
||||||
},
|
},
|
||||||
@@ -846,7 +846,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"snackbarAlreadyInLibrary": "\"{trackName}\" existiert bereits in Ihrer Bibliothek",
|
"snackbarAlreadyInLibrary": "\"{trackName}\" existiert bereits in deiner Bibliothek",
|
||||||
"@snackbarAlreadyInLibrary": {
|
"@snackbarAlreadyInLibrary": {
|
||||||
"description": "Snackbar - track already exists in local library",
|
"description": "Snackbar - track already exists in local library",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
@@ -867,7 +867,7 @@
|
|||||||
"@snackbarCredentialsCleared": {
|
"@snackbarCredentialsCleared": {
|
||||||
"description": "Snackbar - Spotify credentials removed"
|
"description": "Snackbar - Spotify credentials removed"
|
||||||
},
|
},
|
||||||
"snackbarDeletedTracks": "{count} {count, plural, one {}=1{Titel} other{Titel}}",
|
"snackbarDeletedTracks": "{count} {count, plural, =1{Titel gelöscht} other{Titel gelöscht}}",
|
||||||
"@snackbarDeletedTracks": {
|
"@snackbarDeletedTracks": {
|
||||||
"description": "Snackbar - tracks deleted",
|
"description": "Snackbar - tracks deleted",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
@@ -969,7 +969,7 @@
|
|||||||
"@errorUrlFetchFailed": {
|
"@errorUrlFetchFailed": {
|
||||||
"description": "Error message - generic URL fetch failure"
|
"description": "Error message - generic URL fetch failure"
|
||||||
},
|
},
|
||||||
"errorMissingExtensionSource": "Kann {item} nicht lade wegen fehlender Erweiterungsquelle",
|
"errorMissingExtensionSource": "Kann {item} nicht laden wegen fehlender Erweiterungsquelle",
|
||||||
"@errorMissingExtensionSource": {
|
"@errorMissingExtensionSource": {
|
||||||
"description": "Error - extension source not available",
|
"description": "Error - extension source not available",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
@@ -1287,7 +1287,7 @@
|
|||||||
"@logClearLogsTitle": {
|
"@logClearLogsTitle": {
|
||||||
"description": "Clear logs dialog title"
|
"description": "Clear logs dialog title"
|
||||||
},
|
},
|
||||||
"logClearLogsMessage": "Bist du dir sicher, dass Sie alle Protokolle löschen möchtest?",
|
"logClearLogsMessage": "Bist du sicher, dass du alle Protokolle löschen möchtest?",
|
||||||
"@logClearLogsMessage": {
|
"@logClearLogsMessage": {
|
||||||
"description": "Clear logs confirmation message"
|
"description": "Clear logs confirmation message"
|
||||||
},
|
},
|
||||||
@@ -2462,7 +2462,7 @@
|
|||||||
"@libraryClearConfirmTitle": {
|
"@libraryClearConfirmTitle": {
|
||||||
"description": "Dialog title for clear confirmation"
|
"description": "Dialog title for clear confirmation"
|
||||||
},
|
},
|
||||||
"libraryClearConfirmMessage": "Dadurch werden alle gescannten Titel aus Ihrer Bibliothek entfernt. Ihre eigentlichen Musikdateien werden nicht gelöscht.",
|
"libraryClearConfirmMessage": "Dadurch werden alle gescannten Titel aus deiner Bibliothek entfernt. Deine eigentlichen Musikdateien werden nicht gelöscht.",
|
||||||
"@libraryClearConfirmMessage": {
|
"@libraryClearConfirmMessage": {
|
||||||
"description": "Dialog message for clear confirmation"
|
"description": "Dialog message for clear confirmation"
|
||||||
},
|
},
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"@@locale": "en",
|
"@@locale": "en",
|
||||||
"@@last_modified": "2026-01-16",
|
"@@last_modified": "2026-04-28",
|
||||||
"appName": "SpotiFLAC",
|
"appName": "SpotiFLAC",
|
||||||
"@appName": {
|
"@appName": {
|
||||||
"description": "App name - DO NOT TRANSLATE"
|
"description": "App name - DO NOT TRANSLATE"
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
},
|
},
|
||||||
"downloadFolderOrganization": "Folder Organization",
|
"downloadFolderOrganization": "Folder Organization",
|
||||||
"@downloadFolderOrganization": {
|
"@downloadFolderOrganization": {
|
||||||
"description": "Setting for folder structure"
|
"description": "Title of the folder organization picker bottom sheet"
|
||||||
},
|
},
|
||||||
"appearanceTitle": "Appearance",
|
"appearanceTitle": "Appearance",
|
||||||
"@appearanceTitle": {
|
"@appearanceTitle": {
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
"@optionsPrimaryProvider": {
|
"@optionsPrimaryProvider": {
|
||||||
"description": "Main search provider setting"
|
"description": "Main search provider setting"
|
||||||
},
|
},
|
||||||
"optionsPrimaryProviderSubtitle": "Service used when searching by track name.",
|
"optionsPrimaryProviderSubtitle": "Service used for searching by track or album name",
|
||||||
"@optionsPrimaryProviderSubtitle": {
|
"@optionsPrimaryProviderSubtitle": {
|
||||||
"description": "Subtitle for primary provider"
|
"description": "Subtitle for primary provider"
|
||||||
},
|
},
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
"@optionsEmbedLyrics": {
|
"@optionsEmbedLyrics": {
|
||||||
"description": "Embed lyrics in audio files"
|
"description": "Embed lyrics in audio files"
|
||||||
},
|
},
|
||||||
"optionsEmbedLyricsSubtitle": "Embed synced lyrics into FLAC files",
|
"optionsEmbedLyricsSubtitle": "Save synced lyrics alongside your downloaded tracks",
|
||||||
"@optionsEmbedLyricsSubtitle": {
|
"@optionsEmbedLyricsSubtitle": {
|
||||||
"description": "Subtitle for embed lyrics"
|
"description": "Subtitle for embed lyrics"
|
||||||
},
|
},
|
||||||
@@ -729,7 +729,7 @@
|
|||||||
},
|
},
|
||||||
"dialogDownload": "Download",
|
"dialogDownload": "Download",
|
||||||
"@dialogDownload": {
|
"@dialogDownload": {
|
||||||
"description": "Dialog button - download action"
|
"description": "Confirm button in Download All dialog"
|
||||||
},
|
},
|
||||||
"dialogDiscard": "Discard",
|
"dialogDiscard": "Discard",
|
||||||
"@dialogDiscard": {
|
"@dialogDiscard": {
|
||||||
@@ -1449,11 +1449,11 @@
|
|||||||
"@settingsAppearanceSubtitle": {
|
"@settingsAppearanceSubtitle": {
|
||||||
"description": "Appearance settings description"
|
"description": "Appearance settings description"
|
||||||
},
|
},
|
||||||
"settingsDownloadSubtitle": "Service, quality, filename format",
|
"settingsDownloadSubtitle": "Service, quality, fallback",
|
||||||
"@settingsDownloadSubtitle": {
|
"@settingsDownloadSubtitle": {
|
||||||
"description": "Download settings description"
|
"description": "Download settings description"
|
||||||
},
|
},
|
||||||
"settingsOptionsSubtitle": "Fallback, lyrics, cover art, updates",
|
"settingsOptionsSubtitle": "Fallback, metadata, lyrics, cover art",
|
||||||
"@settingsOptionsSubtitle": {
|
"@settingsOptionsSubtitle": {
|
||||||
"description": "Options settings description"
|
"description": "Options settings description"
|
||||||
},
|
},
|
||||||
@@ -3592,18 +3592,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"downloadUseAlbumArtistForFoldersAlbumSubtitle": "Artist folders use Album Artist when available",
|
"downloadUseAlbumArtistForFoldersAlbumSubtitle": "Folder named after Album Artist tag",
|
||||||
"@downloadUseAlbumArtistForFoldersAlbumSubtitle": {
|
"@downloadUseAlbumArtistForFoldersAlbumSubtitle": {
|
||||||
"description": "Subtitle when Album Artist is used for folder naming"
|
"description": "Subtitle when album artist is used for folder names"
|
||||||
},
|
},
|
||||||
"downloadUseAlbumArtistForFoldersTrackSubtitle": "Artist folders use Track Artist only",
|
"downloadUseAlbumArtistForFoldersTrackSubtitle": "Folder named after Track Artist tag",
|
||||||
"@downloadUseAlbumArtistForFoldersTrackSubtitle": {
|
"@downloadUseAlbumArtistForFoldersTrackSubtitle": {
|
||||||
"description": "Subtitle when Track Artist is used for folder naming"
|
"description": "Subtitle when track artist is used for folder names"
|
||||||
},
|
},
|
||||||
|
"lyricsProvidersTitle": "Lyrics Provider Priority",
|
||||||
"lyricsProvidersTitle": "Lyrics Providers",
|
|
||||||
"@lyricsProvidersTitle": {
|
"@lyricsProvidersTitle": {
|
||||||
"description": "Title for the lyrics provider priority page"
|
"description": "Settings item title for lyrics provider order"
|
||||||
},
|
},
|
||||||
"lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.",
|
"lyricsProvidersDescription": "Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.",
|
||||||
"@lyricsProvidersDescription": {
|
"@lyricsProvidersDescription": {
|
||||||
@@ -3667,7 +3666,6 @@
|
|||||||
"@lyricsProviderExtensionDesc": {
|
"@lyricsProviderExtensionDesc": {
|
||||||
"description": "Generic description for extension-based lyrics providers"
|
"description": "Generic description for extension-based lyrics providers"
|
||||||
},
|
},
|
||||||
|
|
||||||
"safMigrationTitle": "Storage Update Required",
|
"safMigrationTitle": "Storage Update Required",
|
||||||
"@safMigrationTitle": {
|
"@safMigrationTitle": {
|
||||||
"description": "Title of SAF migration dialog"
|
"description": "Title of SAF migration dialog"
|
||||||
@@ -3684,16 +3682,14 @@
|
|||||||
"@safMigrationSuccess": {
|
"@safMigrationSuccess": {
|
||||||
"description": "Snackbar after successfully migrating to SAF"
|
"description": "Snackbar after successfully migrating to SAF"
|
||||||
},
|
},
|
||||||
|
"settingsDonate": "Support Development",
|
||||||
"settingsDonate": "Donate",
|
|
||||||
"@settingsDonate": {
|
"@settingsDonate": {
|
||||||
"description": "Settings menu item - donate"
|
"description": "Settings menu item - donate page"
|
||||||
},
|
},
|
||||||
"settingsDonateSubtitle": "Support SpotiFLAC-Mobile development",
|
"settingsDonateSubtitle": "Buy the developer a coffee",
|
||||||
"@settingsDonateSubtitle": {
|
"@settingsDonateSubtitle": {
|
||||||
"description": "Subtitle for donate menu item"
|
"description": "Subtitle for donate menu item"
|
||||||
},
|
},
|
||||||
|
|
||||||
"tooltipLoveAll": "Love All",
|
"tooltipLoveAll": "Love All",
|
||||||
"@tooltipLoveAll": {
|
"@tooltipLoveAll": {
|
||||||
"description": "Tooltip for the Love All button on album/playlist screens"
|
"description": "Tooltip for the Love All button on album/playlist screens"
|
||||||
@@ -3720,10 +3716,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"dialogDownloadAllTitle": "Download All",
|
"dialogDownloadAllTitle": "Download All",
|
||||||
"@dialogDownloadAllTitle": {
|
"@dialogDownloadAllTitle": {
|
||||||
"description": "Title of the Download All confirmation dialog"
|
"description": "Dialog title for bulk download confirmation"
|
||||||
},
|
},
|
||||||
"dialogDownloadAllMessage": "Download {count} tracks?",
|
"dialogDownloadAllMessage": "Download {count} tracks?",
|
||||||
"@dialogDownloadAllMessage": {
|
"@dialogDownloadAllMessage": {
|
||||||
@@ -3734,11 +3729,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dialogDownload": "Download",
|
|
||||||
"@dialogDownload": {
|
|
||||||
"description": "Confirm button in Download All dialog"
|
|
||||||
},
|
|
||||||
|
|
||||||
"homeSkipAlreadyDownloaded": "Skip already downloaded songs",
|
"homeSkipAlreadyDownloaded": "Skip already downloaded songs",
|
||||||
"@homeSkipAlreadyDownloaded": {
|
"@homeSkipAlreadyDownloaded": {
|
||||||
"description": "Checkbox label in import dialog to skip already-downloaded songs"
|
"description": "Checkbox label in import dialog to skip already-downloaded songs"
|
||||||
@@ -3751,7 +3741,6 @@
|
|||||||
"@homeAlbumInfoUnavailable": {
|
"@homeAlbumInfoUnavailable": {
|
||||||
"description": "Snackbar when album info cannot be loaded"
|
"description": "Snackbar when album info cannot be loaded"
|
||||||
},
|
},
|
||||||
|
|
||||||
"snackbarLoadingCueSheet": "Loading CUE sheet...",
|
"snackbarLoadingCueSheet": "Loading CUE sheet...",
|
||||||
"@snackbarLoadingCueSheet": {
|
"@snackbarLoadingCueSheet": {
|
||||||
"description": "Snackbar while loading a CUE sheet file"
|
"description": "Snackbar while loading a CUE sheet file"
|
||||||
@@ -3781,190 +3770,181 @@
|
|||||||
"@snackbarNoActionDefined": {
|
"@snackbarNoActionDefined": {
|
||||||
"description": "Snackbar when an extension button has no action configured"
|
"description": "Snackbar when an extension button has no action configured"
|
||||||
},
|
},
|
||||||
|
|
||||||
"noTracksFoundForAlbum": "No tracks found for this album",
|
"noTracksFoundForAlbum": "No tracks found for this album",
|
||||||
"@noTracksFoundForAlbum": {
|
"@noTracksFoundForAlbum": {
|
||||||
"description": "Empty state message when an album has no tracks"
|
"description": "Empty state message when an album has no tracks"
|
||||||
},
|
},
|
||||||
|
"downloadLocationSubtitle": "Choose where to save your downloaded tracks",
|
||||||
"downloadLocationSubtitle": "Choose storage mode for downloaded files.",
|
|
||||||
"@downloadLocationSubtitle": {
|
"@downloadLocationSubtitle": {
|
||||||
"description": "Subtitle text in Android download location bottom sheet"
|
"description": "Subtitle shown in the download location picker sheet"
|
||||||
},
|
},
|
||||||
"storageModeAppFolder": "App folder (non-SAF)",
|
"storageModeAppFolder": "App Folder (Recommended)",
|
||||||
"@storageModeAppFolder": {
|
"@storageModeAppFolder": {
|
||||||
"description": "Storage mode option - use legacy app folder"
|
"description": "Storage mode option - app-managed folder"
|
||||||
},
|
},
|
||||||
"storageModeAppFolderSubtitle": "Use default Music/SpotiFLAC path",
|
"storageModeAppFolderSubtitle": "Saves to Music/SpotiFLAC by default",
|
||||||
"@storageModeAppFolderSubtitle": {
|
"@storageModeAppFolderSubtitle": {
|
||||||
"description": "Subtitle for app folder storage mode"
|
"description": "Subtitle for app folder storage mode"
|
||||||
},
|
},
|
||||||
"storageModeSaf": "SAF folder",
|
"storageModeSaf": "Custom Folder (SAF)",
|
||||||
"@storageModeSaf": {
|
"@storageModeSaf": {
|
||||||
"description": "Storage mode option - use Android SAF picker"
|
"description": "Storage mode option - Storage Access Framework"
|
||||||
},
|
},
|
||||||
"storageModeSafSubtitle": "Pick folder via Android Storage Access Framework",
|
"storageModeSafSubtitle": "Pick any folder, including SD card",
|
||||||
"@storageModeSafSubtitle": {
|
"@storageModeSafSubtitle": {
|
||||||
"description": "Subtitle for SAF storage mode"
|
"description": "Subtitle for SAF storage mode"
|
||||||
},
|
},
|
||||||
"downloadFilenameDescription": "Customize how your files are named.",
|
"downloadFilenameDescription": "Use {artist}, {title}, {album}, {track}, {year}, {date}, {disc} as placeholders.",
|
||||||
"@downloadFilenameDescription": {
|
"@downloadFilenameDescription": {
|
||||||
"description": "Description text in filename format bottom sheet"
|
"description": "Description shown in filename format editor"
|
||||||
},
|
},
|
||||||
"downloadFilenameInsertTag": "Tap to insert tag:",
|
"downloadFilenameInsertTag": "Tap to insert tag:",
|
||||||
"@downloadFilenameInsertTag": {
|
"@downloadFilenameInsertTag": {
|
||||||
"description": "Label above filename tag chips"
|
"description": "Label above filename tag chips"
|
||||||
},
|
},
|
||||||
"downloadSeparateSinglesEnabled": "Albums/ and Singles/ folders",
|
"downloadSeparateSinglesEnabled": "Singles and EPs saved in a separate folder",
|
||||||
"@downloadSeparateSinglesEnabled": {
|
"@downloadSeparateSinglesEnabled": {
|
||||||
"description": "Subtitle when separate singles folder is enabled"
|
"description": "Subtitle when separate singles folder is on"
|
||||||
},
|
},
|
||||||
"downloadSeparateSinglesDisabled": "All files in same structure",
|
"downloadSeparateSinglesDisabled": "Singles and albums saved in the same folder",
|
||||||
"@downloadSeparateSinglesDisabled": {
|
"@downloadSeparateSinglesDisabled": {
|
||||||
"description": "Subtitle when separate singles folder is disabled"
|
"description": "Subtitle when separate singles folder is off"
|
||||||
},
|
},
|
||||||
"downloadArtistNameFilters": "Artist Name Filters",
|
"downloadArtistNameFilters": "Artist Name Filters",
|
||||||
"@downloadArtistNameFilters": {
|
"@downloadArtistNameFilters": {
|
||||||
"description": "Setting title for artist folder filter options"
|
"description": "Setting title for artist folder filter options"
|
||||||
},
|
},
|
||||||
"downloadCreatePlaylistSourceFolder": "Create playlist source folder",
|
"downloadCreatePlaylistSourceFolder": "Playlist Source Folder",
|
||||||
"@downloadCreatePlaylistSourceFolder": {
|
"@downloadCreatePlaylistSourceFolder": {
|
||||||
"description": "Setting title for adding a playlist folder prefix before the normal organization structure"
|
"description": "Setting to create a subfolder per playlist source"
|
||||||
},
|
},
|
||||||
"downloadCreatePlaylistSourceFolderEnabled": "Playlist downloads use Playlist/ plus your normal folder structure.",
|
"downloadCreatePlaylistSourceFolderEnabled": "A subfolder is created for each playlist",
|
||||||
"@downloadCreatePlaylistSourceFolderEnabled": {
|
"@downloadCreatePlaylistSourceFolderEnabled": {
|
||||||
"description": "Subtitle when playlist source folder prefix is enabled"
|
"description": "Subtitle when playlist folder is enabled"
|
||||||
},
|
},
|
||||||
"downloadCreatePlaylistSourceFolderDisabled": "Playlist downloads use the normal folder structure only.",
|
"downloadCreatePlaylistSourceFolderDisabled": "All tracks saved directly to download folder",
|
||||||
"@downloadCreatePlaylistSourceFolderDisabled": {
|
"@downloadCreatePlaylistSourceFolderDisabled": {
|
||||||
"description": "Subtitle when playlist source folder prefix is disabled"
|
"description": "Subtitle when playlist folder is disabled"
|
||||||
},
|
},
|
||||||
"downloadCreatePlaylistSourceFolderRedundant": "By Playlist already places downloads inside a playlist folder.",
|
"downloadCreatePlaylistSourceFolderRedundant": "Handled by folder organization setting",
|
||||||
"@downloadCreatePlaylistSourceFolderRedundant": {
|
"@downloadCreatePlaylistSourceFolderRedundant": {
|
||||||
"description": "Subtitle when playlist folder prefix setting is redundant because folder organization is already by playlist"
|
"description": "Subtitle when folder organization is already set to playlist"
|
||||||
},
|
},
|
||||||
"downloadSongLinkRegion": "SongLink Region",
|
"downloadSongLinkRegion": "SongLink Region",
|
||||||
"@downloadSongLinkRegion": {
|
"@downloadSongLinkRegion": {
|
||||||
"description": "Setting title for SongLink country region"
|
"description": "Setting for SongLink region used during fallback resolution"
|
||||||
},
|
},
|
||||||
"downloadNetworkCompatibilityMode": "Network compatibility mode",
|
"downloadNetworkCompatibilityMode": "Network Compatibility Mode",
|
||||||
"@downloadNetworkCompatibilityMode": {
|
"@downloadNetworkCompatibilityMode": {
|
||||||
"description": "Setting title for network compatibility toggle"
|
"description": "Setting for legacy TLS/network handling"
|
||||||
},
|
},
|
||||||
"downloadNetworkCompatibilityModeEnabled": "Enabled: try HTTP + accept invalid TLS certificates (unsafe)",
|
"downloadNetworkCompatibilityModeEnabled": "Using legacy TLS settings for older networks",
|
||||||
"@downloadNetworkCompatibilityModeEnabled": {
|
"@downloadNetworkCompatibilityModeEnabled": {
|
||||||
"description": "Subtitle when network compatibility mode is enabled"
|
"description": "Subtitle when network compatibility mode is on"
|
||||||
},
|
},
|
||||||
"downloadNetworkCompatibilityModeDisabled": "Off: strict HTTPS certificate validation (recommended)",
|
"downloadNetworkCompatibilityModeDisabled": "Using standard network settings",
|
||||||
"@downloadNetworkCompatibilityModeDisabled": {
|
"@downloadNetworkCompatibilityModeDisabled": {
|
||||||
"description": "Subtitle when network compatibility mode is disabled"
|
"description": "Subtitle when network compatibility mode is off"
|
||||||
},
|
},
|
||||||
"downloadSelectServiceToEnable": "Select a built-in service to enable",
|
"downloadSelectServiceToEnable": "Select Tidal or Qobuz to enable this option",
|
||||||
"@downloadSelectServiceToEnable": {
|
"@downloadSelectServiceToEnable": {
|
||||||
"description": "Hint shown instead of Ask-quality subtitle when no built-in service selected"
|
"description": "Subtitle when quality picker is disabled due to extension service"
|
||||||
},
|
},
|
||||||
|
"downloadSelectTidalQobuz": "Select Tidal or Qobuz to choose audio quality",
|
||||||
"downloadSelectTidalQobuz": "Select Tidal or Qobuz above to configure quality",
|
|
||||||
"@downloadSelectTidalQobuz": {
|
"@downloadSelectTidalQobuz": {
|
||||||
"description": "Info hint when non-Tidal/Qobuz service is selected"
|
"description": "Info shown when a non-built-in service is selected"
|
||||||
},
|
},
|
||||||
"downloadEmbedLyricsDisabled": "Disabled while Embed Metadata is turned off",
|
"downloadEmbedLyricsDisabled": "Enable metadata embedding first",
|
||||||
"@downloadEmbedLyricsDisabled": {
|
"@downloadEmbedLyricsDisabled": {
|
||||||
"description": "Subtitle for Embed Lyrics when Embed Metadata is disabled"
|
"description": "Subtitle when lyrics embedding is blocked by metadata toggle"
|
||||||
},
|
},
|
||||||
"downloadNeteaseIncludeTranslation": "Netease: Include Translation",
|
"downloadNeteaseIncludeTranslation": "Netease: Include Translation",
|
||||||
"@downloadNeteaseIncludeTranslation": {
|
"@downloadNeteaseIncludeTranslation": {
|
||||||
"description": "Toggle title for including Netease translated lyrics"
|
"description": "Setting to include translated lyrics from Netease"
|
||||||
},
|
},
|
||||||
"downloadNeteaseIncludeTranslationEnabled": "Append translated lyrics when available",
|
"downloadNeteaseIncludeTranslationEnabled": "Chinese translation lines included",
|
||||||
"@downloadNeteaseIncludeTranslationEnabled": {
|
"@downloadNeteaseIncludeTranslationEnabled": {
|
||||||
"description": "Subtitle when Netease translation is enabled"
|
"description": "Subtitle when Netease translation is on"
|
||||||
},
|
},
|
||||||
"downloadNeteaseIncludeTranslationDisabled": "Use original lyrics only",
|
"downloadNeteaseIncludeTranslationDisabled": "Original lyrics only",
|
||||||
"@downloadNeteaseIncludeTranslationDisabled": {
|
"@downloadNeteaseIncludeTranslationDisabled": {
|
||||||
"description": "Subtitle when Netease translation is disabled"
|
"description": "Subtitle when Netease translation is off"
|
||||||
},
|
},
|
||||||
"downloadNeteaseIncludeRomanization": "Netease: Include Romanization",
|
"downloadNeteaseIncludeRomanization": "Netease: Include Romanization",
|
||||||
"@downloadNeteaseIncludeRomanization": {
|
"@downloadNeteaseIncludeRomanization": {
|
||||||
"description": "Toggle title for including Netease romanized lyrics"
|
"description": "Setting to include romanized lyrics from Netease"
|
||||||
},
|
},
|
||||||
"downloadNeteaseIncludeRomanizationEnabled": "Append romanized lyrics when available",
|
"downloadNeteaseIncludeRomanizationEnabled": "Romanization lines included",
|
||||||
"@downloadNeteaseIncludeRomanizationEnabled": {
|
"@downloadNeteaseIncludeRomanizationEnabled": {
|
||||||
"description": "Subtitle when Netease romanization is enabled"
|
"description": "Subtitle when Netease romanization is on"
|
||||||
},
|
},
|
||||||
"downloadNeteaseIncludeRomanizationDisabled": "Disabled",
|
"downloadNeteaseIncludeRomanizationDisabled": "No romanization",
|
||||||
"@downloadNeteaseIncludeRomanizationDisabled": {
|
"@downloadNeteaseIncludeRomanizationDisabled": {
|
||||||
"description": "Subtitle when Netease romanization is disabled"
|
"description": "Subtitle when Netease romanization is off"
|
||||||
},
|
},
|
||||||
"downloadAppleQqMultiPerson": "Apple/QQ Multi-Person Word-by-Word",
|
"downloadAppleQqMultiPerson": "Apple / QQ: Multi-Person Lyrics",
|
||||||
"@downloadAppleQqMultiPerson": {
|
"@downloadAppleQqMultiPerson": {
|
||||||
"description": "Toggle title for Apple/QQ multi-person word-by-word lyrics"
|
"description": "Setting for word-by-word multi-person lyrics from Apple Music and QQ Music"
|
||||||
},
|
},
|
||||||
"downloadAppleQqMultiPersonEnabled": "Enable v1/v2 speaker and [bg:] tags",
|
"downloadAppleQqMultiPersonEnabled": "Speaker labels included for duets and group tracks",
|
||||||
"@downloadAppleQqMultiPersonEnabled": {
|
"@downloadAppleQqMultiPersonEnabled": {
|
||||||
"description": "Subtitle when multi-person word-by-word is enabled"
|
"description": "Subtitle when multi-person lyrics is on"
|
||||||
},
|
},
|
||||||
"downloadAppleQqMultiPersonDisabled": "Simplified word-by-word formatting",
|
"downloadAppleQqMultiPersonDisabled": "Standard lyrics without speaker labels",
|
||||||
"@downloadAppleQqMultiPersonDisabled": {
|
"@downloadAppleQqMultiPersonDisabled": {
|
||||||
"description": "Subtitle when multi-person word-by-word is disabled"
|
"description": "Subtitle when multi-person lyrics is off"
|
||||||
},
|
},
|
||||||
"downloadMusixmatchLanguage": "Musixmatch Language",
|
"downloadMusixmatchLanguage": "Musixmatch Language",
|
||||||
"@downloadMusixmatchLanguage": {
|
"@downloadMusixmatchLanguage": {
|
||||||
"description": "Setting title for Musixmatch language preference"
|
"description": "Setting for Musixmatch lyrics translation language"
|
||||||
},
|
},
|
||||||
"downloadMusixmatchLanguageAuto": "Auto (original)",
|
"downloadMusixmatchLanguageAuto": "Auto (original language)",
|
||||||
"@downloadMusixmatchLanguageAuto": {
|
"@downloadMusixmatchLanguageAuto": {
|
||||||
"description": "Option label when Musixmatch uses original language"
|
"description": "Subtitle when no language is set"
|
||||||
},
|
},
|
||||||
"downloadFilterContributing": "Filter contributing artists in Album Artist",
|
"downloadFilterContributing": "Filter Contributing Artists",
|
||||||
"@downloadFilterContributing": {
|
"@downloadFilterContributing": {
|
||||||
"description": "Toggle title for filtering contributing artists in Album Artist metadata"
|
"description": "Setting to strip contributing artists from Album Artist folder name"
|
||||||
},
|
},
|
||||||
"downloadFilterContributingEnabled": "Album Artist metadata uses primary artist only",
|
"downloadFilterContributingEnabled": "Contributing artists removed from Album Artist folder name",
|
||||||
"@downloadFilterContributingEnabled": {
|
"@downloadFilterContributingEnabled": {
|
||||||
"description": "Subtitle when contributing artist filter is enabled"
|
"description": "Subtitle when contributing artist filter is on"
|
||||||
},
|
},
|
||||||
"downloadFilterContributingDisabled": "Keep full Album Artist metadata value",
|
"downloadFilterContributingDisabled": "Full Album Artist string used",
|
||||||
"@downloadFilterContributingDisabled": {
|
"@downloadFilterContributingDisabled": {
|
||||||
"description": "Subtitle when contributing artist filter is disabled"
|
"description": "Subtitle when contributing artist filter is off"
|
||||||
},
|
},
|
||||||
|
"downloadProvidersNoneEnabled": "No providers enabled",
|
||||||
"downloadProvidersNoneEnabled": "None enabled",
|
|
||||||
"@downloadProvidersNoneEnabled": {
|
"@downloadProvidersNoneEnabled": {
|
||||||
"description": "Subtitle for lyrics providers setting when no providers are enabled"
|
"description": "Shown when no lyrics providers are active"
|
||||||
},
|
},
|
||||||
"downloadMusixmatchLanguageCode": "Language code",
|
"downloadMusixmatchLanguageCode": "Language code",
|
||||||
"@downloadMusixmatchLanguageCode": {
|
"@downloadMusixmatchLanguageCode": {
|
||||||
"description": "Label for the Musixmatch language code text field"
|
"description": "Label for Musixmatch language input field"
|
||||||
},
|
},
|
||||||
"downloadMusixmatchLanguageHint": "auto / en / es / ja",
|
"downloadMusixmatchLanguageHint": "e.g. en, de, ja",
|
||||||
"@downloadMusixmatchLanguageHint": {
|
"@downloadMusixmatchLanguageHint": {
|
||||||
"description": "Hint text for the Musixmatch language code field"
|
"description": "Placeholder for Musixmatch language input"
|
||||||
},
|
},
|
||||||
"downloadMusixmatchLanguageDesc": "Set preferred language code (example: en, es, ja). Leave empty for auto.",
|
"downloadMusixmatchLanguageDesc": "Enter a BCP-47 language code (e.g. en, de, ja) to request translated lyrics from Musixmatch.",
|
||||||
"@downloadMusixmatchLanguageDesc": {
|
"@downloadMusixmatchLanguageDesc": {
|
||||||
"description": "Description in the Musixmatch language picker"
|
"description": "Description in Musixmatch language picker"
|
||||||
},
|
},
|
||||||
"downloadMusixmatchAuto": "Auto",
|
"downloadMusixmatchAuto": "Auto",
|
||||||
"@downloadMusixmatchAuto": {
|
"@downloadMusixmatchAuto": {
|
||||||
"description": "Button to reset Musixmatch language to automatic"
|
"description": "Button to clear Musixmatch language (use auto)"
|
||||||
},
|
},
|
||||||
|
"downloadNetworkAnySubtitle": "Use WiFi or mobile data",
|
||||||
"downloadNetworkAnySubtitle": "WiFi + Mobile Data",
|
|
||||||
"@downloadNetworkAnySubtitle": {
|
"@downloadNetworkAnySubtitle": {
|
||||||
"description": "Subtitle for 'Any' network mode option"
|
"description": "Subtitle for any-network option in picker"
|
||||||
},
|
},
|
||||||
"downloadNetworkWifiOnlySubtitle": "Pause downloads on mobile data",
|
"downloadNetworkWifiOnlySubtitle": "Downloads pause when on mobile data",
|
||||||
"@downloadNetworkWifiOnlySubtitle": {
|
"@downloadNetworkWifiOnlySubtitle": {
|
||||||
"description": "Subtitle for 'WiFi only' network mode option"
|
"description": "Subtitle for WiFi-only option in picker"
|
||||||
},
|
},
|
||||||
"downloadSongLinkRegionDesc": "Used as userCountry for SongLink API lookup.",
|
"downloadSongLinkRegionDesc": "Region used when resolving track links via SongLink. Choose the country where your streaming services are available.",
|
||||||
"@downloadSongLinkRegionDesc": {
|
"@downloadSongLinkRegionDesc": {
|
||||||
"description": "Description in the SongLink region picker"
|
"description": "Description in SongLink region picker"
|
||||||
},
|
|
||||||
"downloadFolderOrganization": "Folder Organization",
|
|
||||||
"@downloadFolderOrganization": {
|
|
||||||
"description": "Title of the folder organization picker bottom sheet"
|
|
||||||
},
|
},
|
||||||
"snackbarUnsupportedAudioFormat": "Unsupported audio format",
|
"snackbarUnsupportedAudioFormat": "Unsupported audio format",
|
||||||
"@snackbarUnsupportedAudioFormat": {
|
"@snackbarUnsupportedAudioFormat": {
|
||||||
@@ -3974,10 +3954,6 @@
|
|||||||
"@cacheRefresh": {
|
"@cacheRefresh": {
|
||||||
"description": "Tooltip for refresh button on cache management page"
|
"description": "Tooltip for refresh button on cache management page"
|
||||||
},
|
},
|
||||||
"dialogDownloadAllTitle": "Download All",
|
|
||||||
"@dialogDownloadAllTitle": {
|
|
||||||
"description": "Dialog title for bulk download confirmation"
|
|
||||||
},
|
|
||||||
"dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?",
|
"dialogDownloadPlaylistsMessage": "Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?",
|
||||||
"@dialogDownloadPlaylistsMessage": {
|
"@dialogDownloadPlaylistsMessage": {
|
||||||
"description": "Dialog message for bulk playlist download confirmation",
|
"description": "Dialog message for bulk playlist download confirmation",
|
||||||
@@ -4105,7 +4081,6 @@
|
|||||||
"@editMetadataSelectEmpty": {
|
"@editMetadataSelectEmpty": {
|
||||||
"description": "Button to select only fields that are currently empty"
|
"description": "Button to select only fields that are currently empty"
|
||||||
},
|
},
|
||||||
|
|
||||||
"queueDownloadingCount": "Downloading ({count})",
|
"queueDownloadingCount": "Downloading ({count})",
|
||||||
"@queueDownloadingCount": {
|
"@queueDownloadingCount": {
|
||||||
"description": "Header for active downloads section with count",
|
"description": "Header for active downloads section with count",
|
||||||
@@ -4229,7 +4204,6 @@
|
|||||||
"@audioAnalysisSamples": {
|
"@audioAnalysisSamples": {
|
||||||
"description": "Total samples metric label"
|
"description": "Total samples metric label"
|
||||||
},
|
},
|
||||||
|
|
||||||
"extensionsSearchWith": "Search with {providerName}",
|
"extensionsSearchWith": "Search with {providerName}",
|
||||||
"@extensionsSearchWith": {
|
"@extensionsSearchWith": {
|
||||||
"description": "Extensions page - subtitle for built-in search provider option",
|
"description": "Extensions page - subtitle for built-in search provider option",
|
||||||
@@ -4249,7 +4223,7 @@
|
|||||||
},
|
},
|
||||||
"extensionsHomeFeedAuto": "Auto",
|
"extensionsHomeFeedAuto": "Auto",
|
||||||
"@extensionsHomeFeedAuto": {
|
"@extensionsHomeFeedAuto": {
|
||||||
"description": "Extensions page - home feed provider option: auto"
|
"description": "Label for auto-selected search provider"
|
||||||
},
|
},
|
||||||
"extensionsHomeFeedAutoSubtitle": "Automatically select the best available",
|
"extensionsHomeFeedAutoSubtitle": "Automatically select the best available",
|
||||||
"@extensionsHomeFeedAutoSubtitle": {
|
"@extensionsHomeFeedAutoSubtitle": {
|
||||||
@@ -4268,7 +4242,6 @@
|
|||||||
"@extensionsNoHomeFeedExtensions": {
|
"@extensionsNoHomeFeedExtensions": {
|
||||||
"description": "Extensions page - shown when no installed extension has home feed"
|
"description": "Extensions page - shown when no installed extension has home feed"
|
||||||
},
|
},
|
||||||
|
|
||||||
"sortAlphaAsc": "A-Z",
|
"sortAlphaAsc": "A-Z",
|
||||||
"@sortAlphaAsc": {
|
"@sortAlphaAsc": {
|
||||||
"description": "Sort option - alphabetical ascending"
|
"description": "Sort option - alphabetical ascending"
|
||||||
@@ -4294,7 +4267,6 @@
|
|||||||
"@cancelDownloadKeep": {
|
"@cancelDownloadKeep": {
|
||||||
"description": "Dialog button - keep the active download (do not cancel)"
|
"description": "Dialog button - keep the active download (do not cancel)"
|
||||||
},
|
},
|
||||||
|
|
||||||
"metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg",
|
"metadataSaveFailedFfmpeg": "Failed to save metadata via FFmpeg",
|
||||||
"@metadataSaveFailedFfmpeg": {
|
"@metadataSaveFailedFfmpeg": {
|
||||||
"description": "Snackbar error when FFmpeg fails to write metadata"
|
"description": "Snackbar error when FFmpeg fails to write metadata"
|
||||||
@@ -4303,7 +4275,6 @@
|
|||||||
"@metadataSaveFailedStorage": {
|
"@metadataSaveFailedStorage": {
|
||||||
"description": "Snackbar error when writing metadata file back to storage fails"
|
"description": "Snackbar error when writing metadata file back to storage fails"
|
||||||
},
|
},
|
||||||
|
|
||||||
"snackbarFolderPickerFailed": "Failed to open folder picker: {error}",
|
"snackbarFolderPickerFailed": "Failed to open folder picker: {error}",
|
||||||
"@snackbarFolderPickerFailed": {
|
"@snackbarFolderPickerFailed": {
|
||||||
"description": "Snackbar shown when folder picker fails to open",
|
"description": "Snackbar shown when folder picker fails to open",
|
||||||
@@ -4313,7 +4284,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"errorLoadAlbum": "Failed to load album",
|
"errorLoadAlbum": "Failed to load album",
|
||||||
"@errorLoadAlbum": {
|
"@errorLoadAlbum": {
|
||||||
"description": "Error state shown when album fails to load"
|
"description": "Error state shown when album fails to load"
|
||||||
@@ -4326,7 +4296,6 @@
|
|||||||
"@errorLoadArtist": {
|
"@errorLoadArtist": {
|
||||||
"description": "Error state shown when artist fails to load"
|
"description": "Error state shown when artist fails to load"
|
||||||
},
|
},
|
||||||
|
|
||||||
"notifChannelDownloadName": "Download Progress",
|
"notifChannelDownloadName": "Download Progress",
|
||||||
"@notifChannelDownloadName": {
|
"@notifChannelDownloadName": {
|
||||||
"description": "Android notification channel name for download progress"
|
"description": "Android notification channel name for download progress"
|
||||||
@@ -4540,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Не вдалося завантажити оновлення. Спробуйте пізніше.",
|
"notifUpdateFailedBody": "Не вдалося завантажити оновлення. Спробуйте пізніше.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4509,5 +4509,77 @@
|
|||||||
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
"notifUpdateFailedBody": "Could not download update. Try again later.",
|
||||||
"@notifUpdateFailedBody": {
|
"@notifUpdateFailedBody": {
|
||||||
"description": "Notification body when app update download fails"
|
"description": "Notification body when app update download fails"
|
||||||
|
},
|
||||||
|
"settingsFiles": "Files & Folders",
|
||||||
|
"@settingsFiles": {
|
||||||
|
"description": "Settings menu item - file and folder settings"
|
||||||
|
},
|
||||||
|
"settingsFilesSubtitle": "Download location, filename, folder structure",
|
||||||
|
"@settingsFilesSubtitle": {
|
||||||
|
"description": "Subtitle for files & folders settings"
|
||||||
|
},
|
||||||
|
"settingsMetadata": "Metadata",
|
||||||
|
"@settingsMetadata": {
|
||||||
|
"description": "Settings menu item - metadata settings"
|
||||||
|
},
|
||||||
|
"settingsMetadataSubtitle": "Cover art, tags, ReplayGain, providers",
|
||||||
|
"@settingsMetadataSubtitle": {
|
||||||
|
"description": "Subtitle for metadata settings"
|
||||||
|
},
|
||||||
|
"settingsLyrics": "Lyrics",
|
||||||
|
"@settingsLyrics": {
|
||||||
|
"description": "Settings menu item - lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsLyricsSubtitle": "Embed, mode, providers, language options",
|
||||||
|
"@settingsLyricsSubtitle": {
|
||||||
|
"description": "Subtitle for lyrics settings"
|
||||||
|
},
|
||||||
|
"settingsApp": "App",
|
||||||
|
"@settingsApp": {
|
||||||
|
"description": "Settings menu item - app settings"
|
||||||
|
},
|
||||||
|
"settingsAppSubtitle": "Updates, data, extension repo, debug",
|
||||||
|
"@settingsAppSubtitle": {
|
||||||
|
"description": "Subtitle for app settings"
|
||||||
|
},
|
||||||
|
"sectionMetadataProviders": "Providers",
|
||||||
|
"@sectionMetadataProviders": {
|
||||||
|
"description": "Settings section header for metadata providers"
|
||||||
|
},
|
||||||
|
"sectionDuplicates": "Duplicates",
|
||||||
|
"@sectionDuplicates": {
|
||||||
|
"description": "Settings section header for deduplication"
|
||||||
|
},
|
||||||
|
"sectionLyricsProviderOptions": "Provider Options",
|
||||||
|
"@sectionLyricsProviderOptions": {
|
||||||
|
"description": "Settings section header for per-provider lyrics options"
|
||||||
|
},
|
||||||
|
"metadataProvidersTitle": "Metadata Provider Priority",
|
||||||
|
"@metadataProvidersTitle": {
|
||||||
|
"description": "Settings item title for metadata provider order"
|
||||||
|
},
|
||||||
|
"metadataProvidersSubtitle": "Drag to set search and metadata source order",
|
||||||
|
"@metadataProvidersSubtitle": {
|
||||||
|
"description": "Subtitle for metadata provider priority item"
|
||||||
|
},
|
||||||
|
"downloadDeduplication": "Skip Duplicate Downloads",
|
||||||
|
"@downloadDeduplication": {
|
||||||
|
"description": "Setting - skip tracks already in download history"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationEnabled": "Already-downloaded tracks will be skipped",
|
||||||
|
"@downloadDeduplicationEnabled": {
|
||||||
|
"description": "Subtitle when deduplication is on"
|
||||||
|
},
|
||||||
|
"downloadDeduplicationDisabled": "All tracks will be downloaded regardless of history",
|
||||||
|
"@downloadDeduplicationDisabled": {
|
||||||
|
"description": "Subtitle when deduplication is off"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensions": "Fallback Extensions",
|
||||||
|
"@downloadFallbackExtensions": {
|
||||||
|
"description": "Settings item for configuring fallback extension providers"
|
||||||
|
},
|
||||||
|
"downloadFallbackExtensionsSubtitle": "Choose which extensions can be used as fallback",
|
||||||
|
"@downloadFallbackExtensionsSubtitle": {
|
||||||
|
"description": "Subtitle for fallback extensions item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,372 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
||||||
|
import 'package:spotiflac_android/providers/download_queue_provider.dart';
|
||||||
|
import 'package:spotiflac_android/providers/settings_provider.dart';
|
||||||
|
import 'package:spotiflac_android/utils/app_bar_layout.dart';
|
||||||
|
import 'package:spotiflac_android/widgets/settings_group.dart';
|
||||||
|
|
||||||
|
class AppSettingsPage extends ConsumerWidget {
|
||||||
|
const AppSettingsPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final settings = ref.watch(settingsProvider);
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
final topPadding = normalizedHeaderTopPadding(context);
|
||||||
|
|
||||||
|
return PopScope(
|
||||||
|
canPop: true,
|
||||||
|
child: Scaffold(
|
||||||
|
body: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
SliverAppBar(
|
||||||
|
expandedHeight: 120 + topPadding,
|
||||||
|
collapsedHeight: kToolbarHeight,
|
||||||
|
floating: false,
|
||||||
|
pinned: true,
|
||||||
|
backgroundColor: colorScheme.surface,
|
||||||
|
surfaceTintColor: Colors.transparent,
|
||||||
|
leading: IconButton(
|
||||||
|
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
|
||||||
|
icon: const Icon(Icons.arrow_back),
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
flexibleSpace: LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
final maxHeight = 120 + topPadding;
|
||||||
|
final minHeight = kToolbarHeight + topPadding;
|
||||||
|
final expandRatio =
|
||||||
|
((constraints.maxHeight - minHeight) /
|
||||||
|
(maxHeight - minHeight))
|
||||||
|
.clamp(0.0, 1.0);
|
||||||
|
final leftPadding = 56 - (32 * expandRatio);
|
||||||
|
return FlexibleSpaceBar(
|
||||||
|
expandedTitleScale: 1.0,
|
||||||
|
titlePadding: EdgeInsets.only(
|
||||||
|
left: leftPadding,
|
||||||
|
bottom: 16,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
context.l10n.settingsApp,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20 + (8 * expandRatio),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Updates ────────────────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsSectionHeader(title: context.l10n.sectionApp),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsGroup(
|
||||||
|
children: [
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.extension,
|
||||||
|
title: context.l10n.optionsExtensionStore,
|
||||||
|
subtitle: context.l10n.optionsExtensionStoreSubtitle,
|
||||||
|
value: settings.showExtensionStore,
|
||||||
|
onChanged: (v) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setShowExtensionStore(v),
|
||||||
|
),
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.system_update,
|
||||||
|
title: context.l10n.optionsCheckUpdates,
|
||||||
|
subtitle: context.l10n.optionsCheckUpdatesSubtitle,
|
||||||
|
value: settings.checkForUpdates,
|
||||||
|
onChanged: (v) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setCheckForUpdates(v),
|
||||||
|
showDivider: settings.checkForUpdates,
|
||||||
|
),
|
||||||
|
if (settings.checkForUpdates)
|
||||||
|
_UpdateChannelSelector(
|
||||||
|
currentChannel: settings.updateChannel,
|
||||||
|
onChanged: (v) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setUpdateChannel(v),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Data ───────────────────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsSectionHeader(title: context.l10n.sectionData),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsGroup(
|
||||||
|
children: [
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.cleaning_services_outlined,
|
||||||
|
title: context.l10n.cleanupOrphanedDownloads,
|
||||||
|
subtitle: context.l10n.cleanupOrphanedDownloadsSubtitle,
|
||||||
|
onTap: () => _cleanupOrphanedDownloads(context, ref),
|
||||||
|
),
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.delete_forever,
|
||||||
|
title: context.l10n.optionsClearHistory,
|
||||||
|
subtitle: context.l10n.optionsClearHistorySubtitle,
|
||||||
|
onTap: () =>
|
||||||
|
_showClearHistoryDialog(context, ref, colorScheme),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Debug ──────────────────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsSectionHeader(title: context.l10n.sectionDebug),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsGroup(
|
||||||
|
children: [
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.bug_report,
|
||||||
|
title: context.l10n.optionsDetailedLogging,
|
||||||
|
subtitle: settings.enableLogging
|
||||||
|
? context.l10n.optionsDetailedLoggingOn
|
||||||
|
: context.l10n.optionsDetailedLoggingOff,
|
||||||
|
value: settings.enableLogging,
|
||||||
|
onChanged: (v) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setEnableLogging(v),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SliverToBoxAdapter(child: SizedBox(height: 32)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showClearHistoryDialog(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
ColorScheme colorScheme,
|
||||||
|
) {
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: Text(context.l10n.dialogClearHistoryTitle),
|
||||||
|
content: Text(context.l10n.dialogClearHistoryMessage),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(context.l10n.dialogCancel),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
ref.read(downloadHistoryProvider.notifier).clearHistory();
|
||||||
|
Navigator.pop(context);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.snackbarHistoryCleared)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
context.l10n.dialogClear,
|
||||||
|
style: TextStyle(color: colorScheme.error),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _cleanupOrphanedDownloads(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
) async {
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
content: Row(
|
||||||
|
children: [
|
||||||
|
const CircularProgressIndicator(),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Text(context.l10n.cleanupOrphanedDownloads),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
final removed = await ref
|
||||||
|
.read(downloadHistoryProvider.notifier)
|
||||||
|
.cleanupOrphanedDownloads();
|
||||||
|
if (context.mounted) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
removed > 0
|
||||||
|
? context.l10n.cleanupOrphanedDownloadsResult(removed)
|
||||||
|
: context.l10n.cleanupOrphanedDownloadsNone,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (context.mounted) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.snackbarError(e.toString()))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UpdateChannelSelector extends StatelessWidget {
|
||||||
|
final String currentChannel;
|
||||||
|
final ValueChanged<String> onChanged;
|
||||||
|
const _UpdateChannelSelector({
|
||||||
|
required this.currentChannel,
|
||||||
|
required this.onChanged,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||||
|
final unselectedColor = isDark
|
||||||
|
? Color.alphaBlend(
|
||||||
|
Colors.white.withValues(alpha: 0.05),
|
||||||
|
colorScheme.surface,
|
||||||
|
)
|
||||||
|
: colorScheme.surfaceContainerHigh;
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.new_releases,
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
context.l10n.optionsUpdateChannel,
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
Text(
|
||||||
|
currentChannel == 'preview'
|
||||||
|
? context.l10n.optionsUpdateChannelPreview
|
||||||
|
: context.l10n.optionsUpdateChannelStable,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
_ChannelChip(
|
||||||
|
label: context.l10n.channelStable,
|
||||||
|
isSelected: currentChannel == 'stable',
|
||||||
|
onTap: () => onChanged('stable'),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
_ChannelChip(
|
||||||
|
label: context.l10n.channelPreview,
|
||||||
|
isSelected: currentChannel == 'preview',
|
||||||
|
onTap: () => onChanged('preview'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.info_outline,
|
||||||
|
size: 16,
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
context.l10n.optionsUpdateChannelWarning,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ChannelChip extends StatelessWidget {
|
||||||
|
final String label;
|
||||||
|
final bool isSelected;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
const _ChannelChip({
|
||||||
|
required this.label,
|
||||||
|
required this.isSelected,
|
||||||
|
required this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||||
|
final unselectedColor = isDark
|
||||||
|
? Color.alphaBlend(
|
||||||
|
Colors.white.withValues(alpha: 0.05),
|
||||||
|
colorScheme.surface,
|
||||||
|
)
|
||||||
|
: colorScheme.surfaceContainerHigh;
|
||||||
|
return Expanded(
|
||||||
|
child: Material(
|
||||||
|
color: isSelected ? colorScheme.primaryContainer : unselectedColor,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
|
||||||
|
color: isSelected
|
||||||
|
? colorScheme.onPrimaryContainer
|
||||||
|
: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
||||||
|
import 'package:spotiflac_android/providers/settings_provider.dart';
|
||||||
|
import 'package:spotiflac_android/utils/app_bar_layout.dart';
|
||||||
|
import 'package:spotiflac_android/screens/settings/lyrics_provider_priority_page.dart';
|
||||||
|
import 'package:spotiflac_android/widgets/settings_group.dart';
|
||||||
|
|
||||||
|
class LyricsSettingsPage extends ConsumerWidget {
|
||||||
|
const LyricsSettingsPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final settings = ref.watch(settingsProvider);
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
final topPadding = normalizedHeaderTopPadding(context);
|
||||||
|
|
||||||
|
return PopScope(
|
||||||
|
canPop: true,
|
||||||
|
child: Scaffold(
|
||||||
|
body: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
SliverAppBar(
|
||||||
|
expandedHeight: 120 + topPadding,
|
||||||
|
collapsedHeight: kToolbarHeight,
|
||||||
|
floating: false,
|
||||||
|
pinned: true,
|
||||||
|
backgroundColor: colorScheme.surface,
|
||||||
|
surfaceTintColor: Colors.transparent,
|
||||||
|
leading: IconButton(
|
||||||
|
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
|
||||||
|
icon: const Icon(Icons.arrow_back),
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
flexibleSpace: LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
final maxHeight = 120 + topPadding;
|
||||||
|
final minHeight = kToolbarHeight + topPadding;
|
||||||
|
final expandRatio =
|
||||||
|
((constraints.maxHeight - minHeight) /
|
||||||
|
(maxHeight - minHeight))
|
||||||
|
.clamp(0.0, 1.0);
|
||||||
|
final leftPadding = 56 - (32 * expandRatio);
|
||||||
|
return FlexibleSpaceBar(
|
||||||
|
expandedTitleScale: 1.0,
|
||||||
|
titlePadding: EdgeInsets.only(
|
||||||
|
left: leftPadding,
|
||||||
|
bottom: 16,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
context.l10n.settingsLyrics,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20 + (8 * expandRatio),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Lyrics Embedding ───────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsSectionHeader(title: context.l10n.sectionLyrics),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsGroup(
|
||||||
|
children: [
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.subtitles_outlined,
|
||||||
|
title: context.l10n.optionsEmbedLyrics,
|
||||||
|
subtitle: settings.embedMetadata
|
||||||
|
? context.l10n.optionsEmbedLyricsSubtitle
|
||||||
|
: context.l10n.downloadEmbedLyricsDisabled,
|
||||||
|
value: settings.embedLyrics,
|
||||||
|
enabled: settings.embedMetadata,
|
||||||
|
onChanged: (value) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setEmbedLyrics(value),
|
||||||
|
showDivider:
|
||||||
|
settings.embedMetadata && settings.embedLyrics,
|
||||||
|
),
|
||||||
|
if (settings.embedMetadata && settings.embedLyrics) ...[
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.lyrics_outlined,
|
||||||
|
title: context.l10n.lyricsMode,
|
||||||
|
subtitle: _getLyricsModeLabel(
|
||||||
|
context,
|
||||||
|
settings.lyricsMode,
|
||||||
|
),
|
||||||
|
onTap: () =>
|
||||||
|
_showLyricsModePicker(context, ref, settings.lyricsMode),
|
||||||
|
),
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.source_outlined,
|
||||||
|
title: context.l10n.lyricsProvidersTitle,
|
||||||
|
subtitle: _getLyricsProvidersSubtitle(
|
||||||
|
context,
|
||||||
|
settings.lyricsProviders,
|
||||||
|
),
|
||||||
|
onTap: () => Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute<void>(
|
||||||
|
builder: (_) => const LyricsProviderPriorityPage(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Provider Options ───────────────────────────────────────
|
||||||
|
if (settings.embedMetadata && settings.embedLyrics) ...[
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsSectionHeader(
|
||||||
|
title: context.l10n.sectionLyricsProviderOptions,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsGroup(
|
||||||
|
children: [
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.translate_outlined,
|
||||||
|
title: context.l10n.downloadNeteaseIncludeTranslation,
|
||||||
|
subtitle: settings.lyricsIncludeTranslationNetease
|
||||||
|
? context.l10n.downloadNeteaseIncludeTranslationEnabled
|
||||||
|
: context.l10n.downloadNeteaseIncludeTranslationDisabled,
|
||||||
|
value: settings.lyricsIncludeTranslationNetease,
|
||||||
|
onChanged: (value) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setLyricsIncludeTranslationNetease(value),
|
||||||
|
),
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.text_fields_outlined,
|
||||||
|
title: context.l10n.downloadNeteaseIncludeRomanization,
|
||||||
|
subtitle: settings.lyricsIncludeRomanizationNetease
|
||||||
|
? context
|
||||||
|
.l10n
|
||||||
|
.downloadNeteaseIncludeRomanizationEnabled
|
||||||
|
: context
|
||||||
|
.l10n
|
||||||
|
.downloadNeteaseIncludeRomanizationDisabled,
|
||||||
|
value: settings.lyricsIncludeRomanizationNetease,
|
||||||
|
onChanged: (value) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setLyricsIncludeRomanizationNetease(value),
|
||||||
|
),
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.record_voice_over_outlined,
|
||||||
|
title: context.l10n.downloadAppleQqMultiPerson,
|
||||||
|
subtitle: settings.lyricsMultiPersonWordByWord
|
||||||
|
? context.l10n.downloadAppleQqMultiPersonEnabled
|
||||||
|
: context.l10n.downloadAppleQqMultiPersonDisabled,
|
||||||
|
value: settings.lyricsMultiPersonWordByWord,
|
||||||
|
onChanged: (value) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setLyricsMultiPersonWordByWord(value),
|
||||||
|
),
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.language_outlined,
|
||||||
|
title: context.l10n.downloadMusixmatchLanguage,
|
||||||
|
subtitle: settings.musixmatchLanguage.isEmpty
|
||||||
|
? context.l10n.downloadMusixmatchLanguageAuto
|
||||||
|
: settings.musixmatchLanguage.toUpperCase(),
|
||||||
|
onTap: () => _showMusixmatchLanguagePicker(
|
||||||
|
context,
|
||||||
|
ref,
|
||||||
|
settings.musixmatchLanguage,
|
||||||
|
),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
const SliverToBoxAdapter(child: SizedBox(height: 32)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getLyricsModeLabel(BuildContext context, String mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case 'external':
|
||||||
|
return context.l10n.lyricsModeExternal;
|
||||||
|
case 'both':
|
||||||
|
return context.l10n.lyricsModeBoth;
|
||||||
|
default:
|
||||||
|
return context.l10n.lyricsModeEmbed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const _providerDisplayNames = <String, String>{
|
||||||
|
'lrclib': 'LRCLIB',
|
||||||
|
'netease': 'Netease',
|
||||||
|
'musixmatch': 'Musixmatch',
|
||||||
|
'apple_music': 'Apple Music',
|
||||||
|
'qqmusic': 'QQ Music',
|
||||||
|
};
|
||||||
|
|
||||||
|
String _getLyricsProvidersSubtitle(
|
||||||
|
BuildContext context,
|
||||||
|
List<String> providers,
|
||||||
|
) {
|
||||||
|
if (providers.isEmpty) return context.l10n.downloadProvidersNoneEnabled;
|
||||||
|
return providers
|
||||||
|
.map((p) => _providerDisplayNames[p] ?? p)
|
||||||
|
.join(' > ');
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showLyricsModePicker(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
String current,
|
||||||
|
) {
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
context: context,
|
||||||
|
useRootNavigator: true,
|
||||||
|
backgroundColor: colorScheme.surfaceContainerHigh,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(28)),
|
||||||
|
),
|
||||||
|
builder: (context) => SafeArea(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(24, 24, 24, 8),
|
||||||
|
child: Text(
|
||||||
|
context.l10n.lyricsMode,
|
||||||
|
style: Theme.of(context).textTheme.titleLarge
|
||||||
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
|
||||||
|
child: Text(
|
||||||
|
context.l10n.lyricsModeDescription,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium
|
||||||
|
?.copyWith(color: colorScheme.onSurfaceVariant),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.audiotrack),
|
||||||
|
title: Text(context.l10n.lyricsModeEmbed),
|
||||||
|
subtitle: Text(context.l10n.lyricsModeEmbedSubtitle),
|
||||||
|
trailing: current == 'embed' ? const Icon(Icons.check) : null,
|
||||||
|
onTap: () {
|
||||||
|
ref.read(settingsProvider.notifier).setLyricsMode('embed');
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.insert_drive_file_outlined),
|
||||||
|
title: Text(context.l10n.lyricsModeExternal),
|
||||||
|
subtitle: Text(context.l10n.lyricsModeExternalSubtitle),
|
||||||
|
trailing: current == 'external' ? const Icon(Icons.check) : null,
|
||||||
|
onTap: () {
|
||||||
|
ref.read(settingsProvider.notifier).setLyricsMode('external');
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.library_music_outlined),
|
||||||
|
title: Text(context.l10n.lyricsModeBoth),
|
||||||
|
subtitle: Text(context.l10n.lyricsModeBothSubtitle),
|
||||||
|
trailing: current == 'both' ? const Icon(Icons.check) : null,
|
||||||
|
onTap: () {
|
||||||
|
ref.read(settingsProvider.notifier).setLyricsMode('both');
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showMusixmatchLanguagePicker(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
String currentLanguage,
|
||||||
|
) {
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
final controller = TextEditingController(text: currentLanguage);
|
||||||
|
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
context: context,
|
||||||
|
useRootNavigator: true,
|
||||||
|
backgroundColor: colorScheme.surfaceContainerHigh,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(28)),
|
||||||
|
),
|
||||||
|
isScrollControlled: true,
|
||||||
|
builder: (context) => Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
left: 24,
|
||||||
|
right: 24,
|
||||||
|
top: 24,
|
||||||
|
bottom: 24 + MediaQuery.of(context).viewInsets.bottom,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
context.l10n.downloadMusixmatchLanguage,
|
||||||
|
style: Theme.of(context).textTheme.titleLarge
|
||||||
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
context.l10n.downloadMusixmatchLanguageDesc,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium
|
||||||
|
?.copyWith(color: colorScheme.onSurfaceVariant),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
TextField(
|
||||||
|
controller: controller,
|
||||||
|
textInputAction: TextInputAction.done,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: context.l10n.downloadMusixmatchLanguageCode,
|
||||||
|
hintText: context.l10n.downloadMusixmatchLanguageHint,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(context.l10n.dialogCancel),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setMusixmatchLanguage('');
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Text(context.l10n.downloadMusixmatchAuto),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
FilledButton(
|
||||||
|
onPressed: () {
|
||||||
|
final normalized = controller.text
|
||||||
|
.trim()
|
||||||
|
.toLowerCase()
|
||||||
|
.replaceAll(RegExp(r'[^a-z0-9\-_]'), '');
|
||||||
|
ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setMusixmatchLanguage(normalized);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Text(context.l10n.dialogSave),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
||||||
|
import 'package:spotiflac_android/providers/settings_provider.dart';
|
||||||
|
import 'package:spotiflac_android/utils/app_bar_layout.dart';
|
||||||
|
import 'package:spotiflac_android/utils/artist_utils.dart';
|
||||||
|
import 'package:spotiflac_android/screens/settings/metadata_provider_priority_page.dart';
|
||||||
|
import 'package:spotiflac_android/widgets/settings_group.dart';
|
||||||
|
|
||||||
|
class MetadataSettingsPage extends ConsumerWidget {
|
||||||
|
const MetadataSettingsPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final settings = ref.watch(settingsProvider);
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
final topPadding = normalizedHeaderTopPadding(context);
|
||||||
|
|
||||||
|
return PopScope(
|
||||||
|
canPop: true,
|
||||||
|
child: Scaffold(
|
||||||
|
body: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
SliverAppBar(
|
||||||
|
expandedHeight: 120 + topPadding,
|
||||||
|
collapsedHeight: kToolbarHeight,
|
||||||
|
floating: false,
|
||||||
|
pinned: true,
|
||||||
|
backgroundColor: colorScheme.surface,
|
||||||
|
surfaceTintColor: Colors.transparent,
|
||||||
|
leading: IconButton(
|
||||||
|
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
|
||||||
|
icon: const Icon(Icons.arrow_back),
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
flexibleSpace: LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
final maxHeight = 120 + topPadding;
|
||||||
|
final minHeight = kToolbarHeight + topPadding;
|
||||||
|
final expandRatio =
|
||||||
|
((constraints.maxHeight - minHeight) /
|
||||||
|
(maxHeight - minHeight))
|
||||||
|
.clamp(0.0, 1.0);
|
||||||
|
final leftPadding = 56 - (32 * expandRatio);
|
||||||
|
return FlexibleSpaceBar(
|
||||||
|
expandedTitleScale: 1.0,
|
||||||
|
titlePadding: EdgeInsets.only(
|
||||||
|
left: leftPadding,
|
||||||
|
bottom: 16,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
context.l10n.settingsMetadata,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20 + (8 * expandRatio),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Embedding ──────────────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsSectionHeader(title: context.l10n.sectionDownload),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsGroup(
|
||||||
|
children: [
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.sell_outlined,
|
||||||
|
title: 'Embed Metadata',
|
||||||
|
subtitle: settings.embedMetadata
|
||||||
|
? 'Write metadata, cover art, and lyrics to files'
|
||||||
|
: 'Disabled (advanced): skip all metadata embedding',
|
||||||
|
value: settings.embedMetadata,
|
||||||
|
onChanged: (v) =>
|
||||||
|
ref.read(settingsProvider.notifier).setEmbedMetadata(v),
|
||||||
|
showDivider: settings.embedMetadata,
|
||||||
|
),
|
||||||
|
if (settings.embedMetadata) ...[
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.people_alt_outlined,
|
||||||
|
title: context.l10n.optionsArtistTagMode,
|
||||||
|
subtitle: _getArtistTagModeLabel(
|
||||||
|
context,
|
||||||
|
settings.artistTagMode,
|
||||||
|
),
|
||||||
|
onTap: () =>
|
||||||
|
_showArtistTagModePicker(context, ref, settings.artistTagMode),
|
||||||
|
),
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.image,
|
||||||
|
title: context.l10n.optionsMaxQualityCover,
|
||||||
|
subtitle: context.l10n.optionsMaxQualityCoverSubtitle,
|
||||||
|
value: settings.maxQualityCover,
|
||||||
|
onChanged: (v) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setMaxQualityCover(v),
|
||||||
|
),
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.graphic_eq,
|
||||||
|
title: context.l10n.optionsReplayGain,
|
||||||
|
subtitle: settings.embedReplayGain
|
||||||
|
? context.l10n.optionsReplayGainSubtitleOn
|
||||||
|
: context.l10n.optionsReplayGainSubtitleOff,
|
||||||
|
value: settings.embedReplayGain,
|
||||||
|
onChanged: (v) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setEmbedReplayGain(v),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Providers ─────────────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsSectionHeader(
|
||||||
|
title: context.l10n.sectionMetadataProviders,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsGroup(
|
||||||
|
children: [
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.source_outlined,
|
||||||
|
title: context.l10n.metadataProvidersTitle,
|
||||||
|
subtitle: context.l10n.metadataProvidersSubtitle,
|
||||||
|
onTap: () => Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute<void>(
|
||||||
|
builder: (_) => const MetadataProviderPriorityPage(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Deduplication ──────────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsSectionHeader(
|
||||||
|
title: context.l10n.sectionDuplicates,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SettingsGroup(
|
||||||
|
children: [
|
||||||
|
SettingsSwitchItem(
|
||||||
|
icon: Icons.filter_list_outlined,
|
||||||
|
title: context.l10n.downloadDeduplication,
|
||||||
|
subtitle: settings.deduplicateDownloads
|
||||||
|
? context.l10n.downloadDeduplicationEnabled
|
||||||
|
: context.l10n.downloadDeduplicationDisabled,
|
||||||
|
value: settings.deduplicateDownloads,
|
||||||
|
onChanged: (value) => ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setDeduplicateDownloads(value),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SliverToBoxAdapter(child: SizedBox(height: 32)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getArtistTagModeLabel(BuildContext context, String mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case artistTagModeSplitVorbis:
|
||||||
|
return context.l10n.optionsArtistTagModeSplitVorbis;
|
||||||
|
default:
|
||||||
|
return context.l10n.optionsArtistTagModeJoined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showArtistTagModePicker(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
String currentMode,
|
||||||
|
) {
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
context: context,
|
||||||
|
useRootNavigator: true,
|
||||||
|
backgroundColor: colorScheme.surfaceContainerHigh,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(28)),
|
||||||
|
),
|
||||||
|
builder: (context) => SafeArea(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(24, 24, 24, 8),
|
||||||
|
child: Text(
|
||||||
|
context.l10n.optionsArtistTagMode,
|
||||||
|
style: Theme.of(context).textTheme.titleLarge
|
||||||
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
|
||||||
|
child: Text(
|
||||||
|
context.l10n.optionsArtistTagModeDescription,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium
|
||||||
|
?.copyWith(color: colorScheme.onSurfaceVariant),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.segment_outlined),
|
||||||
|
title: Text(context.l10n.optionsArtistTagModeJoined),
|
||||||
|
subtitle: Text(context.l10n.optionsArtistTagModeJoinedSubtitle),
|
||||||
|
trailing: currentMode == artistTagModeJoined
|
||||||
|
? const Icon(Icons.check)
|
||||||
|
: null,
|
||||||
|
onTap: () {
|
||||||
|
ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setArtistTagMode(artistTagModeJoined);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.library_music_outlined),
|
||||||
|
title: Text(context.l10n.optionsArtistTagModeSplitVorbis),
|
||||||
|
subtitle: Text(context.l10n.optionsArtistTagModeSplitVorbisSubtitle),
|
||||||
|
trailing: currentMode == artistTagModeSplitVorbis
|
||||||
|
? const Icon(Icons.check)
|
||||||
|
: null,
|
||||||
|
onTap: () {
|
||||||
|
ref
|
||||||
|
.read(settingsProvider.notifier)
|
||||||
|
.setArtistTagMode(artistTagModeSplitVorbis);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,9 +4,12 @@ import 'package:spotiflac_android/constants/app_info.dart';
|
|||||||
import 'package:spotiflac_android/l10n/l10n.dart';
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
||||||
import 'package:spotiflac_android/screens/settings/appearance_settings_page.dart';
|
import 'package:spotiflac_android/screens/settings/appearance_settings_page.dart';
|
||||||
import 'package:spotiflac_android/screens/settings/download_settings_page.dart';
|
import 'package:spotiflac_android/screens/settings/download_settings_page.dart';
|
||||||
|
import 'package:spotiflac_android/screens/settings/files_settings_page.dart';
|
||||||
|
import 'package:spotiflac_android/screens/settings/lyrics_settings_page.dart';
|
||||||
|
import 'package:spotiflac_android/screens/settings/metadata_settings_page.dart';
|
||||||
import 'package:spotiflac_android/screens/settings/extensions_page.dart';
|
import 'package:spotiflac_android/screens/settings/extensions_page.dart';
|
||||||
import 'package:spotiflac_android/screens/settings/library_settings_page.dart';
|
import 'package:spotiflac_android/screens/settings/library_settings_page.dart';
|
||||||
import 'package:spotiflac_android/screens/settings/options_settings_page.dart';
|
import 'package:spotiflac_android/screens/settings/app_settings_page.dart';
|
||||||
import 'package:spotiflac_android/screens/settings/about_page.dart';
|
import 'package:spotiflac_android/screens/settings/about_page.dart';
|
||||||
import 'package:spotiflac_android/screens/settings/cache_management_page.dart';
|
import 'package:spotiflac_android/screens/settings/cache_management_page.dart';
|
||||||
import 'package:spotiflac_android/screens/settings/donate_page.dart';
|
import 'package:spotiflac_android/screens/settings/donate_page.dart';
|
||||||
@@ -48,7 +51,7 @@ class SettingsTab extends ConsumerWidget {
|
|||||||
title: Text(
|
title: Text(
|
||||||
context.l10n.settingsTitle,
|
context.l10n.settingsTitle,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20 + (14 * expandRatio), // 20 -> 34
|
fontSize: 20 + (14 * expandRatio),
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: colorScheme.onSurface,
|
color: colorScheme.onSurface,
|
||||||
),
|
),
|
||||||
@@ -58,6 +61,7 @@ class SettingsTab extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// ── Group 1: Appearance & Content ──────────────────────────────
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
@@ -72,6 +76,34 @@ class SettingsTab extends ConsumerWidget {
|
|||||||
onTap: () =>
|
onTap: () =>
|
||||||
_navigateTo(context, const AppearanceSettingsPage()),
|
_navigateTo(context, const AppearanceSettingsPage()),
|
||||||
),
|
),
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.library_music_outlined,
|
||||||
|
title: l10n.settingsLocalLibrary,
|
||||||
|
subtitle: l10n.settingsLocalLibrarySubtitle,
|
||||||
|
onTap: () =>
|
||||||
|
_navigateTo(context, const LibrarySettingsPage()),
|
||||||
|
),
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.extension_outlined,
|
||||||
|
title: l10n.settingsExtensions,
|
||||||
|
subtitle: l10n.settingsExtensionsSubtitle,
|
||||||
|
onTap: () => _navigateTo(context, const ExtensionsPage()),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Group 2: Download ──────────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
final l10n = context.l10n;
|
||||||
|
return SettingsGroup(
|
||||||
|
margin: const EdgeInsets.fromLTRB(16, 4, 16, 4),
|
||||||
|
children: [
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
icon: Icons.download_outlined,
|
icon: Icons.download_outlined,
|
||||||
title: l10n.settingsDownload,
|
title: l10n.settingsDownload,
|
||||||
@@ -80,12 +112,41 @@ class SettingsTab extends ConsumerWidget {
|
|||||||
_navigateTo(context, const DownloadSettingsPage()),
|
_navigateTo(context, const DownloadSettingsPage()),
|
||||||
),
|
),
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
icon: Icons.library_music_outlined,
|
icon: Icons.folder_outlined,
|
||||||
title: l10n.settingsLocalLibrary,
|
title: l10n.settingsFiles,
|
||||||
subtitle: l10n.settingsLocalLibrarySubtitle,
|
subtitle: l10n.settingsFilesSubtitle,
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
_navigateTo(context, const LibrarySettingsPage()),
|
_navigateTo(context, const FilesSettingsPage()),
|
||||||
),
|
),
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.sell_outlined,
|
||||||
|
title: l10n.settingsMetadata,
|
||||||
|
subtitle: l10n.settingsMetadataSubtitle,
|
||||||
|
onTap: () =>
|
||||||
|
_navigateTo(context, const MetadataSettingsPage()),
|
||||||
|
),
|
||||||
|
SettingsItem(
|
||||||
|
icon: Icons.lyrics_outlined,
|
||||||
|
title: l10n.settingsLyrics,
|
||||||
|
subtitle: l10n.settingsLyricsSubtitle,
|
||||||
|
onTap: () =>
|
||||||
|
_navigateTo(context, const LyricsSettingsPage()),
|
||||||
|
showDivider: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// ── Group 3: App ───────────────────────────────────────────────
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
final l10n = context.l10n;
|
||||||
|
return SettingsGroup(
|
||||||
|
margin: const EdgeInsets.fromLTRB(16, 4, 16, 4),
|
||||||
|
children: [
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
icon: Icons.storage_outlined,
|
icon: Icons.storage_outlined,
|
||||||
title: l10n.settingsCache,
|
title: l10n.settingsCache,
|
||||||
@@ -95,41 +156,22 @@ class SettingsTab extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
icon: Icons.tune_outlined,
|
icon: Icons.tune_outlined,
|
||||||
title: l10n.settingsOptions,
|
title: l10n.settingsApp,
|
||||||
subtitle: l10n.settingsOptionsSubtitle,
|
subtitle: l10n.settingsAppSubtitle,
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
_navigateTo(context, const OptionsSettingsPage()),
|
_navigateTo(context, const AppSettingsPage()),
|
||||||
),
|
),
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
icon: Icons.extension_outlined,
|
icon: Icons.article_outlined,
|
||||||
title: l10n.settingsExtensions,
|
title: l10n.logTitle,
|
||||||
subtitle: l10n.settingsExtensionsSubtitle,
|
subtitle: l10n.settingsLogsSubtitle,
|
||||||
onTap: () => _navigateTo(context, const ExtensionsPage()),
|
onTap: () => _navigateTo(context, const LogScreen()),
|
||||||
),
|
),
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
icon: Icons.favorite_outline,
|
icon: Icons.favorite_outline,
|
||||||
title: l10n.settingsDonate,
|
title: l10n.settingsDonate,
|
||||||
subtitle: l10n.settingsDonateSubtitle,
|
subtitle: l10n.settingsDonateSubtitle,
|
||||||
onTap: () => _navigateTo(context, const DonatePage()),
|
onTap: () => _navigateTo(context, const DonatePage()),
|
||||||
showDivider: false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: Builder(
|
|
||||||
builder: (context) {
|
|
||||||
final l10n = context.l10n;
|
|
||||||
return SettingsGroup(
|
|
||||||
children: [
|
|
||||||
SettingsItem(
|
|
||||||
icon: Icons.article_outlined,
|
|
||||||
title: l10n.logTitle,
|
|
||||||
subtitle: l10n.settingsLogsSubtitle,
|
|
||||||
onTap: () => _navigateTo(context, const LogScreen()),
|
|
||||||
),
|
),
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
icon: Icons.info_outline,
|
icon: Icons.info_outline,
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 71 KiB |