feat(mobile): add bulk download functionality (#18878)
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Docker / pre-job (push) Waiting to run
Docker / Re-Tag ML () (push) Blocked by required conditions
Docker / Re-Tag ML (-armnn) (push) Blocked by required conditions
Docker / Re-Tag ML (-cuda) (push) Blocked by required conditions
Docker / Re-Tag ML (-openvino) (push) Blocked by required conditions
Docker / Re-Tag ML (-rknn) (push) Blocked by required conditions
Docker / Re-Tag ML (-rocm) (push) Blocked by required conditions
Docker / Re-Tag Server () (push) Blocked by required conditions
Docker / Build and Push ML (armnn, linux/arm64, -armnn) (push) Blocked by required conditions
Docker / Build and Push ML (cpu, ) (push) Blocked by required conditions
Docker / Build and Push ML (cuda, linux/amd64, -cuda) (push) Blocked by required conditions
Docker / Build and Push ML (openvino, linux/amd64, -openvino) (push) Blocked by required conditions
Docker / Build and Push ML (rknn, linux/arm64, -rknn) (push) Blocked by required conditions
Docker / Build and Push ML (rocm, linux/amd64, {"linux/amd64": "mich"}, -rocm) (push) Blocked by required conditions
Docker / Build and Push Server (push) Blocked by required conditions
Docker / Docker Build & Push Server Success (push) Blocked by required conditions
Docker / Docker Build & Push ML Success (push) Blocked by required conditions
Docs build / pre-job (push) Waiting to run
Docs build / Docs Build (push) Blocked by required conditions
Static Code Analysis / pre-job (push) Waiting to run
Static Code Analysis / Run Dart Code Analysis (push) Blocked by required conditions
Static Code Analysis / zizmor (push) Waiting to run
Test / pre-job (push) Waiting to run
Test / Test & Lint Server (push) Blocked by required conditions
Test / Unit Test CLI (push) Blocked by required conditions
Test / Unit Test CLI (Windows) (push) Blocked by required conditions
Test / Lint Web (push) Blocked by required conditions
Test / Test Web (push) Blocked by required conditions
Test / Test i18n (push) Blocked by required conditions
Test / End-to-End Lint (push) Blocked by required conditions
Test / Medium Tests (Server) (push) Blocked by required conditions
Test / End-to-End Tests (Server & CLI) (ubuntu-24.04-arm) (push) Blocked by required conditions
Test / End-to-End Tests (Server & CLI) (ubuntu-latest) (push) Blocked by required conditions
Test / End-to-End Tests (Web) (ubuntu-24.04-arm) (push) Blocked by required conditions
Test / End-to-End Tests (Web) (ubuntu-latest) (push) Blocked by required conditions
Test / End-to-End Tests Success (push) Blocked by required conditions
Test / Unit Test Mobile (push) Blocked by required conditions
Test / Unit Test ML (push) Blocked by required conditions
Test / .github Files Formatting (push) Blocked by required conditions
Test / ShellCheck (push) Waiting to run
Test / OpenAPI Clients (push) Waiting to run
Test / SQL Schema Checks (push) Waiting to run

* feat(mobile): add bulk download functionality and update UI messages

- Added `downloadAll` method to `IDownloadRepository` and its implementation in `DownloadRepository` to handle multiple asset downloads.
- Implemented `downloadAllAsset` in `DownloadStateNotifier` to trigger bulk downloads.
- Updated `DownloadService` to create download tasks for all selected assets.
- Enhanced UI with new download success and failure messages in `en.json`.
- Added download button to `ControlBottomAppBar` and integrated download functionality in `MultiselectGrid`.

* translations use i18n method t()

* Update mobile/lib/services/download.service.dart

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>

* fix(mobile): update download logic in DownloadService

- Changed the download method to utilize downloadAll for handling multiple tasks.
- Simplified remoteId check by removing unnecessary condition.

* sort i18n keys

* remove the download signature from interface and logic as we use the downloadAll now

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
This commit is contained in:
JobiJoba
2025-06-04 21:49:43 +07:00
committed by GitHub
parent 1fb8861e35
commit 8733d1e554
8 changed files with 86 additions and 19 deletions

View File

@@ -14,6 +14,7 @@ import 'package:immich_mobile/extensions/collection_extensions.dart';
import 'package:immich_mobile/models/asset_selection_state.dart';
import 'package:immich_mobile/providers/album/album.provider.dart';
import 'package:immich_mobile/providers/asset.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/download.provider.dart';
import 'package:immich_mobile/providers/backup/manual_upload.provider.dart';
import 'package:immich_mobile/providers/multiselect.provider.dart';
import 'package:immich_mobile/providers/routes.provider.dart';
@@ -23,6 +24,7 @@ import 'package:immich_mobile/services/album.service.dart';
import 'package:immich_mobile/services/stack.service.dart';
import 'package:immich_mobile/utils/immich_loading_overlay.dart';
import 'package:immich_mobile/utils/selection_handlers.dart';
import 'package:immich_mobile/utils/translation.dart';
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
import 'package:immich_mobile/widgets/asset_grid/control_bottom_app_bar.dart';
import 'package:immich_mobile/widgets/asset_grid/immich_asset_grid.dart';
@@ -44,6 +46,7 @@ class MultiselectGrid extends HookConsumerWidget {
this.editEnabled = false,
this.unarchive = false,
this.unfavorite = false,
this.downloadEnabled = true,
this.emptyIndicator,
});
@@ -57,6 +60,7 @@ class MultiselectGrid extends HookConsumerWidget {
final bool archiveEnabled;
final bool unarchive;
final bool deleteEnabled;
final bool downloadEnabled;
final bool favoriteEnabled;
final bool unfavorite;
final bool editEnabled;
@@ -239,6 +243,39 @@ class MultiselectGrid extends HookConsumerWidget {
}
}
void onDownload() async {
processing.value = true;
try {
final toDownload = selection.value.toList();
final results = await ref
.read(downloadStateProvider.notifier)
.downloadAllAsset(toDownload);
final totalCount = toDownload.length;
final successCount = results.where((e) => e).length;
final failedCount = totalCount - successCount;
final msg = failedCount > 0
? t('assets_downloaded_failed', {
'count': successCount,
'error': failedCount,
})
: t('assets_downloaded_successfully', {
'count': successCount,
});
ImmichToast.show(
context: context,
msg: msg,
gravity: ToastGravity.BOTTOM,
);
} finally {
processing.value = false;
selectionEnabledHook.value = false;
}
}
void onDeleteRemote([bool shouldDeletePermanently = false]) async {
processing.value = true;
try {
@@ -474,6 +511,7 @@ class MultiselectGrid extends HookConsumerWidget {
onArchive: archiveEnabled ? onArchiveAsset : null,
onDelete: deleteEnabled ? onDelete : null,
onDeleteServer: deleteEnabled ? onDeleteRemote : null,
onDownload: downloadEnabled ? onDownload : null,
/// local file deletion is allowed irrespective of [deleteEnabled] since it has
/// nothing to do with the state of the asset in the Immich server