From d736e5aafe4dfd64c742688f5e7184ee679879b1 Mon Sep 17 00:00:00 2001 From: zarzet Date: Sat, 6 Jun 2026 21:58:45 +0700 Subject: [PATCH] refactor(download): remove concurrent download option The download API only permits one request at a time, so parallel downloads are removed to avoid wasted/blocked API calls. Downloads now always run sequentially (one track at a time). - Drop concurrentDownloads from AppSettings + JSON serialization - Remove setConcurrentDownloads and the settings UI (1-5 chips + warning) - Strip optionsConcurrent* l10n keys from all ARBs and regenerate - Rework queue worker into _processQueueSequential (single active download) - Update marketing copy and adjust tests --- lib/l10n/app_localizations.dart | 24 --- lib/l10n/app_localizations_ar.dart | 15 -- lib/l10n/app_localizations_de.dart | 15 -- lib/l10n/app_localizations_en.dart | 15 -- lib/l10n/app_localizations_es.dart | 30 ---- lib/l10n/app_localizations_fr.dart | 15 -- lib/l10n/app_localizations_hi.dart | 15 -- lib/l10n/app_localizations_id.dart | 15 -- lib/l10n/app_localizations_ja.dart | 15 -- lib/l10n/app_localizations_ko.dart | 14 -- lib/l10n/app_localizations_nl.dart | 15 -- lib/l10n/app_localizations_pt.dart | 30 ---- lib/l10n/app_localizations_ru.dart | 15 -- lib/l10n/app_localizations_tr.dart | 15 -- lib/l10n/app_localizations_uk.dart | 15 -- lib/l10n/app_localizations_zh.dart | 44 ------ lib/l10n/arb/app_ar.arb | 21 --- lib/l10n/arb/app_de.arb | 21 --- lib/l10n/arb/app_en.arb | 21 --- lib/l10n/arb/app_es.arb | 21 --- lib/l10n/arb/app_es_ES.arb | 21 --- lib/l10n/arb/app_fr.arb | 21 --- lib/l10n/arb/app_hi.arb | 21 --- lib/l10n/arb/app_id.arb | 21 --- lib/l10n/arb/app_ja.arb | 21 --- lib/l10n/arb/app_ko.arb | 21 --- lib/l10n/arb/app_nl.arb | 21 --- lib/l10n/arb/app_pt.arb | 21 --- lib/l10n/arb/app_pt_PT.arb | 21 --- lib/l10n/arb/app_ru.arb | 21 --- lib/l10n/arb/app_tr.arb | 21 --- lib/l10n/arb/app_uk.arb | 21 --- lib/l10n/arb/app_zh.arb | 21 --- lib/l10n/arb/app_zh_CN.arb | 21 --- lib/l10n/arb/app_zh_TW.arb | 21 --- lib/models/settings.dart | 4 - lib/models/settings.g.dart | 2 - lib/providers/download_queue_provider.dart | 37 +---- lib/providers/settings_provider.dart | 6 - .../settings/download_settings_page.dart | 139 ------------------ site/index.html | 2 +- test/models_and_utils_test.dart | 2 - 42 files changed, 9 insertions(+), 889 deletions(-) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index fc04bfa8..a8feb295 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -494,30 +494,6 @@ abstract class AppLocalizations { /// **'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'** String get optionsArtistTagModeSplitVorbisSubtitle; - /// Number of parallel downloads - /// - /// In en, this message translates to: - /// **'Concurrent Downloads'** - String get optionsConcurrentDownloads; - - /// Download one at a time - /// - /// In en, this message translates to: - /// **'Sequential (1 at a time)'** - String get optionsConcurrentSequential; - - /// Multiple parallel downloads - /// - /// In en, this message translates to: - /// **'{count} parallel downloads'** - String optionsConcurrentParallel(int count); - - /// Warning about rate limits - /// - /// In en, this message translates to: - /// **'Parallel downloads may trigger rate limiting'** - String get optionsConcurrentWarning; - /// Show/hide store tab /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index 480a8614..374cc6a9 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -206,21 +206,6 @@ class AppLocalizationsAr extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Concurrent Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequential (1 at a time)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallel downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloads may trigger rate limiting'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index a10431f1..d52427cc 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -211,21 +211,6 @@ class AppLocalizationsDe extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Schreibe einen Künstler Tag pro Künstler für FLAC und Opus; MP3 und M4A bleiben beigetreten.'; - @override - String get optionsConcurrentDownloads => 'Parallele Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequentiell (1 gleichzeitig)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallele Downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallele Downloads können Ratenlimitierung auslösen'; - @override String get optionsExtensionStore => 'Erweiterungs-Repo'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 2573753c..5c719d05 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -206,21 +206,6 @@ class AppLocalizationsEn extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Concurrent Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequential (1 at a time)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallel downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloads may trigger rate limiting'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index c39e5d52..a08f978b 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -206,21 +206,6 @@ class AppLocalizationsEs extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Concurrent Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequential (1 at a time)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallel downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloads may trigger rate limiting'; - @override String get optionsExtensionStore => 'Extension Store'; @@ -4448,21 +4433,6 @@ class AppLocalizationsEsEs extends AppLocalizationsEs { String get optionsArtistTagModeSplitVorbisSubtitle => 'Escribe una etiqueta de artista por artista para FLAC y OPUS; MP3 y M4A se mantienen agrupados.'; - @override - String get optionsConcurrentDownloads => 'Descargas simultáneas'; - - @override - String get optionsConcurrentSequential => 'Secuencial (1 a la vez)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count descargas en paralelo'; - } - - @override - String get optionsConcurrentWarning => - 'Las descargas paralelas pueden activar la limitación de velocidad'; - @override String get optionsExtensionStore => 'Extensión Repo'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index c222c28b..16105a81 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -213,21 +213,6 @@ class AppLocalizationsFr extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Créez une balise « artiste » par artiste pour les fichiers FLAC et Opus ; les fichiers MP3 et M4A restent regroupés.'; - @override - String get optionsConcurrentDownloads => 'Téléchargements simultanés'; - - @override - String get optionsConcurrentSequential => 'Séquentiel (1 à la fois)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count téléchargements simultanés'; - } - - @override - String get optionsConcurrentWarning => - 'Les téléchargements simultanés peuvent déclencher une limitation du débit'; - @override String get optionsExtensionStore => 'Référentiel d\'extensions'; diff --git a/lib/l10n/app_localizations_hi.dart b/lib/l10n/app_localizations_hi.dart index 2817a9f8..79dce4dc 100644 --- a/lib/l10n/app_localizations_hi.dart +++ b/lib/l10n/app_localizations_hi.dart @@ -206,21 +206,6 @@ class AppLocalizationsHi extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Concurrent Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequential (1 at a time)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallel downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloads may trigger rate limiting'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart index 5430cb86..0a6b7b6d 100644 --- a/lib/l10n/app_localizations_id.dart +++ b/lib/l10n/app_localizations_id.dart @@ -209,21 +209,6 @@ class AppLocalizationsId extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Tulis satu tag artis per artis untuk FLAC dan Opus; MP3 dan M4A tetap tergabung.'; - @override - String get optionsConcurrentDownloads => 'Unduhan Bersamaan'; - - @override - String get optionsConcurrentSequential => 'Berurutan (1 per waktu)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count unduhan paralel'; - } - - @override - String get optionsConcurrentWarning => - 'Unduhan paralel dapat memicu pembatasan rate'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index c8743e11..dab2cbb4 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -205,21 +205,6 @@ class AppLocalizationsJa extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => '同時ダウンロード'; - - @override - String get optionsConcurrentSequential => 'Sequential (1 at a time)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count 件の分割ダウンロード'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloads may trigger rate limiting'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index 68ae2e77..4bc9e29d 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -202,20 +202,6 @@ class AppLocalizationsKo extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => '동시 다운로드'; - - @override - String get optionsConcurrentSequential => '순차 다운로드 (한 번에 하나)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count개 동시 다운로드'; - } - - @override - String get optionsConcurrentWarning => '동시에 다수의 음반을 다운로드하면 속도 제한이 발생할 수 있습니다'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 90110db8..75c092f4 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -206,21 +206,6 @@ class AppLocalizationsNl extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Concurrent Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequentiële (1 per keer)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallel downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloaden kan leiden tot rate-limiting'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 636c8959..5f081f3d 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -206,21 +206,6 @@ class AppLocalizationsPt extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Concurrent Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequential (1 at a time)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallel downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloads may trigger rate limiting'; - @override String get optionsExtensionStore => 'Extension Store'; @@ -4447,21 +4432,6 @@ class AppLocalizationsPtPt extends AppLocalizationsPt { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Downloads Simultâneos'; - - @override - String get optionsConcurrentSequential => 'Sequencial (1 por vez)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count downloads paralelos'; - } - - @override - String get optionsConcurrentWarning => - 'Downloads simultâneos podem causar um limite da taxa (ratelimit)'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 3a01b4b4..58c8f224 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -211,21 +211,6 @@ class AppLocalizationsRu extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Одновременные загрузки'; - - @override - String get optionsConcurrentSequential => 'Последовательно (1 за раз)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count параллельных загрузок'; - } - - @override - String get optionsConcurrentWarning => - 'Параллельные загрузки могут вызвать ограничение скорости'; - @override String get optionsExtensionStore => 'Репозиторий расширения'; diff --git a/lib/l10n/app_localizations_tr.dart b/lib/l10n/app_localizations_tr.dart index d5367ef4..5e4abac7 100644 --- a/lib/l10n/app_localizations_tr.dart +++ b/lib/l10n/app_localizations_tr.dart @@ -211,21 +211,6 @@ class AppLocalizationsTr extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'FLAC ve Opus için her sanatçıya ayrı bir etiket yazın; MP3 ve M4A birleşik kalır.'; - @override - String get optionsConcurrentDownloads => 'Eş Zamanlı İndirmeler'; - - @override - String get optionsConcurrentSequential => 'Sıralı (Birer birer)'; - - @override - String optionsConcurrentParallel(int count) { - return 'Aynı anda $count indirme'; - } - - @override - String get optionsConcurrentWarning => - 'Aynı anda birden fazla indirme sınırlamaya takılabilir'; - @override String get optionsExtensionStore => 'Eklenti Deposu'; diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index 90f5d4f6..42c0b184 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -212,21 +212,6 @@ class AppLocalizationsUk extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Для FLAC та Opus на кожного виконавця додати окремий тег виконавця; MP3 та M4A залишаються об’єднаними.'; - @override - String get optionsConcurrentDownloads => 'Кількість одночасних завантажень'; - - @override - String get optionsConcurrentSequential => 'Послідовно (по одному за раз)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count паралельних завантажень'; - } - - @override - String get optionsConcurrentWarning => - 'Паралельні завантаження можуть призвести до обмеження швидкості'; - @override String get optionsExtensionStore => 'Репозиторій розширень'; diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index e359fa71..d9cdf77d 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -206,21 +206,6 @@ class AppLocalizationsZh extends AppLocalizations { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Concurrent Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequential (1 at a time)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallel downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloads may trigger rate limiting'; - @override String get optionsExtensionStore => 'Extension Store'; @@ -4434,20 +4419,6 @@ class AppLocalizationsZhCn extends AppLocalizationsZh { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => '并行下载数'; - - @override - String get optionsConcurrentSequential => '按顺序下载(一次一首)'; - - @override - String optionsConcurrentParallel(int count) { - return '同时下载 $count 首'; - } - - @override - String get optionsConcurrentWarning => '并行下载可能会触发速率限制'; - @override String get optionsExtensionStore => 'Extension Repo'; @@ -8670,21 +8641,6 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { String get optionsArtistTagModeSplitVorbisSubtitle => 'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'; - @override - String get optionsConcurrentDownloads => 'Concurrent Downloads'; - - @override - String get optionsConcurrentSequential => 'Sequential (1 at a time)'; - - @override - String optionsConcurrentParallel(int count) { - return '$count parallel downloads'; - } - - @override - String get optionsConcurrentWarning => - 'Parallel downloads may trigger rate limiting'; - @override String get optionsExtensionStore => 'Extension Repo'; diff --git a/lib/l10n/arb/app_ar.arb b/lib/l10n/arb/app_ar.arb index dd45f5e8..977bd66e 100644 --- a/lib/l10n/arb/app_ar.arb +++ b/lib/l10n/arb/app_ar.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Concurrent Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequential (1 at a time)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallel downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_de.arb b/lib/l10n/arb/app_de.arb index a457d3d1..dceacdff 100644 --- a/lib/l10n/arb/app_de.arb +++ b/lib/l10n/arb/app_de.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Parallele Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequentiell (1 gleichzeitig)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallele Downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallele Downloads können Ratenlimitierung auslösen", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Erweiterungs-Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 20ab89d7..b3a58f94 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Concurrent Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequential (1 at a time)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallel downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_es.arb b/lib/l10n/arb/app_es.arb index 896e4da4..1fa94dcf 100644 --- a/lib/l10n/arb/app_es.arb +++ b/lib/l10n/arb/app_es.arb @@ -182,27 +182,6 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, - "optionsConcurrentDownloads": "Concurrent Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequential (1 at a time)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallel downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Store", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_es_ES.arb b/lib/l10n/arb/app_es_ES.arb index c2540c05..cc027514 100644 --- a/lib/l10n/arb/app_es_ES.arb +++ b/lib/l10n/arb/app_es_ES.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Descargas simultáneas", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Secuencial (1 a la vez)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} descargas en paralelo", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Las descargas paralelas pueden activar la limitación de velocidad", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extensión Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb index 218a08dd..b487562c 100644 --- a/lib/l10n/arb/app_fr.arb +++ b/lib/l10n/arb/app_fr.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Téléchargements simultanés", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Séquentiel (1 à la fois)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} téléchargements simultanés", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Les téléchargements simultanés peuvent déclencher une limitation du débit", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Référentiel d'extensions", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_hi.arb b/lib/l10n/arb/app_hi.arb index 5e6e7bf4..05b508f7 100644 --- a/lib/l10n/arb/app_hi.arb +++ b/lib/l10n/arb/app_hi.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Concurrent Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequential (1 at a time)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallel downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_id.arb b/lib/l10n/arb/app_id.arb index c4ef0056..debee746 100644 --- a/lib/l10n/arb/app_id.arb +++ b/lib/l10n/arb/app_id.arb @@ -206,27 +206,6 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, - "optionsConcurrentDownloads": "Unduhan Bersamaan", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Berurutan (1 per waktu)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} unduhan paralel", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Unduhan paralel dapat memicu pembatasan rate", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_ja.arb b/lib/l10n/arb/app_ja.arb index 5f754c4c..8bf8f7d9 100644 --- a/lib/l10n/arb/app_ja.arb +++ b/lib/l10n/arb/app_ja.arb @@ -190,27 +190,6 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, - "optionsConcurrentDownloads": "同時ダウンロード", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequential (1 at a time)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} 件の分割ダウンロード", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_ko.arb b/lib/l10n/arb/app_ko.arb index 981bf8b7..85a8a319 100644 --- a/lib/l10n/arb/app_ko.arb +++ b/lib/l10n/arb/app_ko.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "동시 다운로드", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "순차 다운로드 (한 번에 하나)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count}개 동시 다운로드", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "동시에 다수의 음반을 다운로드하면 속도 제한이 발생할 수 있습니다", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_nl.arb b/lib/l10n/arb/app_nl.arb index a7283d69..48517c62 100644 --- a/lib/l10n/arb/app_nl.arb +++ b/lib/l10n/arb/app_nl.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Concurrent Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequentiële (1 per keer)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallel downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloaden kan leiden tot rate-limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_pt.arb b/lib/l10n/arb/app_pt.arb index aa9a72e0..86a433ea 100644 --- a/lib/l10n/arb/app_pt.arb +++ b/lib/l10n/arb/app_pt.arb @@ -182,27 +182,6 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, - "optionsConcurrentDownloads": "Concurrent Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequential (1 at a time)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallel downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Store", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_pt_PT.arb b/lib/l10n/arb/app_pt_PT.arb index 4e8a55a8..a8c92844 100644 --- a/lib/l10n/arb/app_pt_PT.arb +++ b/lib/l10n/arb/app_pt_PT.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Downloads Simultâneos", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequencial (1 por vez)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} downloads paralelos", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Downloads simultâneos podem causar um limite da taxa (ratelimit)", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_ru.arb b/lib/l10n/arb/app_ru.arb index e3b5e564..ca91e9b4 100644 --- a/lib/l10n/arb/app_ru.arb +++ b/lib/l10n/arb/app_ru.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Одновременные загрузки", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Последовательно (1 за раз)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} параллельных загрузок", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Параллельные загрузки могут вызвать ограничение скорости", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Репозиторий расширения", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_tr.arb b/lib/l10n/arb/app_tr.arb index 56115ddf..57a5a038 100644 --- a/lib/l10n/arb/app_tr.arb +++ b/lib/l10n/arb/app_tr.arb @@ -190,27 +190,6 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, - "optionsConcurrentDownloads": "Eş Zamanlı İndirmeler", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sıralı (Birer birer)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "Aynı anda {count} indirme", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Aynı anda birden fazla indirme sınırlamaya takılabilir", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Eklenti Deposu", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_uk.arb b/lib/l10n/arb/app_uk.arb index 046ea09a..b7c0481f 100644 --- a/lib/l10n/arb/app_uk.arb +++ b/lib/l10n/arb/app_uk.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Кількість одночасних завантажень", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Послідовно (по одному за раз)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} паралельних завантажень", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Паралельні завантаження можуть призвести до обмеження швидкості", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Репозиторій розширень", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_zh.arb b/lib/l10n/arb/app_zh.arb index 10500b57..b570ed40 100644 --- a/lib/l10n/arb/app_zh.arb +++ b/lib/l10n/arb/app_zh.arb @@ -182,27 +182,6 @@ "@optionsMaxQualityCoverSubtitle": { "description": "Subtitle for max quality cover" }, - "optionsConcurrentDownloads": "Concurrent Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequential (1 at a time)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallel downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Store", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_zh_CN.arb b/lib/l10n/arb/app_zh_CN.arb index 979a4b6e..f5ddf027 100644 --- a/lib/l10n/arb/app_zh_CN.arb +++ b/lib/l10n/arb/app_zh_CN.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "并行下载数", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "按顺序下载(一次一首)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "同时下载 {count} 首", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "并行下载可能会触发速率限制", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/l10n/arb/app_zh_TW.arb b/lib/l10n/arb/app_zh_TW.arb index 0b5eeb5c..98e6f4a2 100644 --- a/lib/l10n/arb/app_zh_TW.arb +++ b/lib/l10n/arb/app_zh_TW.arb @@ -250,27 +250,6 @@ "@optionsArtistTagModeSplitVorbisSubtitle": { "description": "Subtitle for split Vorbis artist tag mode" }, - "optionsConcurrentDownloads": "Concurrent Downloads", - "@optionsConcurrentDownloads": { - "description": "Number of parallel downloads" - }, - "optionsConcurrentSequential": "Sequential (1 at a time)", - "@optionsConcurrentSequential": { - "description": "Download one at a time" - }, - "optionsConcurrentParallel": "{count} parallel downloads", - "@optionsConcurrentParallel": { - "description": "Multiple parallel downloads", - "placeholders": { - "count": { - "type": "int" - } - } - }, - "optionsConcurrentWarning": "Parallel downloads may trigger rate limiting", - "@optionsConcurrentWarning": { - "description": "Warning about rate limits" - }, "optionsExtensionStore": "Extension Repo", "@optionsExtensionStore": { "description": "Show/hide store tab" diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 2c55540b..3f17f53d 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -22,7 +22,6 @@ class AppSettings { final bool embedReplayGain; // Calculate and embed ReplayGain tags final bool maxQualityCover; final bool isFirstLaunch; - final int concurrentDownloads; final bool checkForUpdates; final String updateChannel; final bool hasSearchedBefore; @@ -108,7 +107,6 @@ class AppSettings { this.embedReplayGain = false, this.maxQualityCover = true, this.isFirstLaunch = true, - this.concurrentDownloads = 1, this.checkForUpdates = true, this.updateChannel = 'stable', this.hasSearchedBefore = false, @@ -171,7 +169,6 @@ class AppSettings { bool? embedReplayGain, bool? maxQualityCover, bool? isFirstLaunch, - int? concurrentDownloads, bool? checkForUpdates, String? updateChannel, bool? hasSearchedBefore, @@ -237,7 +234,6 @@ class AppSettings { embedReplayGain: embedReplayGain ?? this.embedReplayGain, maxQualityCover: maxQualityCover ?? this.maxQualityCover, isFirstLaunch: isFirstLaunch ?? this.isFirstLaunch, - concurrentDownloads: concurrentDownloads ?? this.concurrentDownloads, checkForUpdates: checkForUpdates ?? this.checkForUpdates, updateChannel: updateChannel ?? this.updateChannel, hasSearchedBefore: hasSearchedBefore ?? this.hasSearchedBefore, diff --git a/lib/models/settings.g.dart b/lib/models/settings.g.dart index e4216991..dfc1daae 100644 --- a/lib/models/settings.g.dart +++ b/lib/models/settings.g.dart @@ -21,7 +21,6 @@ AppSettings _$AppSettingsFromJson(Map json) => AppSettings( embedReplayGain: json['embedReplayGain'] as bool? ?? false, maxQualityCover: json['maxQualityCover'] as bool? ?? true, isFirstLaunch: json['isFirstLaunch'] as bool? ?? true, - concurrentDownloads: (json['concurrentDownloads'] as num?)?.toInt() ?? 1, checkForUpdates: json['checkForUpdates'] as bool? ?? true, updateChannel: json['updateChannel'] as String? ?? 'stable', hasSearchedBefore: json['hasSearchedBefore'] as bool? ?? false, @@ -102,7 +101,6 @@ Map _$AppSettingsToJson( 'embedReplayGain': instance.embedReplayGain, 'maxQualityCover': instance.maxQualityCover, 'isFirstLaunch': instance.isFirstLaunch, - 'concurrentDownloads': instance.concurrentDownloads, 'checkForUpdates': instance.checkForUpdates, 'updateChannel': instance.updateChannel, 'hasSearchedBefore': instance.hasSearchedBefore, diff --git a/lib/providers/download_queue_provider.dart b/lib/providers/download_queue_provider.dart index 44bbb990..93825481 100644 --- a/lib/providers/download_queue_provider.dart +++ b/lib/providers/download_queue_provider.dart @@ -1767,7 +1767,6 @@ class DownloadQueueState { final String singleFilenameFormat; final String audioQuality; final bool autoFallback; - final int concurrentDownloads; const DownloadQueueState({ this.items = const [], @@ -1780,7 +1779,6 @@ class DownloadQueueState { this.singleFilenameFormat = '{title} - {artist}', this.audioQuality = 'LOSSLESS', this.autoFallback = true, - this.concurrentDownloads = 1, }); DownloadQueueState copyWith({ @@ -1794,7 +1792,6 @@ class DownloadQueueState { String? singleFilenameFormat, String? audioQuality, bool? autoFallback, - int? concurrentDownloads, }) { final resolvedItems = items ?? this.items; return DownloadQueueState( @@ -1814,7 +1811,6 @@ class DownloadQueueState { singleFilenameFormat: singleFilenameFormat ?? this.singleFilenameFormat, audioQuality: audioQuality ?? this.audioQuality, autoFallback: autoFallback ?? this.autoFallback, - concurrentDownloads: concurrentDownloads ?? this.concurrentDownloads, ); } @@ -1962,14 +1958,7 @@ class DownloadQueueNotifier extends Notifier { @override DownloadQueueState build() { ref.listen(settingsProvider, (previous, next) { - final previousConcurrent = - previous?.concurrentDownloads ?? state.concurrentDownloads; updateSettings(next); - if (previousConcurrent != next.concurrentDownloads) { - _log.i( - 'Concurrent downloads updated: $previousConcurrent -> ${next.concurrentDownloads}', - ); - } if (previous?.downloadNetworkMode != next.downloadNetworkMode) { _handleDownloadNetworkModeChanged(next.downloadNetworkMode); } @@ -3601,7 +3590,6 @@ class DownloadQueueNotifier extends Notifier { } void updateSettings(AppSettings settings) { - final concurrentDownloads = settings.concurrentDownloads.clamp(1, 5); state = state.copyWith( outputDir: settings.downloadDirectory.isNotEmpty ? settings.downloadDirectory @@ -3610,7 +3598,6 @@ class DownloadQueueNotifier extends Notifier { singleFilenameFormat: settings.singleFilenameFormat, audioQuality: settings.audioQuality, autoFallback: settings.autoFallback, - concurrentDownloads: concurrentDownloads, ); } @@ -6781,9 +6768,8 @@ class DownloadQueueNotifier extends Notifier { } } - _log.d('Concurrent downloads: ${state.concurrentDownloads}'); try { - await _processQueueParallel(); + await _processQueueSequential(); } finally { if (iosDownloadBookmarkActive) { await PlatformBridge.stopAccessingIosBookmark(); @@ -6859,19 +6845,18 @@ class DownloadQueueNotifier extends Notifier { } } - Future _processQueueParallel() async { + Future _processQueueSequential() async { final activeDownloads = >{}; - var lastLoggedMaxConcurrent = -1; _startMultiProgressPolling(); while (true) { if (state.isPaused) { if (activeDownloads.isEmpty) { - _log.d('Queue is paused and no active downloads remain'); + _log.d('Queue is paused and no active download remains'); break; } - _log.d('Queue is paused, waiting for active downloads...'); + _log.d('Queue is paused, waiting for active download...'); await Future.any([ Future.wait(activeDownloads.values), Future.delayed(_queueSchedulingInterval), @@ -6879,12 +6864,6 @@ class DownloadQueueNotifier extends Notifier { continue; } - final maxConcurrent = max(1, state.concurrentDownloads); - if (lastLoggedMaxConcurrent != maxConcurrent) { - _log.d('Parallel worker max concurrency now: $maxConcurrent'); - lastLoggedMaxConcurrent = maxConcurrent; - } - final queuedItems = state.items .where( (item) => @@ -6898,7 +6877,9 @@ class DownloadQueueNotifier extends Notifier { break; } - while (activeDownloads.length < maxConcurrent && + // One download at a time: only start the next item once the current + // download has finished, to stay within the API's single-request limit. + if (activeDownloads.isEmpty && queuedItems.isNotEmpty && !state.isPaused) { final item = queuedItems.removeAt(0); @@ -6911,9 +6892,7 @@ class DownloadQueueNotifier extends Notifier { }); activeDownloads[item.id] = future; - _log.d( - 'Started parallel download: ${item.track.name} (${activeDownloads.length}/$maxConcurrent active)', - ); + _log.d('Started download: ${item.track.name}'); } if (activeDownloads.isNotEmpty) { diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 949c8360..530d82ee 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -392,12 +392,6 @@ class SettingsNotifier extends Notifier { _saveSettings(); } - void setConcurrentDownloads(int count) { - final clamped = count.clamp(1, 5); - state = state.copyWith(concurrentDownloads: clamped); - _saveSettings(); - } - void setCheckForUpdates(bool enabled) { state = state.copyWith(checkForUpdates: enabled); _saveSettings(); diff --git a/lib/screens/settings/download_settings_page.dart b/lib/screens/settings/download_settings_page.dart index e4d51068..d7b20623 100644 --- a/lib/screens/settings/download_settings_page.dart +++ b/lib/screens/settings/download_settings_page.dart @@ -178,12 +178,6 @@ class _DownloadSettingsPageState extends ConsumerState { SliverToBoxAdapter( child: SettingsGroup( children: [ - _ConcurrentDownloadsItem( - currentValue: settings.concurrentDownloads, - onChanged: (v) => ref - .read(settingsProvider.notifier) - .setConcurrentDownloads(v), - ), SettingsItem( icon: Icons.wifi, title: context.l10n.settingsDownloadNetwork, @@ -1015,139 +1009,6 @@ class _ServiceChip extends StatelessWidget { } } -class _ConcurrentDownloadsItem extends StatelessWidget { - final int currentValue; - final ValueChanged onChanged; - const _ConcurrentDownloadsItem({ - required this.currentValue, - required this.onChanged, - }); - - @override - Widget build(BuildContext context) { - final colorScheme = Theme.of(context).colorScheme; - return Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Icon( - Icons.download_for_offline, - color: colorScheme.onSurfaceVariant, - size: 24, - ), - const SizedBox(width: 16), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - context.l10n.optionsConcurrentDownloads, - style: Theme.of(context).textTheme.bodyLarge, - ), - const SizedBox(height: 2), - Text( - currentValue == 1 - ? context.l10n.optionsConcurrentSequential - : context.l10n.optionsConcurrentParallel( - currentValue, - ), - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: colorScheme.onSurfaceVariant, - ), - ), - ], - ), - ), - ], - ), - const SizedBox(height: 16), - Row( - children: [ - for (final n in [1, 2, 3, 4, 5]) ...[ - if (n > 1) const SizedBox(width: 8), - _ConcurrentChip( - label: '$n', - isSelected: currentValue == n, - onTap: () => onChanged(n), - ), - ], - ], - ), - const SizedBox(height: 12), - Row( - children: [ - Icon( - Icons.warning_amber_rounded, - size: 16, - color: colorScheme.error, - ), - const SizedBox(width: 8), - Expanded( - child: Text( - context.l10n.optionsConcurrentWarning, - style: Theme.of( - context, - ).textTheme.bodySmall?.copyWith(color: colorScheme.error), - ), - ), - ], - ), - ], - ), - ); - } -} - -class _ConcurrentChip extends StatelessWidget { - final String label; - final bool isSelected; - final VoidCallback onTap; - const _ConcurrentChip({ - 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, - ), - ), - ), - ), - ), - ), - ); - } -} - class _MetadataSourceSelector extends ConsumerWidget { const _MetadataSourceSelector(); diff --git a/site/index.html b/site/index.html index b1630e0b..4ff1d0e0 100644 --- a/site/index.html +++ b/site/index.html @@ -454,7 +454,7 @@

Batch & Playlist Download

-

Download entire albums and playlists at once. Smart queue management with concurrent downloads.

+

Download entire albums and playlists at once. Smart queue management that downloads one track at a time.

diff --git a/test/models_and_utils_test.dart b/test/models_and_utils_test.dart index 37127302..69456d39 100644 --- a/test/models_and_utils_test.dart +++ b/test/models_and_utils_test.dart @@ -202,7 +202,6 @@ void main() { final updated = settings.copyWith( defaultService: 'tidal', - concurrentDownloads: 4, embedReplayGain: true, lyricsProviders: ['apple_music'], lyricsAppleElrcWordSync: true, @@ -213,7 +212,6 @@ void main() { ); expect(updated.defaultService, 'tidal'); - expect(updated.concurrentDownloads, 4); expect(updated.embedReplayGain, isTrue); expect(updated.lyricsProviders, ['apple_music']); expect(updated.lyricsAppleElrcWordSync, isTrue);