fix receipts are getting deleted if message was removed
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run

This commit is contained in:
otsmr 2026-04-20 11:38:25 +02:00
parent 75b9d3e379
commit 37c5ce933d
4 changed files with 44 additions and 19 deletions

View file

@ -64,18 +64,39 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
return query.map((row) => row.readTable(messages)).watch();
}
Stream<Message?> watchLastMessage(String groupId) {
Future<Stream<Message?>> watchLastMessage(String groupId) async {
final group = await twonlyDB.groupsDao.getGroup(groupId);
final deletionTime = clock.now().subtract(
Duration(
milliseconds: group!.deleteMessagesAfterMilliseconds,
),
);
return (select(messages)
..where((t) => t.groupId.equals(groupId))
..where(
(t) =>
t.groupId.equals(groupId) &
// messages in groups will only be removed in case all members have received it...
// so ensuring that this message is not shown in the messages anymore
t.openedAt.isBiggerThanValue(deletionTime),
)
..orderBy([(t) => OrderingTerm.desc(t.createdAt)])
..limit(1))
.watchSingleOrNull();
}
Stream<List<Message>> watchByGroupId(String groupId) {
Future<Stream<List<Message>>> watchByGroupId(String groupId) async {
final group = await twonlyDB.groupsDao.getGroup(groupId);
final deletionTime = clock.now().subtract(
Duration(
milliseconds: group!.deleteMessagesAfterMilliseconds,
),
);
return ((select(messages)..where(
(t) =>
t.groupId.equals(groupId) &
// messages in groups will only be removed in case all members have received it...
// so ensuring that this message is not shown in the messages anymore
t.openedAt.isBiggerThanValue(deletionTime) &
(t.isDeletedFromSender.equals(true) |
(t.type.equals(MessageType.text.name).not() |
t.type.equals(MessageType.media.name).not()) |
@ -127,7 +148,8 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
(m.mediaStored.equals(true) &
m.isDeletedFromSender.equals(true) |
m.mediaStored.equals(false)) &
(m.openedAt.isSmallerThanValue(deletionTime) |
// Only remove the message when ALL members have seen it. Otherwise the receipt will also be deleted which could cause issues in case a member opens the image later..
(m.openedByAll.isSmallerThanValue(deletionTime) |
(m.isDeletedFromSender.equals(true) &
m.createdAt.isSmallerThanValue(deletionTime))),
))

View file

@ -102,21 +102,23 @@ Future<(Uint8List, Uint8List?)?> tryToSendCompleteMessage({
message.encryptedContent,
);
final pushNotification = await getPushNotificationFromEncryptedContent(
receipt.contactId,
receipt.messageId,
encryptedContent,
);
Log.info('Uploading $receiptId. (${pushNotification?.kind})');
Log.info('Uploading $receiptId.');
Uint8List? pushData;
if (pushNotification != null && receipt.retryCount <= 1) {
// Only show the push notification the first two time.
pushData = await encryptPushNotification(
if (receipt.retryCount == 0) {
final pushNotification = await getPushNotificationFromEncryptedContent(
receipt.contactId,
pushNotification,
receipt.messageId,
encryptedContent,
);
if (pushNotification != null) {
// Only show the push notification the first two time.
pushData = await encryptPushNotification(
receipt.contactId,
pushNotification,
);
}
}
if (message.type == pb.Message_Type.TEST_NOTIFICATION) {

View file

@ -63,9 +63,10 @@ class _UserListItem extends State<GroupListItem> {
}
Future<void> initStreams() async {
_lastMessageStream = twonlyDB.messagesDao
.watchLastMessage(widget.group.groupId)
.listen((update) {
_lastMessageStream =
(await twonlyDB.messagesDao.watchLastMessage(
widget.group.groupId,
)).listen((update) {
protectUpdateState.protect(() async {
await updateState(update, _messagesNotOpened);
});

View file

@ -107,7 +107,7 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
});
});
final msgStream = twonlyDB.messagesDao.watchByGroupId(widget.groupId);
final msgStream = await twonlyDB.messagesDao.watchByGroupId(widget.groupId);
messageSub = msgStream.listen((update) async {
allMessages = update;
await protectMessageUpdating.protect(() async {