feat(queue): add download-next action on queued items

Queued rows get a skip-next button that reinserts the item ahead of all
other queued items, so the next free slot picks it up. During an active
native worker run the current batch keeps its order; the new order
applies from the next run.
This commit is contained in:
zarzet
2026-07-26 17:39:28 +07:00
parent 48f01ba146
commit c9470ef751
19 changed files with 103 additions and 8 deletions
+6
View File
@@ -6220,6 +6220,12 @@ abstract class AppLocalizations {
/// **'Finalizing download'**
String get queueFinalizingDownload;
/// Tooltip on a queued download row; moves the item to the front of the queue so the next free slot downloads it
///
/// In en, this message translates to:
/// **'Download next'**
String get queueDownloadNext;
/// Accessibility label when a downloaded file is missing from disk
///
/// In en, this message translates to:
+3
View File
@@ -3739,6 +3739,9 @@ class AppLocalizationsAr extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3785,6 +3785,9 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Download wird abgeschlossen';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Heruntergeladene Datei fehlt';
+3
View File
@@ -3739,6 +3739,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3733,6 +3733,9 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3839,6 +3839,9 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Téléchargement en cours';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Fichier téléchargé manquant';
+3
View File
@@ -3739,6 +3739,9 @@ class AppLocalizationsHi extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3742,6 +3742,9 @@ class AppLocalizationsId extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3728,6 +3728,9 @@ class AppLocalizationsJa extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3630,6 +3630,9 @@ class AppLocalizationsKo extends AppLocalizations {
@override
String get queueFinalizingDownload => '다운로드를 마무리하는 중';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => '다운로드한 파일이 없음';
+3
View File
@@ -3739,6 +3739,9 @@ class AppLocalizationsNl extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3733,6 +3733,9 @@ class AppLocalizationsPt extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3770,6 +3770,9 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3769,6 +3769,9 @@ class AppLocalizationsTr extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3787,6 +3787,9 @@ class AppLocalizationsUk extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+3
View File
@@ -3733,6 +3733,9 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get queueFinalizingDownload => 'Finalizing download';
@override
String get queueDownloadNext => 'Download next';
@override
String get queueDownloadedFileMissing => 'Downloaded file missing';
+4
View File
@@ -4845,6 +4845,10 @@
"@queueFinalizingDownload": {
"description": "Accessibility label for a queue item that is finalizing"
},
"queueDownloadNext": "Download next",
"@queueDownloadNext": {
"description": "Tooltip on a queued download row; moves the item to the front of the queue so the next free slot downloads it"
},
"queueDownloadedFileMissing": "Downloaded file missing",
"@queueDownloadedFileMissing": {
"description": "Accessibility label when a downloaded file is missing from disk"
@@ -1670,6 +1670,26 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
}
}
/// Reinserts a queued item ahead of all other queued items so the next
/// free download slot picks it up. During an active native worker run the
/// current batch keeps its order; the new order applies from the next run.
void downloadNext(String id) {
final items = state.items;
final index = items.indexWhere((item) => item.id == id);
if (index == -1) return;
final item = items[index];
if (item.status != DownloadStatus.queued) return;
final firstQueuedIndex = items.indexWhere(
(candidate) => candidate.status == DownloadStatus.queued,
);
if (firstQueuedIndex == index) return;
final reordered = List<DownloadItem>.from(items)
..removeAt(index)
..insert(firstQueuedIndex, item);
state = state.copyWith(items: reordered);
_saveQueueToStorage();
}
void removeItem(String id) {
final removedItem = state.items.where((item) => item.id == id).firstOrNull;
_locallyCancelledItemIds.remove(id);
+28 -8
View File
@@ -486,14 +486,34 @@ extension _QueueTabItemWidgets on _QueueTabState {
) {
switch (item.status) {
case DownloadStatus.queued:
return IconButton(
onPressed: () =>
ref.read(downloadQueueProvider.notifier).cancelItem(item.id),
icon: Icon(Icons.close, color: colorScheme.error),
tooltip: context.l10n.dialogCancel,
style: IconButton.styleFrom(
backgroundColor: colorScheme.errorContainer.withValues(alpha: 0.3),
),
return Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: () => ref
.read(downloadQueueProvider.notifier)
.downloadNext(item.id),
icon: Icon(Icons.skip_next, color: colorScheme.primary),
tooltip: context.l10n.queueDownloadNext,
style: IconButton.styleFrom(
backgroundColor: colorScheme.primaryContainer.withValues(
alpha: 0.3,
),
),
),
const SizedBox(width: 4),
IconButton(
onPressed: () =>
ref.read(downloadQueueProvider.notifier).cancelItem(item.id),
icon: Icon(Icons.close, color: colorScheme.error),
tooltip: context.l10n.dialogCancel,
style: IconButton.styleFrom(
backgroundColor: colorScheme.errorContainer.withValues(
alpha: 0.3,
),
),
),
],
);
case DownloadStatus.downloading:
return IconButton(