Merge branch 'krille/retry-failed-sent-file' into 'main'
fix: Retry sending a file event Closes #276 See merge request famedly/company/frontend/famedlysdk!1004
This commit is contained in:
commit
c027cd276b
|
|
@ -22,6 +22,7 @@ import 'dart:typed_data';
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:html/parser.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:matrix/src/utils/file_send_request_credentials.dart';
|
||||
|
||||
import '../matrix.dart';
|
||||
import 'utils/event_localizations.dart';
|
||||
|
|
@ -136,6 +137,18 @@ class Event extends MatrixEvent {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is failed to send and the file is no longer cached, it should be removed!
|
||||
if (!status.isSent &&
|
||||
{
|
||||
MessageTypes.Image,
|
||||
MessageTypes.Video,
|
||||
MessageTypes.Audio,
|
||||
MessageTypes.File,
|
||||
}.contains(messageType) &&
|
||||
!room.sendingFilePlaceholders.containsKey(eventId)) {
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
static Map<String, dynamic> getMapFromPayload(dynamic payload) {
|
||||
|
|
@ -327,12 +340,34 @@ class Event extends MatrixEvent {
|
|||
/// Try to send this event again. Only works with events of status -1.
|
||||
Future<String?> sendAgain({String? txid}) async {
|
||||
if (!status.isError) return null;
|
||||
// If this is a failed file sending event, try to fetch the file from the
|
||||
// database first.
|
||||
final url = getAttachmentUrl();
|
||||
if (url?.scheme == 'local') {
|
||||
final file = await downloadAndDecryptAttachment();
|
||||
return await room.sendFileEvent(file, extraContent: content);
|
||||
|
||||
// Retry sending a file:
|
||||
if ({
|
||||
MessageTypes.Image,
|
||||
MessageTypes.Video,
|
||||
MessageTypes.Audio,
|
||||
MessageTypes.File,
|
||||
}.contains(messageType)) {
|
||||
final file = room.sendingFilePlaceholders[eventId];
|
||||
if (file == null) {
|
||||
await remove();
|
||||
throw Exception('Can not try to send again. File is no longer cached.');
|
||||
}
|
||||
final thumbnail = room.sendingFileThumbnails[eventId];
|
||||
final credentials = FileSendRequestCredentials.fromJson(unsigned ?? {});
|
||||
final inReplyTo = credentials.inReplyTo == null
|
||||
? null
|
||||
: await room.getEventById(credentials.inReplyTo!);
|
||||
txid ??= unsigned?.tryGet<String>('transaction_id');
|
||||
return await room.sendFileEvent(
|
||||
file,
|
||||
txid: txid,
|
||||
thumbnail: thumbnail,
|
||||
inReplyTo: inReplyTo,
|
||||
editEventId: credentials.editEventId,
|
||||
shrinkImageMaxDimension: credentials.shrinkImageMaxDimension,
|
||||
extraContent: credentials.extraContent,
|
||||
);
|
||||
}
|
||||
|
||||
// we do not remove the event here. It will automatically be updated
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import 'dart:typed_data';
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:html_unescape/html_unescape.dart';
|
||||
import 'package:matrix/src/utils/crypto/crypto.dart';
|
||||
import 'package:matrix/src/utils/file_send_request_credentials.dart';
|
||||
import 'package:matrix/src/utils/space_child.dart';
|
||||
import 'package:matrix/widget.dart';
|
||||
|
||||
|
|
@ -683,6 +684,7 @@ class Room {
|
|||
}
|
||||
|
||||
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
|
||||
|
|
@ -706,6 +708,9 @@ class Room {
|
|||
}) 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(
|
||||
|
|
@ -728,6 +733,12 @@ class Room {
|
|||
unsigned: {
|
||||
messageSendingStatusKey: EventStatus.sending.intValue,
|
||||
'transaction_id': txid,
|
||||
...FileSendRequestCredentials(
|
||||
inReplyTo: inReplyTo?.eventId,
|
||||
editEventId: editEventId,
|
||||
shrinkImageMaxDimension: shrinkImageMaxDimension,
|
||||
extraContent: extraContent,
|
||||
).toJson(),
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
@ -805,14 +816,12 @@ class Room {
|
|||
syncUpdate.rooms!.join!.values.first.timeline!.events!.first
|
||||
.unsigned![messageSendingStatusKey] = EventStatus.error.intValue;
|
||||
await _handleFakeSync(syncUpdate);
|
||||
sendingFilePlaceholders.remove(txid);
|
||||
rethrow;
|
||||
} catch (_) {
|
||||
if (DateTime.now().isAfter(timeoutDate)) {
|
||||
syncUpdate.rooms!.join!.values.first.timeline!.events!.first
|
||||
.unsigned![messageSendingStatusKey] = EventStatus.error.intValue;
|
||||
await _handleFakeSync(syncUpdate);
|
||||
sendingFilePlaceholders.remove(txid);
|
||||
rethrow;
|
||||
}
|
||||
Logs().v('Send File into room failed. Try again...');
|
||||
|
|
@ -875,6 +884,7 @@ class Room {
|
|||
editEventId: editEventId,
|
||||
);
|
||||
sendingFilePlaceholders.remove(txid);
|
||||
sendingFileThumbnails.remove(txid);
|
||||
return eventId;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Famedly Matrix SDK
|
||||
* Copyright (C) 2019, 2020, 2021 Famedly GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class FileSendRequestCredentials {
|
||||
final String? inReplyTo;
|
||||
final String? editEventId;
|
||||
final int? shrinkImageMaxDimension;
|
||||
final Map<String, dynamic>? extraContent;
|
||||
|
||||
const FileSendRequestCredentials({
|
||||
this.inReplyTo,
|
||||
this.editEventId,
|
||||
this.shrinkImageMaxDimension,
|
||||
this.extraContent,
|
||||
});
|
||||
|
||||
factory FileSendRequestCredentials.fromJson(Map<String, dynamic> json) =>
|
||||
FileSendRequestCredentials(
|
||||
inReplyTo: json['in_reply_to'],
|
||||
editEventId: json['edit_event_id'],
|
||||
shrinkImageMaxDimension: json['shrink_image_max_dimension'],
|
||||
extraContent: json['extra_content'],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
if (inReplyTo != null) 'in_reply_to': inReplyTo,
|
||||
if (editEventId != null) 'edit_event_id': editEventId,
|
||||
if (shrinkImageMaxDimension != null)
|
||||
'shrink_image_max_dimension': shrinkImageMaxDimension,
|
||||
if (extraContent != null) 'extra_content': extraContent,
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue