fix: edge case with sending msg before, then getting one sent earlier

pull/3022/head
Audric Ackermann 1 year ago
parent 33ddf51ba6
commit 6e952398c9

@ -1144,9 +1144,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
}; };
// if the message is trying to be added unread, make sure that it shouldn't be already read from our other devices // if the message is trying to be added unread, make sure that it shouldn't be already read from our other devices
markAttributesAsReadIfNeeded(toBeAddedAttributes); markAttributesAsReadIfNeeded(toBeAddedAttributes);
return this.addSingleMessage(toBeAddedAttributes); return this.addSingleMessage(toBeAddedAttributes);
} }

@ -117,6 +117,7 @@ export function markAttributesAsReadIfNeeded(messageAttributes: MessageAttribute
latestUnreadForThisConvo?.lastRead && latestUnreadForThisConvo?.lastRead &&
sentAt <= latestUnreadForThisConvo.lastRead sentAt <= latestUnreadForThisConvo.lastRead
) { ) {
// That message was sent before our last read timestamp for that conversation.
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
messageAttributes.unread = READ_MESSAGE_STATE.read; messageAttributes.unread = READ_MESSAGE_STATE.read;
} }

@ -12,6 +12,7 @@ import { ExpiringDetails, expireMessagesOnSnode } from '../apis/snode_api/expire
import { GetNetworkTime } from '../apis/snode_api/getNetworkTime'; import { GetNetworkTime } from '../apis/snode_api/getNetworkTime';
import { getConversationController } from '../conversations'; import { getConversationController } from '../conversations';
import { isValidUnixTimestamp } from '../utils/Timestamps'; import { isValidUnixTimestamp } from '../utils/Timestamps';
import { UpdateMsgExpirySwarm } from '../utils/job_runners/jobs/UpdateMsgExpirySwarmJob';
import { import {
checkIsLegacyDisappearingDataMessage, checkIsLegacyDisappearingDataMessage,
couldBeLegacyDisappearingMessageContent, couldBeLegacyDisappearingMessageContent,
@ -543,18 +544,40 @@ function getMessageReadyToDisappear(
messageExpirationFromRetrieve && messageExpirationFromRetrieve &&
messageExpirationFromRetrieve > 0 messageExpirationFromRetrieve > 0
) { ) {
const expirationStartTimestamp = messageExpirationFromRetrieve - expireTimer * 1000; /**
const expires_at = messageExpirationFromRetrieve; * Edge case: when we send a message before we poll for a message sent earlier, our convo volatile update will
// TODO a message might be added even when it expired, but the period cleaning of expired message will pick it up and remove it soon enough * mark that incoming message as read right away (because it was sent earlier than our latest convolatile lastRead).
window.log.debug( * To take care of this case, we need to check if the expiration of an incoming DaR, alreadt marked as read message looks to not have been updated yet.
`incoming DaR message already read by another device, forcing readAt ${(Date.now() - * The way we do it, is by checking that the swarm expiration is before (now + expireTimer).
expirationStartTimestamp) / * If it looks like this expiration was not updated yet, we need to trigger a UpdateExpiryJob for that message.
1000}s ago, so with ${(expires_at - Date.now()) / 1000}s left` */
); const now = GetNetworkTime.getNowWithNetworkOffset();
messageModel.set({ const expirationNowPlusTimer = now + expireTimer * 1000;
expirationStartTimestamp, const msgExpirationWasAlreadyUpdated = messageExpirationFromRetrieve <= expirationNowPlusTimer;
expires_at, // Note: a message might be added even when it expired, but the periodic cleaning of expired message will pick it up and remove it soon enough
});
if (msgExpirationWasAlreadyUpdated) {
const expirationStartTimestamp = messageExpirationFromRetrieve - expireTimer * 1000;
window.log.debug(
`incoming DaR message already read by another device, forcing readAt ${(Date.now() -
expirationStartTimestamp) /
1000}s ago, so with ${(messageExpirationFromRetrieve - Date.now()) / 1000}s left`
);
messageModel.set({
expirationStartTimestamp,
expires_at: messageExpirationFromRetrieve,
});
} else {
window.log.debug(
`incoming DaR message already read by another device but swarmExpiration seems NOT updated, forcing readAt NOW and triggering UpdateExpiryJob with ${expireTimer}s left`
);
messageModel.set({
expirationStartTimestamp: now,
expires_at: expirationNowPlusTimer,
});
// Ideally we would batch call those UpdateExpiry, but we can't currently and disappear v2 is already too complex as it is.
void UpdateMsgExpirySwarm.queueNewJobIfNeeded([messageModel.id]);
}
} else if ( } else if (
expirationType === 'deleteAfterSend' && expirationType === 'deleteAfterSend' &&
expireTimer > 0 && expireTimer > 0 &&

Loading…
Cancel
Save