mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-30 21:29:36 +02:00
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
This commit is contained in:
1 parent
3a536ad348
commit
d736e5aafe
42 files changed
+9
-889
No files matched your search
@@ -494,30 +494,6 @@ abstract class AppLocalizations {
|
|||||||
/// **'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'**
|
/// **'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'**
|
||||||
String get optionsArtistTagModeSplitVorbisSubtitle;
|
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
|
/// Show/hide store tab
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|||||||
@@ -206,21 +206,6 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -211,21 +211,6 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Schreibe einen Künstler Tag pro Künstler für FLAC und Opus; MP3 und M4A bleiben beigetreten.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Erweiterungs-Repo';
|
String get optionsExtensionStore => 'Erweiterungs-Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -206,21 +206,6 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -206,21 +206,6 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Store';
|
String get optionsExtensionStore => 'Extension Store';
|
||||||
|
|
||||||
@@ -4448,21 +4433,6 @@ class AppLocalizationsEsEs extends AppLocalizationsEs {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Escribe una etiqueta de artista por artista para FLAC y OPUS; MP3 y M4A se mantienen agrupados.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extensión Repo';
|
String get optionsExtensionStore => 'Extensión Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -213,21 +213,6 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Créez une balise « artiste » par artiste pour les fichiers FLAC et Opus ; les fichiers MP3 et M4A restent regroupés.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Référentiel d\'extensions';
|
String get optionsExtensionStore => 'Référentiel d\'extensions';
|
||||||
|
|
||||||
|
|||||||
@@ -206,21 +206,6 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -209,21 +209,6 @@ class AppLocalizationsId extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Tulis satu tag artis per artis untuk FLAC dan Opus; MP3 dan M4A tetap tergabung.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -205,21 +205,6 @@ class AppLocalizationsJa extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -202,20 +202,6 @@ class AppLocalizationsKo extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -206,21 +206,6 @@ class AppLocalizationsNl extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -206,21 +206,6 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Store';
|
String get optionsExtensionStore => 'Extension Store';
|
||||||
|
|
||||||
@@ -4447,21 +4432,6 @@ class AppLocalizationsPtPt extends AppLocalizationsPt {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -211,21 +211,6 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Репозиторий расширения';
|
String get optionsExtensionStore => 'Репозиторий расширения';
|
||||||
|
|
||||||
|
|||||||
@@ -211,21 +211,6 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'FLAC ve Opus için her sanatçıya ayrı bir etiket yazın; MP3 ve M4A birleşik kalır.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Eklenti Deposu';
|
String get optionsExtensionStore => 'Eklenti Deposu';
|
||||||
|
|
||||||
|
|||||||
@@ -212,21 +212,6 @@ class AppLocalizationsUk extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Для FLAC та Opus на кожного виконавця додати окремий тег виконавця; MP3 та M4A залишаються об’єднаними.';
|
'Для FLAC та Opus на кожного виконавця додати окремий тег виконавця; MP3 та M4A залишаються об’єднаними.';
|
||||||
|
|
||||||
@override
|
|
||||||
String get optionsConcurrentDownloads => 'Кількість одночасних завантажень';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get optionsConcurrentSequential => 'Послідовно (по одному за раз)';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String optionsConcurrentParallel(int count) {
|
|
||||||
return '$count паралельних завантажень';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get optionsConcurrentWarning =>
|
|
||||||
'Паралельні завантаження можуть призвести до обмеження швидкості';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get optionsExtensionStore => 'Репозиторій розширень';
|
String get optionsExtensionStore => 'Репозиторій розширень';
|
||||||
|
|
||||||
|
|||||||
@@ -206,21 +206,6 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Store';
|
String get optionsExtensionStore => 'Extension Store';
|
||||||
|
|
||||||
@@ -4434,20 +4419,6 @@ class AppLocalizationsZhCn extends AppLocalizationsZh {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
@@ -8670,21 +8641,6 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
|
|||||||
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
String get optionsArtistTagModeSplitVorbisSubtitle =>
|
||||||
'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.';
|
'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
|
@override
|
||||||
String get optionsExtensionStore => 'Extension Repo';
|
String get optionsExtensionStore => 'Extension Repo';
|
||||||
|
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Erweiterungs-Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -182,27 +182,6 @@
|
|||||||
"@optionsMaxQualityCoverSubtitle": {
|
"@optionsMaxQualityCoverSubtitle": {
|
||||||
"description": "Subtitle for max quality cover"
|
"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": "Extension Store",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extensión Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Référentiel d'extensions",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -206,27 +206,6 @@
|
|||||||
"@optionsMaxQualityCoverSubtitle": {
|
"@optionsMaxQualityCoverSubtitle": {
|
||||||
"description": "Subtitle for max quality cover"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -190,27 +190,6 @@
|
|||||||
"@optionsMaxQualityCoverSubtitle": {
|
"@optionsMaxQualityCoverSubtitle": {
|
||||||
"description": "Subtitle for max quality cover"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -182,27 +182,6 @@
|
|||||||
"@optionsMaxQualityCoverSubtitle": {
|
"@optionsMaxQualityCoverSubtitle": {
|
||||||
"description": "Subtitle for max quality cover"
|
"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": "Extension Store",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Репозиторий расширения",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -190,27 +190,6 @@
|
|||||||
"@optionsMaxQualityCoverSubtitle": {
|
"@optionsMaxQualityCoverSubtitle": {
|
||||||
"description": "Subtitle for max quality cover"
|
"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": "Eklenti Deposu",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Репозиторій розширень",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -182,27 +182,6 @@
|
|||||||
"@optionsMaxQualityCoverSubtitle": {
|
"@optionsMaxQualityCoverSubtitle": {
|
||||||
"description": "Subtitle for max quality cover"
|
"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": "Extension Store",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -250,27 +250,6 @@
|
|||||||
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
"@optionsArtistTagModeSplitVorbisSubtitle": {
|
||||||
"description": "Subtitle for split Vorbis artist tag mode"
|
"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": "Extension Repo",
|
||||||
"@optionsExtensionStore": {
|
"@optionsExtensionStore": {
|
||||||
"description": "Show/hide store tab"
|
"description": "Show/hide store tab"
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class AppSettings {
|
|||||||
final bool embedReplayGain; // Calculate and embed ReplayGain tags
|
final bool embedReplayGain; // Calculate and embed ReplayGain tags
|
||||||
final bool maxQualityCover;
|
final bool maxQualityCover;
|
||||||
final bool isFirstLaunch;
|
final bool isFirstLaunch;
|
||||||
final int concurrentDownloads;
|
|
||||||
final bool checkForUpdates;
|
final bool checkForUpdates;
|
||||||
final String updateChannel;
|
final String updateChannel;
|
||||||
final bool hasSearchedBefore;
|
final bool hasSearchedBefore;
|
||||||
@@ -108,7 +107,6 @@ class AppSettings {
|
|||||||
this.embedReplayGain = false,
|
this.embedReplayGain = false,
|
||||||
this.maxQualityCover = true,
|
this.maxQualityCover = true,
|
||||||
this.isFirstLaunch = true,
|
this.isFirstLaunch = true,
|
||||||
this.concurrentDownloads = 1,
|
|
||||||
this.checkForUpdates = true,
|
this.checkForUpdates = true,
|
||||||
this.updateChannel = 'stable',
|
this.updateChannel = 'stable',
|
||||||
this.hasSearchedBefore = false,
|
this.hasSearchedBefore = false,
|
||||||
@@ -171,7 +169,6 @@ class AppSettings {
|
|||||||
bool? embedReplayGain,
|
bool? embedReplayGain,
|
||||||
bool? maxQualityCover,
|
bool? maxQualityCover,
|
||||||
bool? isFirstLaunch,
|
bool? isFirstLaunch,
|
||||||
int? concurrentDownloads,
|
|
||||||
bool? checkForUpdates,
|
bool? checkForUpdates,
|
||||||
String? updateChannel,
|
String? updateChannel,
|
||||||
bool? hasSearchedBefore,
|
bool? hasSearchedBefore,
|
||||||
@@ -237,7 +234,6 @@ class AppSettings {
|
|||||||
embedReplayGain: embedReplayGain ?? this.embedReplayGain,
|
embedReplayGain: embedReplayGain ?? this.embedReplayGain,
|
||||||
maxQualityCover: maxQualityCover ?? this.maxQualityCover,
|
maxQualityCover: maxQualityCover ?? this.maxQualityCover,
|
||||||
isFirstLaunch: isFirstLaunch ?? this.isFirstLaunch,
|
isFirstLaunch: isFirstLaunch ?? this.isFirstLaunch,
|
||||||
concurrentDownloads: concurrentDownloads ?? this.concurrentDownloads,
|
|
||||||
checkForUpdates: checkForUpdates ?? this.checkForUpdates,
|
checkForUpdates: checkForUpdates ?? this.checkForUpdates,
|
||||||
updateChannel: updateChannel ?? this.updateChannel,
|
updateChannel: updateChannel ?? this.updateChannel,
|
||||||
hasSearchedBefore: hasSearchedBefore ?? this.hasSearchedBefore,
|
hasSearchedBefore: hasSearchedBefore ?? this.hasSearchedBefore,
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ AppSettings _$AppSettingsFromJson(Map<String, dynamic> json) => AppSettings(
|
|||||||
embedReplayGain: json['embedReplayGain'] as bool? ?? false,
|
embedReplayGain: json['embedReplayGain'] as bool? ?? false,
|
||||||
maxQualityCover: json['maxQualityCover'] as bool? ?? true,
|
maxQualityCover: json['maxQualityCover'] as bool? ?? true,
|
||||||
isFirstLaunch: json['isFirstLaunch'] as bool? ?? true,
|
isFirstLaunch: json['isFirstLaunch'] as bool? ?? true,
|
||||||
concurrentDownloads: (json['concurrentDownloads'] as num?)?.toInt() ?? 1,
|
|
||||||
checkForUpdates: json['checkForUpdates'] as bool? ?? true,
|
checkForUpdates: json['checkForUpdates'] as bool? ?? true,
|
||||||
updateChannel: json['updateChannel'] as String? ?? 'stable',
|
updateChannel: json['updateChannel'] as String? ?? 'stable',
|
||||||
hasSearchedBefore: json['hasSearchedBefore'] as bool? ?? false,
|
hasSearchedBefore: json['hasSearchedBefore'] as bool? ?? false,
|
||||||
@@ -102,7 +101,6 @@ Map<String, dynamic> _$AppSettingsToJson(
|
|||||||
'embedReplayGain': instance.embedReplayGain,
|
'embedReplayGain': instance.embedReplayGain,
|
||||||
'maxQualityCover': instance.maxQualityCover,
|
'maxQualityCover': instance.maxQualityCover,
|
||||||
'isFirstLaunch': instance.isFirstLaunch,
|
'isFirstLaunch': instance.isFirstLaunch,
|
||||||
'concurrentDownloads': instance.concurrentDownloads,
|
|
||||||
'checkForUpdates': instance.checkForUpdates,
|
'checkForUpdates': instance.checkForUpdates,
|
||||||
'updateChannel': instance.updateChannel,
|
'updateChannel': instance.updateChannel,
|
||||||
'hasSearchedBefore': instance.hasSearchedBefore,
|
'hasSearchedBefore': instance.hasSearchedBefore,
|
||||||
|
|||||||
@@ -1767,7 +1767,6 @@ class DownloadQueueState {
|
|||||||
final String singleFilenameFormat;
|
final String singleFilenameFormat;
|
||||||
final String audioQuality;
|
final String audioQuality;
|
||||||
final bool autoFallback;
|
final bool autoFallback;
|
||||||
final int concurrentDownloads;
|
|
||||||
|
|
||||||
const DownloadQueueState({
|
const DownloadQueueState({
|
||||||
this.items = const [],
|
this.items = const [],
|
||||||
@@ -1780,7 +1779,6 @@ class DownloadQueueState {
|
|||||||
this.singleFilenameFormat = '{title} - {artist}',
|
this.singleFilenameFormat = '{title} - {artist}',
|
||||||
this.audioQuality = 'LOSSLESS',
|
this.audioQuality = 'LOSSLESS',
|
||||||
this.autoFallback = true,
|
this.autoFallback = true,
|
||||||
this.concurrentDownloads = 1,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
DownloadQueueState copyWith({
|
DownloadQueueState copyWith({
|
||||||
@@ -1794,7 +1792,6 @@ class DownloadQueueState {
|
|||||||
String? singleFilenameFormat,
|
String? singleFilenameFormat,
|
||||||
String? audioQuality,
|
String? audioQuality,
|
||||||
bool? autoFallback,
|
bool? autoFallback,
|
||||||
int? concurrentDownloads,
|
|
||||||
}) {
|
}) {
|
||||||
final resolvedItems = items ?? this.items;
|
final resolvedItems = items ?? this.items;
|
||||||
return DownloadQueueState(
|
return DownloadQueueState(
|
||||||
@@ -1814,7 +1811,6 @@ class DownloadQueueState {
|
|||||||
singleFilenameFormat: singleFilenameFormat ?? this.singleFilenameFormat,
|
singleFilenameFormat: singleFilenameFormat ?? this.singleFilenameFormat,
|
||||||
audioQuality: audioQuality ?? this.audioQuality,
|
audioQuality: audioQuality ?? this.audioQuality,
|
||||||
autoFallback: autoFallback ?? this.autoFallback,
|
autoFallback: autoFallback ?? this.autoFallback,
|
||||||
concurrentDownloads: concurrentDownloads ?? this.concurrentDownloads,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1962,14 +1958,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
|||||||
@override
|
@override
|
||||||
DownloadQueueState build() {
|
DownloadQueueState build() {
|
||||||
ref.listen<AppSettings>(settingsProvider, (previous, next) {
|
ref.listen<AppSettings>(settingsProvider, (previous, next) {
|
||||||
final previousConcurrent =
|
|
||||||
previous?.concurrentDownloads ?? state.concurrentDownloads;
|
|
||||||
updateSettings(next);
|
updateSettings(next);
|
||||||
if (previousConcurrent != next.concurrentDownloads) {
|
|
||||||
_log.i(
|
|
||||||
'Concurrent downloads updated: $previousConcurrent -> ${next.concurrentDownloads}',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (previous?.downloadNetworkMode != next.downloadNetworkMode) {
|
if (previous?.downloadNetworkMode != next.downloadNetworkMode) {
|
||||||
_handleDownloadNetworkModeChanged(next.downloadNetworkMode);
|
_handleDownloadNetworkModeChanged(next.downloadNetworkMode);
|
||||||
}
|
}
|
||||||
@@ -3601,7 +3590,6 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateSettings(AppSettings settings) {
|
void updateSettings(AppSettings settings) {
|
||||||
final concurrentDownloads = settings.concurrentDownloads.clamp(1, 5);
|
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
outputDir: settings.downloadDirectory.isNotEmpty
|
outputDir: settings.downloadDirectory.isNotEmpty
|
||||||
? settings.downloadDirectory
|
? settings.downloadDirectory
|
||||||
@@ -3610,7 +3598,6 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
|||||||
singleFilenameFormat: settings.singleFilenameFormat,
|
singleFilenameFormat: settings.singleFilenameFormat,
|
||||||
audioQuality: settings.audioQuality,
|
audioQuality: settings.audioQuality,
|
||||||
autoFallback: settings.autoFallback,
|
autoFallback: settings.autoFallback,
|
||||||
concurrentDownloads: concurrentDownloads,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6781,9 +6768,8 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_log.d('Concurrent downloads: ${state.concurrentDownloads}');
|
|
||||||
try {
|
try {
|
||||||
await _processQueueParallel();
|
await _processQueueSequential();
|
||||||
} finally {
|
} finally {
|
||||||
if (iosDownloadBookmarkActive) {
|
if (iosDownloadBookmarkActive) {
|
||||||
await PlatformBridge.stopAccessingIosBookmark();
|
await PlatformBridge.stopAccessingIosBookmark();
|
||||||
@@ -6859,19 +6845,18 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _processQueueParallel() async {
|
Future<void> _processQueueSequential() async {
|
||||||
final activeDownloads = <String, Future<void>>{};
|
final activeDownloads = <String, Future<void>>{};
|
||||||
var lastLoggedMaxConcurrent = -1;
|
|
||||||
|
|
||||||
_startMultiProgressPolling();
|
_startMultiProgressPolling();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (state.isPaused) {
|
if (state.isPaused) {
|
||||||
if (activeDownloads.isEmpty) {
|
if (activeDownloads.isEmpty) {
|
||||||
_log.d('Queue is paused and no active downloads remain');
|
_log.d('Queue is paused and no active download remains');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_log.d('Queue is paused, waiting for active downloads...');
|
_log.d('Queue is paused, waiting for active download...');
|
||||||
await Future.any([
|
await Future.any([
|
||||||
Future.wait(activeDownloads.values),
|
Future.wait(activeDownloads.values),
|
||||||
Future<void>.delayed(_queueSchedulingInterval),
|
Future<void>.delayed(_queueSchedulingInterval),
|
||||||
@@ -6879,12 +6864,6 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final maxConcurrent = max(1, state.concurrentDownloads);
|
|
||||||
if (lastLoggedMaxConcurrent != maxConcurrent) {
|
|
||||||
_log.d('Parallel worker max concurrency now: $maxConcurrent');
|
|
||||||
lastLoggedMaxConcurrent = maxConcurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
final queuedItems = state.items
|
final queuedItems = state.items
|
||||||
.where(
|
.where(
|
||||||
(item) =>
|
(item) =>
|
||||||
@@ -6898,7 +6877,9 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
|||||||
break;
|
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 &&
|
queuedItems.isNotEmpty &&
|
||||||
!state.isPaused) {
|
!state.isPaused) {
|
||||||
final item = queuedItems.removeAt(0);
|
final item = queuedItems.removeAt(0);
|
||||||
@@ -6911,9 +6892,7 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
activeDownloads[item.id] = future;
|
activeDownloads[item.id] = future;
|
||||||
_log.d(
|
_log.d('Started download: ${item.track.name}');
|
||||||
'Started parallel download: ${item.track.name} (${activeDownloads.length}/$maxConcurrent active)',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeDownloads.isNotEmpty) {
|
if (activeDownloads.isNotEmpty) {
|
||||||
|
|||||||
@@ -392,12 +392,6 @@ class SettingsNotifier extends Notifier<AppSettings> {
|
|||||||
_saveSettings();
|
_saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setConcurrentDownloads(int count) {
|
|
||||||
final clamped = count.clamp(1, 5);
|
|
||||||
state = state.copyWith(concurrentDownloads: clamped);
|
|
||||||
_saveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCheckForUpdates(bool enabled) {
|
void setCheckForUpdates(bool enabled) {
|
||||||
state = state.copyWith(checkForUpdates: enabled);
|
state = state.copyWith(checkForUpdates: enabled);
|
||||||
_saveSettings();
|
_saveSettings();
|
||||||
|
|||||||
@@ -178,12 +178,6 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
|
|||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: SettingsGroup(
|
child: SettingsGroup(
|
||||||
children: [
|
children: [
|
||||||
_ConcurrentDownloadsItem(
|
|
||||||
currentValue: settings.concurrentDownloads,
|
|
||||||
onChanged: (v) => ref
|
|
||||||
.read(settingsProvider.notifier)
|
|
||||||
.setConcurrentDownloads(v),
|
|
||||||
),
|
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
icon: Icons.wifi,
|
icon: Icons.wifi,
|
||||||
title: context.l10n.settingsDownloadNetwork,
|
title: context.l10n.settingsDownloadNetwork,
|
||||||
@@ -1015,139 +1009,6 @@ class _ServiceChip extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ConcurrentDownloadsItem extends StatelessWidget {
|
|
||||||
final int currentValue;
|
|
||||||
final ValueChanged<int> 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 {
|
class _MetadataSourceSelector extends ConsumerWidget {
|
||||||
const _MetadataSourceSelector();
|
const _MetadataSourceSelector();
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -454,7 +454,7 @@
|
|||||||
<svg class="icon-svg" viewBox="0 0 24 24"><path fill="currentColor" d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H8V4h12v12zm-6-1l-4-4.8h3V5h2v4.2h3L14 14z"/></svg>
|
<svg class="icon-svg" viewBox="0 0 24 24"><path fill="currentColor" d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H8V4h12v12zm-6-1l-4-4.8h3V5h2v4.2h3L14 14z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<h3>Batch & Playlist Download</h3>
|
<h3>Batch & Playlist Download</h3>
|
||||||
<p>Download entire albums and playlists at once. Smart queue management with concurrent downloads.</p>
|
<p>Download entire albums and playlists at once. Smart queue management that downloads one track at a time.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon">
|
<div class="feature-icon">
|
||||||
|
|||||||
@@ -202,7 +202,6 @@ void main() {
|
|||||||
|
|
||||||
final updated = settings.copyWith(
|
final updated = settings.copyWith(
|
||||||
defaultService: 'tidal',
|
defaultService: 'tidal',
|
||||||
concurrentDownloads: 4,
|
|
||||||
embedReplayGain: true,
|
embedReplayGain: true,
|
||||||
lyricsProviders: ['apple_music'],
|
lyricsProviders: ['apple_music'],
|
||||||
lyricsAppleElrcWordSync: true,
|
lyricsAppleElrcWordSync: true,
|
||||||
@@ -213,7 +212,6 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(updated.defaultService, 'tidal');
|
expect(updated.defaultService, 'tidal');
|
||||||
expect(updated.concurrentDownloads, 4);
|
|
||||||
expect(updated.embedReplayGain, isTrue);
|
expect(updated.embedReplayGain, isTrue);
|
||||||
expect(updated.lyricsProviders, ['apple_music']);
|
expect(updated.lyricsProviders, ['apple_music']);
|
||||||
expect(updated.lyricsAppleElrcWordSync, isTrue);
|
expect(updated.lyricsAppleElrcWordSync, isTrue);
|
||||||
|
|||||||
Reference in new issue
Block a user