diff --git a/lib/ui/actions/collection/collection_file_actions.dart b/lib/ui/actions/collection/collection_file_actions.dart index 2f39c3086..bf8faecc1 100644 --- a/lib/ui/actions/collection/collection_file_actions.dart +++ b/lib/ui/actions/collection/collection_file_actions.dart @@ -10,6 +10,7 @@ import 'package:photos/models/file.dart'; import 'package:photos/models/selected_files.dart'; import "package:photos/services/collections_service.dart"; import 'package:photos/services/favorites_service.dart'; +import "package:photos/services/hidden_service.dart"; import "package:photos/services/ignored_files_service.dart"; import "package:photos/services/remote_sync_service.dart"; import 'package:photos/ui/actions/collection/collection_sharing_actions.dart'; @@ -18,6 +19,7 @@ import 'package:photos/ui/components/action_sheet_widget.dart'; import 'package:photos/ui/components/buttons/button_widget.dart'; import 'package:photos/ui/components/models/button_type.dart'; import 'package:photos/utils/dialog_util.dart'; +import "package:photos/utils/file_uploader.dart"; import "package:photos/utils/share_util.dart"; import 'package:photos/utils/toast_util.dart'; import "package:receive_sharing_intent/receive_sharing_intent.dart"; @@ -83,7 +85,7 @@ extension CollectionFileActions on CollectionActions { List? sharedFiles, List? pickedFiles, }) async { - final dialog = showProgressDialog + ProgressDialog? dialog = showProgressDialog ? createProgressDialog( context, S.of(context).uploadingFilesToAlbum, @@ -139,9 +141,23 @@ extension CollectionFileActions on CollectionActions { final Collection? c = CollectionsService.instance.getCollectionByID(collectionID); if (c != null && c.owner!.id != currentUserID) { - showToast(context, S.of(context).canNotUploadToAlbumsOwnedByOthers); - await dialog?.hide(); - return false; + if (!showProgressDialog) { + dialog = createProgressDialog( + context, + S.of(context).uploadingFilesToAlbum, + isDismissible: true, + ); + await dialog.show(); + } + final Collection uncat = + await CollectionsService.instance.getUncategorizedCollection(); + for (File unuploadedFile in filesPendingUpload) { + final uploadedFile = await FileUploader.instance.forceUpload( + unuploadedFile, + uncat.id, + ); + files.add(uploadedFile); + } } else { // filesPendingUpload might be getting ignored during auto-upload // because the user deleted these files from ente in the past. diff --git a/lib/utils/file_uploader.dart b/lib/utils/file_uploader.dart index e3c828115..76fb9fb9e 100644 --- a/lib/utils/file_uploader.dart +++ b/lib/utils/file_uploader.dart @@ -24,7 +24,6 @@ import 'package:photos/models/encryption_result.dart'; import 'package:photos/models/file.dart'; import 'package:photos/models/file_type.dart'; import "package:photos/models/metadata/file_magic.dart"; - import 'package:photos/models/upload_url.dart'; import 'package:photos/services/collections_service.dart'; import "package:photos/services/file_magic_service.dart"; @@ -296,20 +295,26 @@ class FileUploader { } } + Future forceUpload(File file, int collectionID) async { + return _tryToUpload(file, collectionID, true); + } + Future _tryToUpload( File file, int collectionID, bool forcedUpload, ) async { await checkNetworkForUpload(isForceUpload: forcedUpload); - final fileOnDisk = await FilesDB.instance.getFile(file.generatedID!); - final wasAlreadyUploaded = fileOnDisk != null && - fileOnDisk.uploadedFileID != null && - (fileOnDisk.updationTime ?? -1) != -1 && - (fileOnDisk.collectionID ?? -1) == collectionID; - if (wasAlreadyUploaded) { - debugPrint("File is already uploaded ${fileOnDisk.tag}"); - return fileOnDisk; + if (!forcedUpload) { + final fileOnDisk = await FilesDB.instance.getFile(file.generatedID!); + final wasAlreadyUploaded = fileOnDisk != null && + fileOnDisk.uploadedFileID != null && + (fileOnDisk.updationTime ?? -1) != -1 && + (fileOnDisk.collectionID ?? -1) == collectionID; + if (wasAlreadyUploaded) { + debugPrint("File is already uploaded ${fileOnDisk.tag}"); + return fileOnDisk; + } } if ((file.localID ?? '') == '') { _logger.severe('Trying to upload file with missing localID'); @@ -590,7 +595,9 @@ class FileUploader { "\n existing: ${sameLocalSameCollection.tag}", ); // should delete the fileToUploadEntry - await FilesDB.instance.deleteByGeneratedID(fileToUpload.generatedID!); + if (fileToUpload.generatedID != null) { + await FilesDB.instance.deleteByGeneratedID(fileToUpload.generatedID!); + } Bus.instance.fire( LocalPhotosUpdatedEvent( @@ -619,7 +626,11 @@ class FileUploader { fileMissingLocal.uploadedFileID!, fileToUpload.localID!, ); - await FilesDB.instance.deleteByGeneratedID(fileToUpload.generatedID!); + // For files selected from device, during collaborative upload, we don't + // insert entries in the FilesDB. So, we don't need to delete the entry + if (fileToUpload.generatedID != null) { + await FilesDB.instance.deleteByGeneratedID(fileToUpload.generatedID!); + } Bus.instance.fire( LocalPhotosUpdatedEvent( [fileToUpload], @@ -848,7 +859,9 @@ class FileUploader { Future _getUploadURL() async { if (_uploadURLs.isEmpty) { - await fetchUploadURLs(_queue.length); + // the queue is empty, fetch at least for one file to handle force uploads + // that are not in the queue. This is to also avoid + await fetchUploadURLs(max(_queue.length, 1)); } try { return _uploadURLs.removeFirst();