diff --git a/lib/src/client.dart b/lib/src/client.dart index ba1129be..83b71bd6 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -102,6 +102,8 @@ class Client extends MatrixApi { return await function(arg); } + final Duration sendTimelineEventTimeout; + /// Create a client /// [clientName] = unique identifier of this client /// [databaseBuilder]: A function that creates the database instance, that will be used. @@ -137,6 +139,8 @@ class Client extends MatrixApi { /// will use lazy_load_members. /// Set [compute] to the Flutter compute method to enable the SDK to run some /// code in background. + /// Set [timelineEventTimeout] to the preferred time the Client should retry + /// sending events on connection problems or to `Duration.zero` to disable it. Client( this.clientName, { this.databaseBuilder, @@ -158,6 +162,7 @@ class Client extends MatrixApi { this.formatLocalpart = true, this.compute, Filter? syncFilter, + this.sendTimelineEventTimeout = const Duration(minutes: 1), @deprecated bool? debug, }) : syncFilter = syncFilter ?? Filter( diff --git a/lib/src/room.dart b/lib/src/room.dart index aa03cb1c..5ed2fbfe 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -718,18 +718,34 @@ class Room { uploadThumbnail = encryptedThumbnail.toMatrixFile(); } } - final uploadResp = await client.uploadContent( - uploadFile.bytes, - filename: uploadFile.name, - contentType: uploadFile.mimeType, - ); - final thumbnailUploadResp = uploadThumbnail != null - ? await client.uploadContent( - uploadThumbnail.bytes, - filename: uploadThumbnail.name, - contentType: uploadThumbnail.mimeType, - ) - : null; + Uri? uploadResp, thumbnailUploadResp; + + final timeoutDate = DateTime.now().add(client.sendTimelineEventTimeout); + while (uploadResp == null || + (uploadThumbnail != null && thumbnailUploadResp == null)) { + try { + uploadResp = await client.uploadContent( + uploadFile.bytes, + filename: uploadFile.name, + contentType: uploadFile.mimeType, + ); + thumbnailUploadResp = uploadThumbnail != null + ? await client.uploadContent( + uploadThumbnail.bytes, + filename: uploadThumbnail.name, + contentType: uploadThumbnail.mimeType, + ) + : null; + } on MatrixException catch (_) { + rethrow; + } catch (_) { + if (DateTime.now().isAfter(timeoutDate)) { + rethrow; + } + Logs().v('Send File into room failed. Try again...'); + await Future.delayed(Duration(seconds: 1)); + } + } // Send event final content = { @@ -916,6 +932,7 @@ class Room { ); await _handleFakeSync(syncUpdate); + final timeoutDate = DateTime.now().add(client.sendTimelineEventTimeout); // Send the text and on success, store and display a *sent* event. String? res; while (res == null) { @@ -926,20 +943,15 @@ class Room { txid: messageID, ); } catch (e, s) { - if ((DateTime.now().millisecondsSinceEpoch - - sentDate.millisecondsSinceEpoch) < - (1000 * client.sendMessageTimeoutSeconds)) { - Logs().w('[Client] Problem while sending message because of "' + - e.toString() + - '". Try again in 1 seconds...'); - await Future.delayed(Duration(seconds: 1)); - } else { - Logs().w('[Client] Problem while sending message', e, s); + if (e is MatrixException || DateTime.now().isAfter(timeoutDate)) { + Logs().w('Problem while sending message', e, s); syncUpdate.rooms!.join!.values.first.timeline!.events!.first .unsigned![messageSendingStatusKey] = EventStatus.error.intValue; await _handleFakeSync(syncUpdate); return null; } + Logs().w('Problem while sending message: $e Try again in 1 seconds...'); + await Future.delayed(Duration(seconds: 1)); } } syncUpdate.rooms!.join!.values.first.timeline!.events!.first