Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Store sending attachment in temporary file storage #1921

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions lib/src/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,14 @@ class Event extends MatrixEvent {

await room.client.database?.removeEvent(eventId, room.id);

// Delete possible send file requests:
await room.client.database?.deleteFile(
Uri.parse('com.famedly.sendingAttachment://file/$eventId'),
);
await room.client.database?.deleteFile(
Uri.parse('com.famedly.sendingAttachment://thumbnail/$eventId'),
);

if (room.lastEvent != null && room.lastEvent!.eventId == eventId) {
final redactedBecause = Event.fromMatrixEvent(
MatrixEvent(
Expand Down Expand Up @@ -420,12 +428,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 +733,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 @@ -689,9 +689,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 @@ -715,10 +712,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 @@ -755,6 +748,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 @@ -840,12 +849,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 @@ -909,8 +928,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
Loading