|
@@ -1,4 +1,8 @@
|
|
|
-import { SelectedState } from 'types/gallery';
|
|
|
+import {
|
|
|
+ SelectedState,
|
|
|
+ SetFilesDownloadProgressAttributes,
|
|
|
+ SetFilesDownloadProgressAttributesCreator,
|
|
|
+} from 'types/gallery';
|
|
|
import {
|
|
|
EnteFile,
|
|
|
EncryptedEnteFile,
|
|
@@ -625,9 +629,96 @@ export function getUniqueFiles(files: EnteFile[]) {
|
|
|
return uniqueFiles;
|
|
|
}
|
|
|
|
|
|
+export async function downloadFilesWithProgress(
|
|
|
+ files: EnteFile[],
|
|
|
+ downloadDirPath: string,
|
|
|
+ setFilesDownloadProgressAttributes: SetFilesDownloadProgressAttributes
|
|
|
+) {
|
|
|
+ if (!files.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const canceller = new AbortController();
|
|
|
+ const increaseSuccess = () => {
|
|
|
+ if (canceller.signal.aborted) return;
|
|
|
+ setFilesDownloadProgressAttributes((prev) => ({
|
|
|
+ ...prev,
|
|
|
+ success: prev.success + 1,
|
|
|
+ }));
|
|
|
+ };
|
|
|
+ const increaseFailed = () => {
|
|
|
+ if (canceller.signal.aborted) return;
|
|
|
+ setFilesDownloadProgressAttributes((prev) => ({
|
|
|
+ ...prev,
|
|
|
+ failed: prev.failed + 1,
|
|
|
+ }));
|
|
|
+ };
|
|
|
+ const isCancelled = () => canceller.signal.aborted;
|
|
|
+
|
|
|
+ setFilesDownloadProgressAttributes({
|
|
|
+ downloadDirPath,
|
|
|
+ success: 0,
|
|
|
+ failed: 0,
|
|
|
+ total: files.length,
|
|
|
+ canceller,
|
|
|
+ });
|
|
|
+
|
|
|
+ if (isElectron()) {
|
|
|
+ await downloadFilesDesktop(
|
|
|
+ files,
|
|
|
+ { increaseSuccess, increaseFailed, isCancelled },
|
|
|
+ downloadDirPath
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ await downloadFiles(files, {
|
|
|
+ increaseSuccess,
|
|
|
+ increaseFailed,
|
|
|
+ isCancelled,
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export async function downloadSelectedFiles(
|
|
|
+ files: EnteFile[],
|
|
|
+ setFilesDownloadProgressAttributes: SetFilesDownloadProgressAttributes
|
|
|
+) {
|
|
|
+ if (!files.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let downloadDirPath: string;
|
|
|
+ if (isElectron()) {
|
|
|
+ downloadDirPath = await ElectronAPIs.selectDirectory();
|
|
|
+ if (!downloadDirPath) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await downloadFilesWithProgress(
|
|
|
+ files,
|
|
|
+ downloadDirPath,
|
|
|
+ setFilesDownloadProgressAttributes
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+export async function downloadSingleFile(
|
|
|
+ file: EnteFile,
|
|
|
+ setFilesDownloadProgressAttributes: SetFilesDownloadProgressAttributes
|
|
|
+) {
|
|
|
+ let downloadDirPath: string;
|
|
|
+ if (isElectron()) {
|
|
|
+ downloadDirPath = await ElectronAPIs.selectDirectory();
|
|
|
+ if (!downloadDirPath) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await downloadFilesWithProgress(
|
|
|
+ [file],
|
|
|
+ downloadDirPath,
|
|
|
+ setFilesDownloadProgressAttributes
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
export async function downloadFiles(
|
|
|
files: EnteFile[],
|
|
|
- progressBarUpdater?: {
|
|
|
+ progressBarUpdater: {
|
|
|
increaseSuccess: () => void;
|
|
|
increaseFailed: () => void;
|
|
|
isCancelled: () => boolean;
|
|
@@ -869,7 +960,8 @@ export const handleFileOps = async (
|
|
|
files: EnteFile[];
|
|
|
}
|
|
|
| ((prev: { files: EnteFile[] }) => { files: EnteFile[] })
|
|
|
- ) => void
|
|
|
+ ) => void,
|
|
|
+ setFilesDownloadProgressAttributesCreator: SetFilesDownloadProgressAttributesCreator
|
|
|
) => {
|
|
|
switch (ops) {
|
|
|
case FILE_OPS_TYPE.TRASH:
|
|
@@ -881,9 +973,17 @@ export const handleFileOps = async (
|
|
|
case FILE_OPS_TYPE.HIDE:
|
|
|
await hideFilesHelper(files, setHiddenFileIds);
|
|
|
break;
|
|
|
- case FILE_OPS_TYPE.DOWNLOAD:
|
|
|
- await downloadFiles(files);
|
|
|
+ case FILE_OPS_TYPE.DOWNLOAD: {
|
|
|
+ const setSelectedFileDownloadProgressAttributes =
|
|
|
+ setFilesDownloadProgressAttributesCreator(
|
|
|
+ `${files.length} files`
|
|
|
+ );
|
|
|
+ await downloadSelectedFiles(
|
|
|
+ files,
|
|
|
+ setSelectedFileDownloadProgressAttributes
|
|
|
+ );
|
|
|
break;
|
|
|
+ }
|
|
|
case FILE_OPS_TYPE.FIX_TIME:
|
|
|
fixTimeHelper(files, setFixCreationTimeAttributes);
|
|
|
break;
|