diff --git a/lib/services/sync_service.dart b/lib/services/sync_service.dart index 739b2d4cf..44c22294f 100644 --- a/lib/services/sync_service.dart +++ b/lib/services/sync_service.dart @@ -98,6 +98,9 @@ class SyncService { } on NoActiveSubscriptionError { Bus.instance.fire(SyncStatusUpdate(SyncStatus.error, error: NoActiveSubscriptionError())); + } on StorageLimitExceededError { + Bus.instance.fire(SyncStatusUpdate(SyncStatus.error, + error: StorageLimitExceededError())); } catch (e, s) { _logger.severe(e, s); Bus.instance.fire(SyncStatusUpdate(SyncStatus.error)); @@ -287,7 +290,7 @@ class SyncService { futures.add(future); } try { - await Future.wait(futures); + await Future.wait(futures, eagerError: true); } on InvalidFileError { // Do nothing } catch (e, s) { diff --git a/lib/ui/sync_indicator.dart b/lib/ui/sync_indicator.dart index c77f55621..7530a6141 100644 --- a/lib/ui/sync_indicator.dart +++ b/lib/ui/sync_indicator.dart @@ -138,6 +138,41 @@ class _SyncIndicatorState extends State { ], ), ); + } else if (_event.error is StorageLimitExceededError) { + return Container( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon( + Icons.error_outline, + color: Theme.of(context).accentColor, + ), + Padding(padding: EdgeInsets.all(4)), + Text("storage quota exceeded, backups paused"), + ], + ), + Padding(padding: EdgeInsets.all(6)), + Container( + width: double.infinity, + height: 64, + padding: const EdgeInsets.fromLTRB(80, 0, 80, 0), + child: button("upgrade", onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) { + return SubscriptionPage(); + }, + ), + ); + }), + ), + Padding(padding: EdgeInsets.all(8)), + ], + ), + ); } else { return Container( child: Column( diff --git a/lib/utils/file_uploader.dart b/lib/utils/file_uploader.dart index c4100334e..552a85db9 100644 --- a/lib/utils/file_uploader.dart +++ b/lib/utils/file_uploader.dart @@ -319,23 +319,30 @@ class FileUploader { "decryptionHeader": metadataDecryptionHeader, } }; - final response = await _dio.post( - Configuration.instance.getHttpEndpoint() + "/files", - options: - Options(headers: {"X-Auth-Token": Configuration.instance.getToken()}), - data: request, - ); - final data = response.data; - file.uploadedFileID = data["id"]; - file.collectionID = collectionID; - file.updationTime = data["updationTime"]; - file.ownerID = data["ownerID"]; - file.encryptedKey = encryptedKey; - file.keyDecryptionNonce = keyDecryptionNonce; - file.fileDecryptionHeader = fileDecryptionHeader; - file.thumbnailDecryptionHeader = thumbnailDecryptionHeader; - file.metadataDecryptionHeader = metadataDecryptionHeader; - return file; + try { + final response = await _dio.post( + Configuration.instance.getHttpEndpoint() + "/files", + options: Options( + headers: {"X-Auth-Token": Configuration.instance.getToken()}), + data: request, + ); + final data = response.data; + file.uploadedFileID = data["id"]; + file.collectionID = collectionID; + file.updationTime = data["updationTime"]; + file.ownerID = data["ownerID"]; + file.encryptedKey = encryptedKey; + file.keyDecryptionNonce = keyDecryptionNonce; + file.fileDecryptionHeader = fileDecryptionHeader; + file.thumbnailDecryptionHeader = thumbnailDecryptionHeader; + file.metadataDecryptionHeader = metadataDecryptionHeader; + return file; + } on DioError catch (e) { + if (e.response.statusCode == 426) { + throw StorageLimitExceededError(); + } + throw e; + } } Future _updateFile( @@ -362,19 +369,26 @@ class FileUploader { "decryptionHeader": metadataDecryptionHeader, } }; - final response = await _dio.post( - Configuration.instance.getHttpEndpoint() + "/files", - options: - Options(headers: {"X-Auth-Token": Configuration.instance.getToken()}), - data: request, - ); - final data = response.data; - file.uploadedFileID = data["id"]; - file.updationTime = data["updationTime"]; - file.fileDecryptionHeader = fileDecryptionHeader; - file.thumbnailDecryptionHeader = thumbnailDecryptionHeader; - file.metadataDecryptionHeader = metadataDecryptionHeader; - return file; + try { + final response = await _dio.post( + Configuration.instance.getHttpEndpoint() + "/files", + options: Options( + headers: {"X-Auth-Token": Configuration.instance.getToken()}), + data: request, + ); + final data = response.data; + file.uploadedFileID = data["id"]; + file.updationTime = data["updationTime"]; + file.fileDecryptionHeader = fileDecryptionHeader; + file.thumbnailDecryptionHeader = thumbnailDecryptionHeader; + file.metadataDecryptionHeader = metadataDecryptionHeader; + return file; + } on DioError catch (e) { + if (e.response.statusCode == 426) { + throw StorageLimitExceededError(); + } + throw e; + } } Future _getUploadURL() async { @@ -460,3 +474,5 @@ class WiFiUnavailableError extends Error {} class SyncStopRequestedError extends Error {} class NoActiveSubscriptionError extends Error {} + +class StorageLimitExceededError extends Error {}