diff --git a/mobile/lib/models/backup/backup_item.dart b/mobile/lib/models/backup/backup_item.dart index 02ea0c442d..957f0f883c 100644 --- a/mobile/lib/models/backup/backup_item.dart +++ b/mobile/lib/models/backup/backup_item.dart @@ -8,12 +8,14 @@ class BackupItem { final EnteFile file; final int collectionID; final Completer completer; + final Object? error; BackupItem({ required this.status, required this.file, required this.collectionID, required this.completer, + this.error, }); BackupItem copyWith({ @@ -21,18 +23,20 @@ class BackupItem { EnteFile? file, int? collectionID, Completer? completer, + Object? error, }) { return BackupItem( status: status ?? this.status, file: file ?? this.file, collectionID: collectionID ?? this.collectionID, completer: completer ?? this.completer, + error: error ?? this.error, ); } @override String toString() { - return 'BackupItem(status: $status, file: $file, collectionID: $collectionID)'; + return 'BackupItem(status: $status, file: $file, collectionID: $collectionID, error: $error)'; } @override @@ -42,7 +46,8 @@ class BackupItem { return other.status == status && other.file == file && other.collectionID == collectionID && - other.completer == completer; + other.completer == completer && + other.error == error; } @override diff --git a/mobile/lib/ui/settings/backup/backup_item_card.dart b/mobile/lib/ui/settings/backup/backup_item_card.dart index e99d1ed54b..40be26cbdc 100644 --- a/mobile/lib/ui/settings/backup/backup_item_card.dart +++ b/mobile/lib/ui/settings/backup/backup_item_card.dart @@ -147,17 +147,17 @@ class _BackupItemCardState extends State { color: Color(0xFFFDB816), ), onPressed: () async { - await FileUploader.instance.forceUpload( + await FileUploader.instance.upload( widget.item.file, widget.item.collectionID, ); }, ), BackupItemStatus.inBackground => SizedBox( - width: 24, - height: 24, - child: Icon( - Icons.lock_reset, + width: 16, + height: 16, + child: CircularProgressIndicator( + strokeWidth: 2.0, color: Theme.of(context).brightness == Brightness.light ? const Color.fromRGBO(0, 0, 0, .6) : const Color.fromRGBO(255, 255, 255, .6), diff --git a/mobile/lib/ui/settings/backup/backup_status_screen.dart b/mobile/lib/ui/settings/backup/backup_status_screen.dart index 4117e2c980..0d7199ca47 100644 --- a/mobile/lib/ui/settings/backup/backup_status_screen.dart +++ b/mobile/lib/ui/settings/backup/backup_status_screen.dart @@ -91,12 +91,13 @@ class _BackupStatusScreenState extends State { vertical: 20, horizontal: 16, ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - for (final item in items) - BackupItemCard(item: item), - ], + child: ListView.builder( + shrinkWrap: true, + primary: false, + itemBuilder: (context, index) { + return BackupItemCard(item: items[index]); + }, + itemCount: items.length, ), ); }, diff --git a/mobile/lib/utils/file_uploader.dart b/mobile/lib/utils/file_uploader.dart index c4c8217c5e..0b3ee1c4bc 100644 --- a/mobile/lib/utils/file_uploader.dart +++ b/mobile/lib/utils/file_uploader.dart @@ -219,6 +219,7 @@ class FileUploader { _queue.remove(id)?.completer.completeError(reason); _allBackups[id] = _allBackups[id]!.copyWith( status: BackupItemStatus.retry, + error: reason, ); Bus.instance.fire(BackupUpdatedEvent(_allBackups)); } @@ -243,8 +244,8 @@ class FileUploader { }); for (final id in uploadsToBeRemoved) { _queue.remove(id)?.completer.completeError(reason); - _allBackups[id] = - _allBackups[id]!.copyWith(status: BackupItemStatus.retry); + _allBackups[id] = _allBackups[id]! + .copyWith(status: BackupItemStatus.retry, error: reason); Bus.instance.fire(BackupUpdatedEvent(_allBackups)); } _logger.info( @@ -283,6 +284,10 @@ class FileUploader { } if (pendingEntry != null) { pendingEntry.status = UploadStatus.inProgress; + _allBackups[pendingEntry.file.localID!] = + _allBackups[pendingEntry.file.localID]! + .copyWith(status: BackupItemStatus.uploading); + Bus.instance.fire(BackupUpdatedEvent(_allBackups)); _encryptAndUploadFileToCollection( pendingEntry.file, pendingEntry.collectionID, @@ -314,6 +319,7 @@ class FileUploader { _queue.remove(localID)!.completer.complete(uploadedFile); _allBackups[localID] = _allBackups[localID]!.copyWith(status: BackupItemStatus.completed); + Bus.instance.fire(BackupUpdatedEvent(_allBackups)); return uploadedFile; } catch (e) { if (e is LockAlreadyAcquiredError) { @@ -324,8 +330,8 @@ class FileUploader { return _queue[localID]!.completer.future; } else { _queue.remove(localID)!.completer.completeError(e); - _allBackups[localID] = - _allBackups[localID]!.copyWith(status: BackupItemStatus.retry); + _allBackups[localID] = _allBackups[localID]! + .copyWith(status: BackupItemStatus.retry, error: e); Bus.instance.fire(BackupUpdatedEvent(_allBackups)); return null; } @@ -435,18 +441,24 @@ class FileUploader { Future forceUpload(EnteFile file, int collectionID) async { _hasInitiatedForceUpload = true; + final isInQueue = _allBackups[file.localID!] != null; try { final result = await _tryToUpload(file, collectionID, true); - _allBackups[file.localID!] = _allBackups[file.localID]!.copyWith( - status: BackupItemStatus.completed, - ); - Bus.instance.fire(BackupUpdatedEvent(_allBackups)); + if (isInQueue) { + _allBackups[file.localID!] = _allBackups[file.localID]!.copyWith( + status: BackupItemStatus.completed, + ); + Bus.instance.fire(BackupUpdatedEvent(_allBackups)); + } return result; - } catch (_) { - _allBackups[file.localID!] = _allBackups[file.localID]!.copyWith( - status: BackupItemStatus.retry, - ); - Bus.instance.fire(BackupUpdatedEvent(_allBackups)); + } catch (error) { + if (isInQueue) { + _allBackups[file.localID!] = _allBackups[file.localID]!.copyWith( + status: BackupItemStatus.retry, + error: error, + ); + Bus.instance.fire(BackupUpdatedEvent(_allBackups)); + } rethrow; } } @@ -1335,8 +1347,10 @@ class FileUploader { } else { _logger.info("Background upload failure detected"); completer?.completeError(SilentlyCancelUploadsError()); - _allBackups[upload.key] = - _allBackups[upload.key]!.copyWith(status: BackupItemStatus.retry); + _allBackups[upload.key] = _allBackups[upload.key]!.copyWith( + status: BackupItemStatus.retry, + error: SilentlyCancelUploadsError(), + ); } Bus.instance.fire(BackupUpdatedEvent(_allBackups)); }