diff --git a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt index 5ace7826..0dd78b8c 100644 --- a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt +++ b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt @@ -1393,10 +1393,9 @@ class MainActivity: FlutterFragmentActivity() { "downloadCoverToFile" -> { val coverUrl = call.argument("cover_url") ?: "" val outputPath = call.argument("output_path") ?: "" - val maxQuality = call.argument("max_quality") ?: true val response = withContext(Dispatchers.IO) { try { - Gobackend.downloadCoverToFile(coverUrl, outputPath, maxQuality) + Gobackend.downloadCoverToFile(coverUrl, outputPath, false) """{"success":true}""" } catch (e: Exception) { """{"success":false,"error":"${e.message?.replace("\"", "'")}"}""" diff --git a/android/app/src/main/kotlin/com/zarz/spotiflac/NativeFinalizerMedia.kt b/android/app/src/main/kotlin/com/zarz/spotiflac/NativeFinalizerMedia.kt index a3eef59b..f5e5f204 100644 --- a/android/app/src/main/kotlin/com/zarz/spotiflac/NativeFinalizerMedia.kt +++ b/android/app/src/main/kotlin/com/zarz/spotiflac/NativeFinalizerMedia.kt @@ -503,7 +503,7 @@ internal fun NativeDownloadFinalizer.downloadCoverForMetadata(context: Context, Gobackend.downloadCoverToFile( coverUrl, output.absolutePath, - input.request.optBoolean("embed_max_quality_cover", true) + false ) if (output.exists() && output.length() > 0L) { output diff --git a/go_backend/cover.go b/go_backend/cover.go index 702e3ff0..52eb3848 100644 --- a/go_backend/cover.go +++ b/go_backend/cover.go @@ -8,158 +8,28 @@ import ( _ "image/png" "io" "net/http" - "regexp" - "strings" "sync" "time" ) -const ( - spotifySize300 = "ab67616d00001e02" - spotifySize640 = "ab67616d0000b273" - spotifySizeMax = "ab67616d000082c1" -) - -// Square CDN covers using this path shape may return an image whose decoded -// dimensions differ from the dimensions advertised in the URL. Max-quality -// selection therefore probes both useful high-resolution variants and checks -// the image headers instead of trusting the filename. -var squareCoverSizeRegex = regexp.MustCompile(`/(\d+)x(\d+)-\d+-\d+-\d+-\d+\.jpg$`) - -var tidalSizeRegex = regexp.MustCompile(`/\d+x\d+\.jpg$`) - -var qobuzSizeRegex = regexp.MustCompile(`_\d+\.jpg$`) - -func convertSmallToMedium(imageURL string) string { - if strings.Contains(imageURL, spotifySize300) { - return strings.Replace(imageURL, spotifySize300, spotifySize640, 1) - } - return imageURL -} - -func downloadCoverToMemory(coverURL string, maxQuality bool) ([]byte, error) { +// downloadCoverToMemory downloads exactly the URL supplied by the metadata +// provider. Cover-resolution selection belongs to the provider extension; +// the app must not infer a provider from its CDN URL or rewrite that URL. +func downloadCoverToMemory(coverURL string) ([]byte, error) { if coverURL == "" { return nil, fmt.Errorf("no cover URL provided") } - GoLog("[Cover] Original URL: %s", coverURL) - - downloadURL := convertSmallToMedium(coverURL) - if downloadURL != coverURL { - GoLog("[Cover] Upgraded 300x300 → 640x640") - } - - if !maxQuality { - GoLog("[Cover] Final URL: %s", downloadURL) - data, err := fetchCoverCached(downloadURL) - if err != nil { - return nil, err - } - return append([]byte(nil), data...), nil - } - - candidates := maxQualityCoverCandidateURLs(downloadURL) - data, selectedURL, width, height, err := fetchBestCoverCandidate(candidates) + GoLog("[Cover] Provider URL: %s", coverURL) + data, err := fetchCoverCached(coverURL) if err != nil { - // A CDN can reject an upgraded size while the provider-supplied URL is - // still valid. Preserve that URL as the final fallback. - if len(candidates) == 1 && candidates[0] == downloadURL { - return nil, err - } - data, err = fetchCoverCached(downloadURL) - if err != nil { - return nil, err - } - selectedURL = downloadURL - width, height = coverDimensions(data) + return nil, err } - GoLog("[Cover] Selected URL: %s (%dx%d, %d KB)", selectedURL, width, height, len(data)/1024) // Cached bytes are shared across goroutines and must never be mutated; // hand callers their own copy. return append([]byte(nil), data...), nil } -type fetchedCoverCandidate struct { - url string - data []byte - width, height int - err error -} - -func maxQualityCoverCandidateURLs(coverURL string) []string { - upgraded := upgradeToMaxQuality(coverURL) - candidates := []string{upgraded} - // This is deliberately based on the URL capability rather than a provider - // or extension ID. Any metadata source returning the same square-cover URL - // shape receives the same verified candidate selection. - if squareCoverSizeRegex.MatchString(coverURL) { - candidate1500 := squareCoverSizeRegex.ReplaceAllString( - coverURL, - "/1500x1500-000000-80-0-0.jpg", - ) - if candidate1500 != upgraded { - candidates = append(candidates, candidate1500) - } - } - return uniqueNonEmptyStrings(candidates) -} - -func uniqueNonEmptyStrings(values []string) []string { - seen := make(map[string]struct{}, len(values)) - result := make([]string, 0, len(values)) - for _, value := range values { - value = strings.TrimSpace(value) - if value == "" { - continue - } - if _, exists := seen[value]; exists { - continue - } - seen[value] = struct{}{} - result = append(result, value) - } - return result -} - -func fetchBestCoverCandidate(urls []string) ([]byte, string, int, int, error) { - if len(urls) == 0 { - return nil, "", 0, 0, fmt.Errorf("no cover candidates available") - } - results := make(chan fetchedCoverCandidate, len(urls)) - for _, candidateURL := range urls { - go func(url string) { - data, err := fetchCoverCached(url) - width, height := coverDimensions(data) - results <- fetchedCoverCandidate{ - url: url, data: data, width: width, height: height, err: err, - } - }(candidateURL) - } - - var best *fetchedCoverCandidate - var firstErr error - for range urls { - candidate := <-results - if candidate.err != nil || len(candidate.data) == 0 { - if firstErr == nil { - firstErr = candidate.err - } - continue - } - if best == nil || coverCandidateBetter(candidate, *best) { - copy := candidate - best = © - } - } - if best == nil { - if firstErr == nil { - firstErr = fmt.Errorf("cover candidates returned no image data") - } - return nil, "", 0, 0, firstErr - } - return best.data, best.url, best.width, best.height, nil -} - func coverDimensions(data []byte) (int, int) { if len(data) == 0 { return 0, 0 @@ -171,15 +41,6 @@ func coverDimensions(data []byte) (int, int) { return config.Width, config.Height } -func coverCandidateBetter(candidate, current fetchedCoverCandidate) bool { - candidatePixels := int64(candidate.width) * int64(candidate.height) - currentPixels := int64(current.width) * int64(current.height) - if candidatePixels != currentPixels { - return candidatePixels > currentPixels - } - return len(candidate.data) > len(current.data) -} - const ( coverCacheMaxBytes = 24 * 1024 * 1024 coverCacheTTL = 15 * time.Minute @@ -307,59 +168,3 @@ func fetchCoverBytes(downloadURL string) ([]byte, error) { return data, nil } - -func upgradeToMaxQuality(coverURL string) string { - if strings.Contains(coverURL, spotifySize640) { - return strings.Replace(coverURL, spotifySize640, spotifySizeMax, 1) - } - - if squareCoverSizeRegex.MatchString(coverURL) { - return upgradeSquareCover(coverURL) - } - - if strings.Contains(coverURL, "resources.tidal.com") { - return upgradeTidalCover(coverURL) - } - - if strings.Contains(coverURL, "static.qobuz.com") { - return upgradeQobuzCover(coverURL) - } - - return coverURL -} - -func upgradeSquareCover(coverURL string) string { - if !squareCoverSizeRegex.MatchString(coverURL) { - return coverURL - } - - upgraded := squareCoverSizeRegex.ReplaceAllString(coverURL, "/1900x1900-000000-80-0-0.jpg") - if upgraded != coverURL { - GoLog("[Cover] Square CDN: probing 1900x1900 and 1500x1500") - } - return upgraded -} - -func upgradeTidalCover(coverURL string) string { - if !strings.Contains(coverURL, "resources.tidal.com") { - return coverURL - } - - upgraded := tidalSizeRegex.ReplaceAllString(coverURL, "/origin.jpg") - if upgraded != coverURL { - GoLog("[Cover] Tidal: upgraded to origin resolution") - } - return upgraded -} - -func upgradeQobuzCover(coverURL string) string { - if !strings.Contains(coverURL, "static.qobuz.com") { - return coverURL - } - - upgraded := qobuzSizeRegex.ReplaceAllString(coverURL, "_max.jpg") - if upgraded != coverURL { - GoLog("[Cover] Qobuz: upgraded to max resolution") - } - return upgraded -} diff --git a/go_backend/cover_test.go b/go_backend/cover_test.go index 89154033..2dc2ae6a 100644 --- a/go_backend/cover_test.go +++ b/go_backend/cover_test.go @@ -1,33 +1,12 @@ package gobackend import ( - "bytes" - "errors" - "image" - "image/color" - "image/png" - "strings" "sync" "sync/atomic" "testing" "time" ) -func testPNG(t *testing.T, width, height int) []byte { - t.Helper() - img := image.NewRGBA(image.Rect(0, 0, width, height)) - for y := 0; y < height; y++ { - for x := 0; x < width; x++ { - img.Set(x, y, color.RGBA{R: uint8(x), G: uint8(y), B: 100, A: 255}) - } - } - var buffer bytes.Buffer - if err := png.Encode(&buffer, img); err != nil { - t.Fatalf("encode test cover: %v", err) - } - return buffer.Bytes() -} - func resetCoverCache() { coverMu.Lock() coverCache = map[string]*coverCacheEntry{} @@ -116,72 +95,26 @@ func TestFetchCoverCachedTTLExpiry(t *testing.T) { } } -func TestMaxQualityCoverCandidatesProbe1900And1500(t *testing.T) { - url := "https://cdn-images.dzcdn.net/images/cover/abc/1000x1000-000000-80-0-0.jpg" - candidates := maxQualityCoverCandidateURLs(url) - if len(candidates) != 2 { - t.Fatalf("expected two candidates, got %#v", candidates) - } - if !strings.Contains(candidates[0], "1900x1900") { - t.Fatalf("first candidate = %q", candidates[0]) - } - if !strings.Contains(candidates[1], "1500x1500") { - t.Fatalf("second candidate = %q", candidates[1]) - } -} - -func TestDownloadCoverSelectsDecodedDimensionsBeforeByteSize(t *testing.T) { +func TestDownloadCoverUsesProviderURLUnchanged(t *testing.T) { orig := coverFetch defer func() { coverFetch = orig }() resetCoverCache() - advertised1900ButSmaller := append(testPNG(t, 12, 12), bytes.Repeat([]byte{0}, 4096)...) - actualLargerDimensions := testPNG(t, 15, 15) + const providerURL = "https://i.scdn.co/image/ab67616d00001e02example" + var requestedURL string coverFetch = func(url string) ([]byte, error) { - switch { - case strings.Contains(url, "1900x1900"): - return advertised1900ButSmaller, nil - case strings.Contains(url, "1500x1500"): - return actualLargerDimensions, nil - default: - return nil, errors.New("unexpected URL") - } + requestedURL = url + return []byte("provider-cover"), nil } - url := "https://cdn-images.dzcdn.net/images/cover/abc/1000x1000-000000-80-0-0.jpg" - got, err := downloadCoverToMemory(url, true) + got, err := downloadCoverToMemory(providerURL) if err != nil { - t.Fatalf("download max cover: %v", err) + t.Fatalf("download provider cover: %v", err) } - if !bytes.Equal(got, actualLargerDimensions) { - t.Fatal("expected decoded 15x15 candidate instead of larger-byte 12x12 candidate") + if requestedURL != providerURL { + t.Fatalf("requested URL = %q, want provider URL %q", requestedURL, providerURL) } -} - -func TestBestCoverCandidateUsesByteSizeAsDimensionTiebreaker(t *testing.T) { - orig := coverFetch - defer func() { coverFetch = orig }() - resetCoverCache() - - base := testPNG(t, 10, 10) - largerFile := append(append([]byte(nil), base...), bytes.Repeat([]byte{0}, 512)...) - coverFetch = func(url string) ([]byte, error) { - if strings.Contains(url, "large") { - return largerFile, nil - } - return base, nil - } - - got, selected, width, height, err := fetchBestCoverCandidate( - []string{"https://covers.test/small", "https://covers.test/large"}, - ) - if err != nil { - t.Fatalf("select cover: %v", err) - } - if selected != "https://covers.test/large" || width != 10 || height != 10 { - t.Fatalf("selected=%q dimensions=%dx%d", selected, width, height) - } - if !bytes.Equal(got, largerFile) { - t.Fatal("expected larger file when decoded dimensions are equal") + if string(got) != "provider-cover" { + t.Fatalf("downloaded cover = %q", got) } } diff --git a/go_backend/exports_download.go b/go_backend/exports_download.go index ebcee941..c2acd7e8 100644 --- a/go_backend/exports_download.go +++ b/go_backend/exports_download.go @@ -28,7 +28,6 @@ type DownloadRequest struct { EmbedMetadata bool `json:"embed_metadata"` ArtistTagMode string `json:"artist_tag_mode,omitempty"` EmbedLyrics bool `json:"embed_lyrics"` - EmbedMaxQualityCover bool `json:"embed_max_quality_cover"` EmbedReplayGain bool `json:"embed_replaygain,omitempty"` PostProcessingEnabled bool `json:"post_processing_enabled,omitempty"` TidalHighFormat string `json:"tidal_high_format,omitempty"` diff --git a/go_backend/exports_metadata.go b/go_backend/exports_metadata.go index 5625cad8..2eb7e16d 100644 --- a/go_backend/exports_metadata.go +++ b/go_backend/exports_metadata.go @@ -527,12 +527,15 @@ func RewriteSplitArtistTagsExport(filePath, artist, albumArtist string) (string, return s, nil } -func DownloadCoverToFile(coverURL string, outputPath string, maxQuality bool) error { +// The final bool is retained for gomobile ABI compatibility with existing +// native shells. Resolution selection is extension-owned and the value is +// intentionally ignored. +func DownloadCoverToFile(coverURL string, outputPath string, _ bool) error { if coverURL == "" { return fmt.Errorf("no cover URL provided") } - data, err := downloadCoverToMemory(coverURL, maxQuality) + data, err := downloadCoverToMemory(coverURL) if err != nil { return fmt.Errorf("failed to download cover: %w", err) } diff --git a/go_backend/exports_reenrich.go b/go_backend/exports_reenrich.go index a6bd1711..6941b75b 100644 --- a/go_backend/exports_reenrich.go +++ b/go_backend/exports_reenrich.go @@ -21,7 +21,6 @@ var fetchMusicBrainzAlbumArtistByISRC = FetchMusicBrainzAlbumArtistByISRC type reEnrichRequest struct { FilePath string `json:"file_path"` CoverURL string `json:"cover_url"` - MaxQuality bool `json:"max_quality"` EmbedLyrics bool `json:"embed_lyrics"` LyricsMode string `json:"lyrics_mode,omitempty"` ArtistTagMode string `json:"artist_tag_mode,omitempty"` @@ -727,7 +726,7 @@ func ReEnrichFile(requestJSON string) (string, error) { var coverTempPath string var coverDataBytes []byte if req.CoverURL != "" && req.shouldUpdateTag("cover", "cover") { - coverData, err := downloadCoverToMemory(req.CoverURL, req.MaxQuality) + coverData, err := downloadCoverToMemory(req.CoverURL) if err != nil { GoLog("[ReEnrich] Failed to download cover: %v\n", err) } else { diff --git a/go_backend/extension_fallback_output.go b/go_backend/extension_fallback_output.go index cc59e381..7569c601 100644 --- a/go_backend/extension_fallback_output.go +++ b/go_backend/extension_fallback_output.go @@ -146,7 +146,7 @@ func embedExtensionDownloadMetadata(resp DownloadResponse, req DownloadRequest, coverURL := firstNonEmptyTrimmed(resp.CoverURL, req.CoverURL) var coverData []byte if coverURL != "" { - data, err := downloadCoverToMemory(coverURL, req.EmbedMaxQualityCover) + data, err := downloadCoverToMemory(coverURL) if err != nil { GoLog("[DownloadWithExtensionFallback] Warning: failed to download cover for metadata embed: %v\n", err) } else if len(data) > 0 { diff --git a/go_backend/extension_health_misc_supplement_test.go b/go_backend/extension_health_misc_supplement_test.go index 4fe15fdb..35b2601f 100644 --- a/go_backend/extension_health_misc_supplement_test.go +++ b/go_backend/extension_health_misc_supplement_test.go @@ -72,16 +72,7 @@ func TestExtensionHealthClassificationAndValidation(t *testing.T) { } func TestCoverAndIDHSHelpers(t *testing.T) { - if got := upgradeToMaxQuality("https://cdn-images.dzcdn.net/images/cover/abc/500x500-000000-80-0-0.jpg"); !strings.Contains(got, "1900x1900") { - t.Fatalf("deezer cover = %q", got) - } - if got := upgradeToMaxQuality("https://resources.tidal.com/images/id/320x320.jpg"); !strings.Contains(got, "origin.jpg") { - t.Fatalf("tidal cover = %q", got) - } - if got := upgradeToMaxQuality("https://static.qobuz.com/images/covers/ab/cd/foo_600.jpg"); !strings.Contains(got, "_max.jpg") { - t.Fatalf("qobuz cover = %q", got) - } - if data, err := downloadCoverToMemory("", false); err == nil || data != nil { + if data, err := downloadCoverToMemory(""); err == nil || data != nil { t.Fatalf("expected empty cover error") } diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 024e5954..e839a6cd 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -564,8 +564,7 @@ import Gobackend let args = call.arguments as! [String: Any] let coverURL = args["cover_url"] as! String let outputPath = args["output_path"] as! String - let maxQuality = args["max_quality"] as? Bool ?? true - GobackendDownloadCoverToFile(coverURL, outputPath, maxQuality, &error) + GobackendDownloadCoverToFile(coverURL, outputPath, false, &error) if let error = error { throw error } return "{\"success\":true}" diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 9a6c6921..1e567da1 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -382,18 +382,6 @@ abstract class AppLocalizations { /// **'Save synced lyrics alongside your downloaded tracks'** String get optionsEmbedLyricsSubtitle; - /// Download highest quality album art - /// - /// In en, this message translates to: - /// **'Max Quality Cover'** - String get optionsMaxQualityCover; - - /// Subtitle for max quality cover - /// - /// In en, this message translates to: - /// **'Download highest resolution cover art'** - String get optionsMaxQualityCoverSubtitle; - /// Title for ReplayGain setting toggle /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index e3544a68..31b09af6 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -151,13 +151,6 @@ class AppLocalizationsDe extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Speichere synchronisierte Liedtexte zusammen mit heruntergeladenen Titeln'; - @override - String get optionsMaxQualityCover => 'Maximale Cover-Qualität'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Cover in höchster Auflösung herunterladen'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 54da7258..09e140ef 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -148,13 +148,6 @@ class AppLocalizationsEn extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Save synced lyrics alongside your downloaded tracks'; - @override - String get optionsMaxQualityCover => 'Max Quality Cover'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Download highest resolution cover art'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 539ef1e0..2efd104c 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -148,13 +148,6 @@ class AppLocalizationsEs extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Embed synced lyrics into FLAC files'; - @override - String get optionsMaxQualityCover => 'Max Quality Cover'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Download highest resolution cover art'; - @override String get optionsReplayGain => 'ReplayGain'; @@ -5090,13 +5083,6 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get optionsEmbedLyricsSubtitle => 'Guarda las letras sincronizadas junto a las pistas descargadas'; - @override - String get optionsMaxQualityCover => 'Máxima calidad de portada'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Descargar la portada en la mayor resolución'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 7c0dde3f..cdfd84f1 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -151,13 +151,6 @@ class AppLocalizationsFr extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Enregistrez les paroles synchronisées avec vos morceaux téléchargés'; - @override - String get optionsMaxQualityCover => 'Pochette de qualité supérieure'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Télécharger la pochette en haute résolution'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart index 7a4a4d00..e620271e 100644 --- a/lib/l10n/app_localizations_id.dart +++ b/lib/l10n/app_localizations_id.dart @@ -151,13 +151,6 @@ class AppLocalizationsId extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Simpan lirik yang disinkronkan bersama dengan lagu yang Anda unduh'; - @override - String get optionsMaxQualityCover => 'Cover Kualitas Maksimal'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Unduh cover art resolusi tertinggi'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index 1c0d1e5d..bef89963 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -148,12 +148,6 @@ class AppLocalizationsJa extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Save synced lyrics alongside your downloaded tracks'; - @override - String get optionsMaxQualityCover => '最大品質のカバー'; - - @override - String get optionsMaxQualityCoverSubtitle => '最高解像度のカバーアートをダウンロード'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index c2ac4cbd..a90eebcb 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -143,12 +143,6 @@ class AppLocalizationsKo extends AppLocalizations { @override String get optionsEmbedLyricsSubtitle => '다운로드된 트랙과 함께 동기화된 가사를 저장합니다'; - @override - String get optionsMaxQualityCover => '고품질 표지 이미지'; - - @override - String get optionsMaxQualityCoverSubtitle => '최고 해상도의 표지 이미지를 다운로드'; - @override String get optionsReplayGain => '리플레이게인'; diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 604a69df..516c0e96 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -148,13 +148,6 @@ class AppLocalizationsPt extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Embed synced lyrics into FLAC files'; - @override - String get optionsMaxQualityCover => 'Max Quality Cover'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Download highest resolution cover art'; - @override String get optionsReplayGain => 'ReplayGain'; @@ -5089,13 +5082,6 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get optionsEmbedLyricsSubtitle => 'Salve letras sincronizadas ao lado das suas faixas baixadas'; - @override - String get optionsMaxQualityCover => 'Capa de Qualidade Máxima'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Baixar capa do álbum com a mais alta resolução'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 9fe5dad0..24404f1d 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -150,13 +150,6 @@ class AppLocalizationsRu extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Сохранять синхронизированный текст песни рядом с загруженным треком'; - @override - String get optionsMaxQualityCover => 'Максимальное качество обложки'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Скачивать обложку в макс. разрешении'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_tr.dart b/lib/l10n/app_localizations_tr.dart index 329300c1..2e6b202a 100644 --- a/lib/l10n/app_localizations_tr.dart +++ b/lib/l10n/app_localizations_tr.dart @@ -151,13 +151,6 @@ class AppLocalizationsTr extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'İndirdiğiniz parçaların yanına senkronize edilmiş şarkı sözlerini kaydedin'; - @override - String get optionsMaxQualityCover => 'En Yüksek Kapak Kalitesi'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'En yüksek kalitedeki albüm kapaklarını indir'; - @override String get optionsReplayGain => 'ReplayGain'; diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index bd214764..da224306 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -151,13 +151,6 @@ class AppLocalizationsUk extends AppLocalizations { String get optionsEmbedLyricsSubtitle => 'Save synced lyrics alongside your downloaded tracks'; - @override - String get optionsMaxQualityCover => 'Максимальна якість обкладинки'; - - @override - String get optionsMaxQualityCoverSubtitle => - 'Завантажити обкладинку з найвищою роздільною здатністю'; - @override String get optionsReplayGain => 'Нормалізація звуку'; diff --git a/lib/l10n/arb/app_de.arb b/lib/l10n/arb/app_de.arb index 464ca826..eed2699e 100644 --- a/lib/l10n/arb/app_de.arb +++ b/lib/l10n/arb/app_de.arb @@ -922,9 +922,6 @@ "@audioAnalysisMono": { "description": "Audio channel layout label - mono" }, - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, @@ -3249,7 +3246,6 @@ "description": "Tutorial extensions tip 2" }, "libraryFolder": "Bibliotheksordner", - "optionsMaxQualityCoverSubtitle": "Cover in höchster Auflösung herunterladen", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, @@ -5476,9 +5472,6 @@ "nowPlayingDetails": "Details", "collectionWishlistEmptyTitle": "Wunschliste ist leer", "downloadAppleQqMultiPersonEnabled": "Sängerlabel für Duette und Gruppentitel enthalten", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, "@snackbarExtensionUpdatedVersion": { "description": "Snackbar after updating an extension from the repo tab", "placeholders": { @@ -5822,7 +5815,6 @@ "downloadFrom": "Herunterladen von", "collectionWishlistEmptySubtitle": "Tippe auf das + bei den Titeln, um sie zum späteren Herunterladen zu speichern", "cueSplitSplitting": "CUE-Sheet wird geteilt... ({current}/{total})", - "optionsMaxQualityCover": "Maximale Cover-Qualität", "trackOptionAddToWishlist": "Zur Wunschliste hinzufügen", "settingsBackup": "Backup & Restore", "aboutPaxsenixSubtitle": "Lyrics proxy for Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius", diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 186e7dff..1f222d68 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -182,14 +182,6 @@ "@optionsEmbedLyricsSubtitle": { "description": "Subtitle for embed lyrics" }, - "optionsMaxQualityCover": "Max Quality Cover", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, - "optionsMaxQualityCoverSubtitle": "Download highest resolution cover art", - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "optionsReplayGain": "ReplayGain", "@optionsReplayGain": { "description": "Title for ReplayGain setting toggle" diff --git a/lib/l10n/arb/app_es.arb b/lib/l10n/arb/app_es.arb index 0913a72e..fd8b0f11 100644 --- a/lib/l10n/arb/app_es.arb +++ b/lib/l10n/arb/app_es.arb @@ -150,14 +150,6 @@ "@optionsEmbedLyricsSubtitle": { "description": "Subtitle for embed lyrics" }, - "optionsMaxQualityCover": "Max Quality Cover", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, - "optionsMaxQualityCoverSubtitle": "Download highest resolution cover art", - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_es_ES.arb b/lib/l10n/arb/app_es_ES.arb index a2744408..f17b82c9 100644 --- a/lib/l10n/arb/app_es_ES.arb +++ b/lib/l10n/arb/app_es_ES.arb @@ -182,14 +182,6 @@ "@optionsEmbedLyricsSubtitle": { "description": "Subtitle for embed lyrics" }, - "optionsMaxQualityCover": "Máxima calidad de portada", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, - "optionsMaxQualityCoverSubtitle": "Descargar la portada en la mayor resolución", - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "optionsReplayGain": "ReplayGain", "@optionsReplayGain": { "description": "Title for ReplayGain setting toggle" diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb index 46a1cbe8..93c8fa75 100644 --- a/lib/l10n/arb/app_fr.arb +++ b/lib/l10n/arb/app_fr.arb @@ -922,9 +922,6 @@ "@audioAnalysisMono": { "description": "Audio channel layout label - mono" }, - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, @@ -3249,7 +3246,6 @@ "description": "Tutorial extensions tip 2" }, "libraryFolder": "Dossier de bibliothèque", - "optionsMaxQualityCoverSubtitle": "Télécharger la pochette en haute résolution", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, @@ -5476,9 +5472,6 @@ "nowPlayingDetails": "Détails", "collectionWishlistEmptyTitle": "La liste de souhaits est vide", "downloadAppleQqMultiPersonEnabled": "Étiquettes d'intervenants incluses pour les duos et les morceaux en groupe", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, "@snackbarExtensionUpdatedVersion": { "description": "Snackbar after updating an extension from the repo tab", "placeholders": { @@ -5822,7 +5815,6 @@ "downloadFrom": "Télécharger depuis", "collectionWishlistEmptySubtitle": "Appuyez sur le signe « + » à côté des morceaux pour enregistrer ceux que vous souhaitez télécharger plus tard", "cueSplitSplitting": "Fractionnement de la liste CUE... ({current}/{total})", - "optionsMaxQualityCover": "Pochette de qualité supérieure", "trackOptionAddToWishlist": "Ajouter à la liste de souhaits", "settingsBackup": "Sauvegarde & Restauration", "aboutPaxsenixSubtitle": "Proxy de paroles pour Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou et Genius", diff --git a/lib/l10n/arb/app_id.arb b/lib/l10n/arb/app_id.arb index aa47fc0c..e32db072 100644 --- a/lib/l10n/arb/app_id.arb +++ b/lib/l10n/arb/app_id.arb @@ -941,9 +941,6 @@ "@audioAnalysisMono": { "description": "Audio channel layout label - mono" }, - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, @@ -3312,7 +3309,6 @@ "description": "Tutorial extensions tip 2" }, "libraryFolder": "Library Folder", - "optionsMaxQualityCoverSubtitle": "Unduh cover art resolusi tertinggi", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, @@ -5587,9 +5583,6 @@ "nowPlayingDetails": "Details", "collectionWishlistEmptyTitle": "Wishlist is empty", "downloadAppleQqMultiPersonEnabled": "Speaker labels included for duets and group tracks", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, "@snackbarExtensionUpdatedVersion": { "description": "Snackbar after updating an extension from the repo tab", "placeholders": { @@ -5933,7 +5926,6 @@ "downloadFrom": "Unduh Dari", "collectionWishlistEmptySubtitle": "Tap + on tracks to save what you want to download later", "cueSplitSplitting": "Splitting CUE sheet... ({current}/{total})", - "optionsMaxQualityCover": "Cover Kualitas Maksimal", "trackOptionAddToWishlist": "Add to Wishlist", "settingsBackup": "Backup & Restore", "aboutPaxsenixSubtitle": "Lyrics proxy for Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius", diff --git a/lib/l10n/arb/app_ja.arb b/lib/l10n/arb/app_ja.arb index 3a696f5a..68916afb 100644 --- a/lib/l10n/arb/app_ja.arb +++ b/lib/l10n/arb/app_ja.arb @@ -922,9 +922,6 @@ "@audioAnalysisMono": { "description": "Audio channel layout label - mono" }, - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, @@ -3249,7 +3246,6 @@ "description": "Tutorial extensions tip 2" }, "libraryFolder": "ライブラリのフォルダ", - "optionsMaxQualityCoverSubtitle": "最高解像度のカバーアートをダウンロード", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, @@ -5476,9 +5472,6 @@ "nowPlayingDetails": "Details", "collectionWishlistEmptyTitle": "Wishlist is empty", "downloadAppleQqMultiPersonEnabled": "Speaker labels included for duets and group tracks", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, "@snackbarExtensionUpdatedVersion": { "description": "Snackbar after updating an extension from the repo tab", "placeholders": { @@ -5822,7 +5815,6 @@ "downloadFrom": "ダウンロード元", "collectionWishlistEmptySubtitle": "Tap + on tracks to save what you want to download later", "cueSplitSplitting": "Splitting CUE sheet... ({current}/{total})", - "optionsMaxQualityCover": "最大品質のカバー", "trackOptionAddToWishlist": "ウィッシュリストに追加", "settingsBackup": "Backup & Restore", "aboutPaxsenixSubtitle": "Lyrics proxy for Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius", diff --git a/lib/l10n/arb/app_ko.arb b/lib/l10n/arb/app_ko.arb index 6ca17306..eb83157c 100644 --- a/lib/l10n/arb/app_ko.arb +++ b/lib/l10n/arb/app_ko.arb @@ -182,14 +182,6 @@ "@optionsEmbedLyricsSubtitle": { "description": "Subtitle for embed lyrics" }, - "optionsMaxQualityCover": "고품질 표지 이미지", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, - "optionsMaxQualityCoverSubtitle": "최고 해상도의 표지 이미지를 다운로드", - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "optionsReplayGain": "리플레이게인", "@optionsReplayGain": { "description": "Title for ReplayGain setting toggle" diff --git a/lib/l10n/arb/app_pt.arb b/lib/l10n/arb/app_pt.arb index e697a029..a2227015 100644 --- a/lib/l10n/arb/app_pt.arb +++ b/lib/l10n/arb/app_pt.arb @@ -150,14 +150,6 @@ "@optionsEmbedLyricsSubtitle": { "description": "Subtitle for embed lyrics" }, - "optionsMaxQualityCover": "Max Quality Cover", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, - "optionsMaxQualityCoverSubtitle": "Download highest resolution cover art", - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_pt_PT.arb b/lib/l10n/arb/app_pt_PT.arb index 1ddf2329..4c674604 100644 --- a/lib/l10n/arb/app_pt_PT.arb +++ b/lib/l10n/arb/app_pt_PT.arb @@ -922,9 +922,6 @@ "@audioAnalysisMono": { "description": "Audio channel layout label - mono" }, - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, @@ -3249,7 +3246,6 @@ "description": "Tutorial extensions tip 2" }, "libraryFolder": "Library Folder", - "optionsMaxQualityCoverSubtitle": "Baixar capa do álbum com a mais alta resolução", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, @@ -5476,9 +5472,6 @@ "nowPlayingDetails": "Details", "collectionWishlistEmptyTitle": "Wishlist is empty", "downloadAppleQqMultiPersonEnabled": "Speaker labels included for duets and group tracks", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, "@snackbarExtensionUpdatedVersion": { "description": "Snackbar after updating an extension from the repo tab", "placeholders": { @@ -5822,7 +5815,6 @@ "downloadFrom": "Baixar De", "collectionWishlistEmptySubtitle": "Tap + on tracks to save what you want to download later", "cueSplitSplitting": "Splitting CUE sheet... ({current}/{total})", - "optionsMaxQualityCover": "Capa de Qualidade Máxima", "trackOptionAddToWishlist": "Add to Wishlist", "settingsBackup": "Backup & Restore", "aboutPaxsenixSubtitle": "Lyrics proxy for Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius", diff --git a/lib/l10n/arb/app_ru.arb b/lib/l10n/arb/app_ru.arb index 957cc666..23cfc312 100644 --- a/lib/l10n/arb/app_ru.arb +++ b/lib/l10n/arb/app_ru.arb @@ -922,9 +922,6 @@ "@audioAnalysisMono": { "description": "Audio channel layout label - mono" }, - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, @@ -3249,7 +3246,6 @@ "description": "Tutorial extensions tip 2" }, "libraryFolder": "Папка библиотеки", - "optionsMaxQualityCoverSubtitle": "Скачивать обложку в макс. разрешении", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, @@ -5476,9 +5472,6 @@ "nowPlayingDetails": "Details", "collectionWishlistEmptyTitle": "Список желаний пуст", "downloadAppleQqMultiPersonEnabled": "Speaker labels included for duets and group tracks", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, "@snackbarExtensionUpdatedVersion": { "description": "Snackbar after updating an extension from the repo tab", "placeholders": { @@ -5822,7 +5815,6 @@ "downloadFrom": "Скачивать из", "collectionWishlistEmptySubtitle": "Нажмите + на треках, чтобы сохранить то, что вы хотите скачать позже", "cueSplitSplitting": "Разделение CUE sheet... ({current}/{total})", - "optionsMaxQualityCover": "Максимальное качество обложки", "trackOptionAddToWishlist": "Добавить в список желаний", "settingsBackup": "Backup & Restore", "aboutPaxsenixSubtitle": "Lyrics proxy for Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius", diff --git a/lib/l10n/arb/app_tr.arb b/lib/l10n/arb/app_tr.arb index 2ba88039..9d4c4c03 100644 --- a/lib/l10n/arb/app_tr.arb +++ b/lib/l10n/arb/app_tr.arb @@ -922,9 +922,6 @@ "@audioAnalysisMono": { "description": "Audio channel layout label - mono" }, - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, @@ -3249,7 +3246,6 @@ "description": "Tutorial extensions tip 2" }, "libraryFolder": "Kitaplık Klasörü", - "optionsMaxQualityCoverSubtitle": "En yüksek kalitedeki albüm kapaklarını indir", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, @@ -5476,9 +5472,6 @@ "nowPlayingDetails": "Details", "collectionWishlistEmptyTitle": "İstek listesi boş", "downloadAppleQqMultiPersonEnabled": "Speaker labels included for duets and group tracks", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, "@snackbarExtensionUpdatedVersion": { "description": "Snackbar after updating an extension from the repo tab", "placeholders": { @@ -5822,7 +5815,6 @@ "downloadFrom": "İndirme Kaynağı", "collectionWishlistEmptySubtitle": "Daha sonra indirmek istediğiniz parçaları kaydetmek için parçaların üzerine + işaretiyle dokunun", "cueSplitSplitting": "CUE sayfası bölünüyor... ({current}/{total})", - "optionsMaxQualityCover": "En Yüksek Kapak Kalitesi", "trackOptionAddToWishlist": "Add to Wishlist", "settingsBackup": "Backup & Restore", "aboutPaxsenixSubtitle": "Lyrics proxy for Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius", diff --git a/lib/l10n/arb/app_uk.arb b/lib/l10n/arb/app_uk.arb index 75e6024f..3dff5465 100644 --- a/lib/l10n/arb/app_uk.arb +++ b/lib/l10n/arb/app_uk.arb @@ -922,9 +922,6 @@ "@audioAnalysisMono": { "description": "Audio channel layout label - mono" }, - "@optionsMaxQualityCoverSubtitle": { - "description": "Subtitle for max quality cover" - }, "@audioAnalysisNyquist": { "description": "Nyquist frequency metric label" }, @@ -3249,7 +3246,6 @@ "description": "Tutorial extensions tip 2" }, "libraryFolder": "Папка бібліотеки", - "optionsMaxQualityCoverSubtitle": "Завантажити обкладинку з найвищою роздільною здатністю", "@metadataProviderPriorityTitle": { "description": "Metadata priority page title" }, @@ -5476,9 +5472,6 @@ "nowPlayingDetails": "Details", "collectionWishlistEmptyTitle": "Список бажань порожній", "downloadAppleQqMultiPersonEnabled": "Speaker labels included for duets and group tracks", - "@optionsMaxQualityCover": { - "description": "Download highest quality album art" - }, "@snackbarExtensionUpdatedVersion": { "description": "Snackbar after updating an extension from the repo tab", "placeholders": { @@ -5822,7 +5815,6 @@ "downloadFrom": "Завантажити з", "collectionWishlistEmptySubtitle": "Натисніть + на треках, щоб зберегти те, що ви хочете завантажити пізніше", "cueSplitSplitting": "Розділення аркуша CUE... ({current}/{total})", - "optionsMaxQualityCover": "Максимальна якість обкладинки", "trackOptionAddToWishlist": "Додати до списку бажань", "settingsBackup": "Backup & Restore", "aboutPaxsenixSubtitle": "Lyrics proxy for Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius", diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 0fdb6010..dc27dcb7 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -25,7 +25,6 @@ class AppSettings { final bool embedReplayGain; // Apply ReplayGain/R128 tags as volume normalization in the built-in player. final bool playbackNormalization; - final bool maxQualityCover; final bool isFirstLaunch; final bool checkForUpdates; final String updateChannel; @@ -134,7 +133,6 @@ class AppSettings { this.embedLyrics = true, this.embedReplayGain = false, this.playbackNormalization = false, - this.maxQualityCover = true, this.isFirstLaunch = true, this.checkForUpdates = true, this.updateChannel = 'stable', @@ -209,7 +207,6 @@ class AppSettings { bool? embedLyrics, bool? embedReplayGain, bool? playbackNormalization, - bool? maxQualityCover, bool? isFirstLaunch, bool? checkForUpdates, String? updateChannel, @@ -288,7 +285,6 @@ class AppSettings { embedReplayGain: embedReplayGain ?? this.embedReplayGain, playbackNormalization: playbackNormalization ?? this.playbackNormalization, - maxQualityCover: maxQualityCover ?? this.maxQualityCover, isFirstLaunch: isFirstLaunch ?? this.isFirstLaunch, checkForUpdates: checkForUpdates ?? this.checkForUpdates, updateChannel: updateChannel ?? this.updateChannel, diff --git a/lib/models/settings.g.dart b/lib/models/settings.g.dart index 108778ac..4b72643c 100644 --- a/lib/models/settings.g.dart +++ b/lib/models/settings.g.dart @@ -20,7 +20,6 @@ AppSettings _$AppSettingsFromJson(Map json) => AppSettings( embedLyrics: json['embedLyrics'] as bool? ?? true, embedReplayGain: json['embedReplayGain'] as bool? ?? false, playbackNormalization: json['playbackNormalization'] as bool? ?? false, - maxQualityCover: json['maxQualityCover'] as bool? ?? true, isFirstLaunch: json['isFirstLaunch'] as bool? ?? true, checkForUpdates: json['checkForUpdates'] as bool? ?? true, updateChannel: json['updateChannel'] as String? ?? 'stable', @@ -116,7 +115,6 @@ Map _$AppSettingsToJson( 'embedLyrics': instance.embedLyrics, 'embedReplayGain': instance.embedReplayGain, 'playbackNormalization': instance.playbackNormalization, - 'maxQualityCover': instance.maxQualityCover, 'isFirstLaunch': instance.isFirstLaunch, 'checkForUpdates': instance.checkForUpdates, 'updateChannel': instance.updateChannel, diff --git a/lib/providers/download_queue_provider.dart b/lib/providers/download_queue_provider.dart index 5da7e795..d4b0ede2 100644 --- a/lib/providers/download_queue_provider.dart +++ b/lib/providers/download_queue_provider.dart @@ -705,7 +705,6 @@ class DownloadQueueNotifier extends Notifier { settings.embedMetadata && settings.embedLyrics && !_shouldSkipLyrics(extensionState, track.source, item.service), - embedMaxQualityCover: settings.embedMetadata && settings.maxQualityCover, embedReplayGain: settings.embedReplayGain, postProcessingEnabled: postProcessingEnabled, tidalHighFormat: settings.tidalHighFormat, diff --git a/lib/providers/download_queue_provider_embedding.dart b/lib/providers/download_queue_provider_embedding.dart index 53475255..80188f62 100644 --- a/lib/providers/download_queue_provider_embedding.dart +++ b/lib/providers/download_queue_provider_embedding.dart @@ -657,10 +657,7 @@ extension _DownloadQueueEmbedding on DownloadQueueNotifier { // Started here, awaited only after the lyrics fetch below so the two // network round trips overlap. Errors are handled inside the fetch // (it resolves to null), never as an unhandled rejection. - coverFuture = _sharedEmbedCover( - coverUrl, - maxQuality: settings.maxQualityCover, - ); + coverFuture = _sharedEmbedCover(coverUrl); } String? lrcContent; @@ -1021,33 +1018,24 @@ extension _DownloadQueueEmbedding on DownloadQueueNotifier { static const _embedCoverCacheMax = 8; /// One cover fetch per URL, shared by every track in the batch. - Future _sharedEmbedCover( - String coverUrl, { - required bool maxQuality, - }) { - final cacheKey = '${maxQuality ? 'max' : 'original'}|$coverUrl'; - final existing = _embedCoverCache.remove(cacheKey); + Future _sharedEmbedCover(String coverUrl) { + final existing = _embedCoverCache.remove(coverUrl); if (existing != null) { - _embedCoverCache[cacheKey] = existing; // LRU touch + _embedCoverCache[coverUrl] = existing; // LRU touch return existing; } - final fetch = _downloadEmbedCover(coverUrl, maxQuality: maxQuality).then(( - path, - ) { - if (path == null) _embedCoverCache.remove(cacheKey); // allow retry + final fetch = _downloadEmbedCover(coverUrl).then((path) { + if (path == null) _embedCoverCache.remove(coverUrl); // allow retry return path; }); - _embedCoverCache[cacheKey] = fetch; + _embedCoverCache[coverUrl] = fetch; while (_embedCoverCache.length > _embedCoverCacheMax) { _evictEmbedCover(_embedCoverCache.keys.first); } return fetch; } - Future _downloadEmbedCover( - String coverUrl, { - required bool maxQuality, - }) async { + Future _downloadEmbedCover(String coverUrl) async { try { final tempDir = await getTemporaryDirectory(); final uniqueId = @@ -1058,7 +1046,6 @@ extension _DownloadQueueEmbedding on DownloadQueueNotifier { final result = await PlatformBridge.downloadCoverToFile( coverUrl, coverPath, - maxQuality: maxQuality, ); if (result['error'] != null) { _log.w('Failed to download cover: ${result['error']}'); diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 0fafdb35..7d78c54c 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -576,11 +576,6 @@ class SettingsNotifier extends Notifier { _syncLyricsSettingsToBackend(); } - void setMaxQualityCover(bool enabled) { - state = state.copyWith(maxQualityCover: enabled); - _saveSettings(); - } - void setFirstLaunchComplete() { state = state.copyWith(isFirstLaunch: false); _saveSettings(); diff --git a/lib/screens/settings/metadata_settings_page.dart b/lib/screens/settings/metadata_settings_page.dart index bb458ec2..a55eeb78 100644 --- a/lib/screens/settings/metadata_settings_page.dart +++ b/lib/screens/settings/metadata_settings_page.dart @@ -52,15 +52,6 @@ class MetadataSettingsPage extends ConsumerWidget { 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, diff --git a/lib/screens/settings/settings_search_catalog.dart b/lib/screens/settings/settings_search_catalog.dart index 50de51fa..21279430 100644 --- a/lib/screens/settings/settings_search_catalog.dart +++ b/lib/screens/settings/settings_search_catalog.dart @@ -233,12 +233,6 @@ class SettingsSearchCatalog { title: l10n.optionsArtistTagMode, keywords: const ['artist separator', 'multiple artists'], ), - SettingsSearchEntry( - icon: Icons.image, - title: l10n.optionsMaxQualityCover, - subtitle: l10n.optionsMaxQualityCoverSubtitle, - keywords: const ['artwork', 'album art', 'cover size'], - ), SettingsSearchEntry( icon: Icons.graphic_eq, title: l10n.optionsReplayGain, diff --git a/lib/screens/track_metadata_edit_sheet.dart b/lib/screens/track_metadata_edit_sheet.dart index f56b0658..f555ec2c 100644 --- a/lib/screens/track_metadata_edit_sheet.dart +++ b/lib/screens/track_metadata_edit_sheet.dart @@ -37,11 +37,11 @@ class _MetadataCandidateArtworkState extends State<_MetadataCandidateArtwork> { void initState() { super.initState(); if (widget.coverUrl?.isNotEmpty == true) { - unawaited(_loadMaxQualityCover()); + unawaited(_loadCover()); } } - Future _loadMaxQualityCover() async { + Future _loadCover() async { final tempDir = await Directory.systemTemp.createTemp( 'metadata_candidate_cover_', ); @@ -50,7 +50,6 @@ class _MetadataCandidateArtworkState extends State<_MetadataCandidateArtwork> { final result = await PlatformBridge.downloadCoverToFile( widget.coverUrl!, path, - maxQuality: true, ); if (result['error'] != null || !await File(path).exists()) { await tempDir.delete(recursive: true); @@ -588,11 +587,7 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> { ); final coverPath = '${tempDir.path}${Platform.pathSeparator}cover.jpg'; try { - await PlatformBridge.downloadCoverToFile( - coverUrl, - coverPath, - maxQuality: true, - ); + await PlatformBridge.downloadCoverToFile(coverUrl, coverPath); final file = File(coverPath); if (!await file.exists() || await file.length() <= 0) { await tempDir.delete(recursive: true); diff --git a/lib/screens/track_metadata_lyrics.dart b/lib/screens/track_metadata_lyrics.dart index b02c1737..9a034eee 100644 --- a/lib/screens/track_metadata_lyrics.dart +++ b/lib/screens/track_metadata_lyrics.dart @@ -685,14 +685,12 @@ extension _TrackMetadataLyricsAndSaving on _TrackMetadataScreenState { result = await PlatformBridge.downloadCoverToFile( _coverUrl!, tempOutput, - maxQuality: true, ); } } else if (_coverUrl != null && _coverUrl!.isNotEmpty) { result = await PlatformBridge.downloadCoverToFile( _coverUrl!, tempOutput, - maxQuality: true, ); } else { if (mounted) { @@ -781,14 +779,12 @@ extension _TrackMetadataLyricsAndSaving on _TrackMetadataScreenState { result = await PlatformBridge.downloadCoverToFile( _coverUrl!, outputPath, - maxQuality: true, ); } } else if (_coverUrl != null && _coverUrl!.isNotEmpty) { result = await PlatformBridge.downloadCoverToFile( _coverUrl!, outputPath, - maxQuality: true, ); } else { if (mounted) { @@ -996,7 +992,6 @@ extension _TrackMetadataLyricsAndSaving on _TrackMetadataScreenState { final request = { 'file_path': cleanFilePath, 'cover_url': _coverUrl ?? '', - 'max_quality': true, 'embed_lyrics': settings.embedLyrics, 'lyrics_mode': settings.lyricsMode, 'artist_tag_mode': artistTagMode, diff --git a/lib/services/batch_metadata_re_enrich.dart b/lib/services/batch_metadata_re_enrich.dart index cff4b7af..75c6419e 100644 --- a/lib/services/batch_metadata_re_enrich.dart +++ b/lib/services/batch_metadata_re_enrich.dart @@ -81,7 +81,6 @@ Map buildBatchReEnrichRequest({ final request = { 'file_path': item.filePath, 'cover_url': '', - 'max_quality': true, 'embed_lyrics': settings.embedLyrics, 'lyrics_mode': settings.lyricsMode, 'artist_tag_mode': settings.artistTagMode, diff --git a/lib/services/cover_download_service.dart b/lib/services/cover_download_service.dart index 00a5c130..45d16c98 100644 --- a/lib/services/cover_download_service.dart +++ b/lib/services/cover_download_service.dart @@ -37,7 +37,6 @@ class CoverDownloadService { final download = await PlatformBridge.downloadCoverToFile( normalizedUrl, tempPath, - maxQuality: true, ); final error = download['error']?.toString().trim() ?? ''; if (error.isNotEmpty) throw StateError(error); diff --git a/lib/services/download_request_payload.dart b/lib/services/download_request_payload.dart index 4fef1350..32318138 100644 --- a/lib/services/download_request_payload.dart +++ b/lib/services/download_request_payload.dart @@ -18,7 +18,6 @@ class DownloadRequestPayload { final bool embedMetadata; final String artistTagMode; final bool embedLyrics; - final bool embedMaxQualityCover; final bool embedReplayGain; final bool postProcessingEnabled; final String tidalHighFormat; @@ -80,7 +79,6 @@ class DownloadRequestPayload { this.embedMetadata = true, this.artistTagMode = 'joined', this.embedLyrics = true, - this.embedMaxQualityCover = true, this.embedReplayGain = false, this.postProcessingEnabled = false, this.tidalHighFormat = 'mp3_320', @@ -144,7 +142,6 @@ class DownloadRequestPayload { 'embed_metadata': embedMetadata, 'artist_tag_mode': artistTagMode, 'embed_lyrics': embedLyrics, - 'embed_max_quality_cover': embedMaxQualityCover, 'embed_replaygain': embedReplayGain, 'post_processing_enabled': postProcessingEnabled, 'tidal_high_format': tidalHighFormat, @@ -212,7 +209,6 @@ class DownloadRequestPayload { embedMetadata: embedMetadata, artistTagMode: artistTagMode, embedLyrics: embedLyrics, - embedMaxQualityCover: embedMaxQualityCover, embedReplayGain: embedReplayGain, postProcessingEnabled: postProcessingEnabled, tidalHighFormat: tidalHighFormat, diff --git a/lib/services/platform_bridge.dart b/lib/services/platform_bridge.dart index 60e09d14..6747636b 100644 --- a/lib/services/platform_bridge.dart +++ b/lib/services/platform_bridge.dart @@ -899,13 +899,11 @@ class PlatformBridge { static Future> downloadCoverToFile( String coverUrl, - String outputPath, { - bool maxQuality = true, - }) { + String outputPath, + ) { return _invokeMap('downloadCoverToFile', { 'cover_url': coverUrl, 'output_path': outputPath, - 'max_quality': maxQuality, }); } diff --git a/test/models_and_utils_test.dart b/test/models_and_utils_test.dart index 75c2e8e7..a8d95bca 100644 --- a/test/models_and_utils_test.dart +++ b/test/models_and_utils_test.dart @@ -864,7 +864,6 @@ void main() { embedMetadata: false, artistTagMode: artistTagModeSplitVorbis, embedLyrics: false, - embedMaxQualityCover: false, embedReplayGain: true, postProcessingEnabled: true, tidalHighFormat: 'opus_256', @@ -924,7 +923,6 @@ void main() { 'embed_metadata': false, 'artist_tag_mode': artistTagModeSplitVorbis, 'embed_lyrics': false, - 'embed_max_quality_cover': false, 'embed_replaygain': true, 'post_processing_enabled': true, 'tidal_high_format': 'opus_256',