Skip to content

Commit

Permalink
feat: Store sending attachment in temporary file storage
Browse files Browse the repository at this point in the history
This could make retrying to send
files more easy as the file is
stored in the file storage.

This just replaces the current approach to store
the file in the memory instead so they are gone
on the next session.
For this we need a deleteFile() method for the
database.
  • Loading branch information
krille-chan committed Dec 9, 2024
1 parent f3e249d commit cf0501c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 12 deletions.
31 changes: 28 additions & 3 deletions lib/src/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,29 @@ class Event extends MatrixEvent {
MessageTypes.Audio,
MessageTypes.File,
}.contains(messageType)) {
final file = room.sendingFilePlaceholders[eventId];
final bytes = await room.client.database?.getFile(
Uri.parse('com.famedly.sendingAttachment://file/$eventId'),
);
final file = bytes == null
? null
: MatrixFile(
bytes: bytes,
name: content.tryGet<String>('filename') ?? 'image',
);
if (file == null) {
await cancelSend();
throw Exception('Can not try to send again. File is no longer cached.');
}
final thumbnail = room.sendingFileThumbnails[eventId];
final thumbnailBytes = await room.client.database?.getFile(
Uri.parse('com.famedly.sendingAttachment://thumbnail/$txid'),
);
final thumbnail = thumbnailBytes == null
? null
: MatrixImageFile(
bytes: thumbnailBytes,
name:
'thumbnail_${content.tryGet<String>('filename') ?? 'image'}',
);
final credentials = FileSendRequestCredentials.fromJson(unsigned ?? {});
final inReplyTo = credentials.inReplyTo == null
? null
Expand Down Expand Up @@ -708,7 +725,15 @@ class Event extends MatrixEvent {
throw ("This event has the type '$type' and so it can't contain an attachment.");
}
if (status.isSending) {
final localFile = room.sendingFilePlaceholders[eventId];
final bytes = await room.client.database?.getFile(
Uri.parse('com.famedly.sendingAttachment://file/$eventId'),
);
final localFile = bytes == null
? null
: MatrixImageFile(
bytes: bytes,
name: content.tryGet<String>('filename') ?? 'image',
);
if (localFile != null) return localFile;
}
final database = room.client.database;
Expand Down
42 changes: 33 additions & 9 deletions lib/src/room.dart
Original file line number Diff line number Diff line change
Expand Up @@ -687,9 +687,6 @@ class Room {
return sendEvent(event, txid: txid);
}

final Map<String, MatrixFile> sendingFilePlaceholders = {};
final Map<String, MatrixImageFile> sendingFileThumbnails = {};

/// Sends a [file] to this room after uploading it. Returns the mxc uri of
/// the uploaded file. If [waitUntilSent] is true, the future will wait until
/// the message event has received the server. Otherwise the future will only
Expand All @@ -713,10 +710,6 @@ class Room {
String? threadLastEventId,
}) async {
txid ??= client.generateUniqueTransactionId();
sendingFilePlaceholders[txid] = file;
if (thumbnail != null) {
sendingFileThumbnails[txid] = thumbnail;
}

// Create a fake Event object as a placeholder for the uploading file:
final syncUpdate = SyncUpdate(
Expand Down Expand Up @@ -753,6 +746,22 @@ class Room {
},
),
);
await _handleFakeSync(syncUpdate);

if (client.database?.supportsFileStoring == true) {
await client.database?.storeFile(
Uri.parse('com.famedly.sendingAttachment://file/$txid'),
file.bytes,
DateTime.now().millisecondsSinceEpoch,
);
if (thumbnail != null) {
await client.database?.storeFile(
Uri.parse('com.famedly.sendingAttachment://thumbnail/$txid'),
file.bytes,
DateTime.now().millisecondsSinceEpoch,
);
}
}

MatrixFile uploadFile = file; // ignore: omit_local_variable_types
// computing the thumbnail in case we can
Expand Down Expand Up @@ -838,12 +847,22 @@ class Room {
syncUpdate.rooms!.join!.values.first.timeline!.events!.first
.unsigned![messageSendingStatusKey] = EventStatus.error.intValue;
await _handleFakeSync(syncUpdate);

if (client.database?.supportsFileStoring != true) {
final sendEvent = await getEventById(txid);
await sendEvent?.cancelSend();
}
rethrow;
} catch (_) {
if (DateTime.now().isAfter(timeoutDate)) {
syncUpdate.rooms!.join!.values.first.timeline!.events!.first
.unsigned![messageSendingStatusKey] = EventStatus.error.intValue;
await _handleFakeSync(syncUpdate);

if (client.database?.supportsFileStoring != true) {
final sendEvent = await getEventById(txid);
await sendEvent?.cancelSend();
}
rethrow;
}
Logs().v('Send File into room failed. Try again...');
Expand Down Expand Up @@ -907,8 +926,13 @@ class Room {
threadRootEventId: threadRootEventId,
threadLastEventId: threadLastEventId,
);
sendingFilePlaceholders.remove(txid);
sendingFileThumbnails.remove(txid);
await client.database?.deleteFile(
Uri.parse('com.famedly.sendingAttachment://file/$txid'),
);
await client.database?.deleteFile(
Uri.parse('com.famedly.sendingAttachment://thumbnail/$txid'),
);

return eventId;
}

Expand Down

0 comments on commit cf0501c

Please sign in to comment.