Do not confirm messages until we have handled them
This commit is contained in:
parent
29aa188c0f
commit
04f716986c
16 changed files with 990 additions and 960 deletions
|
@ -9,17 +9,14 @@ import type { SendStateByConversationId } from '../messages/MessageSendState';
|
|||
import * as Edits from '../messageModifiers/Edits';
|
||||
import * as log from '../logging/log';
|
||||
import * as Deletes from '../messageModifiers/Deletes';
|
||||
import {
|
||||
MessageReceipts,
|
||||
MessageReceiptType,
|
||||
} from '../messageModifiers/MessageReceipts';
|
||||
import { Reactions } from '../messageModifiers/Reactions';
|
||||
import * as MessageReceipts from '../messageModifiers/MessageReceipts';
|
||||
import * as Reactions from '../messageModifiers/Reactions';
|
||||
import * as ReadSyncs from '../messageModifiers/ReadSyncs';
|
||||
import * as ViewOnceOpenSyncs from '../messageModifiers/ViewOnceOpenSyncs';
|
||||
import * as ViewSyncs from '../messageModifiers/ViewSyncs';
|
||||
import { ReadStatus } from '../messages/MessageReadStatus';
|
||||
import { ReadSyncs } from '../messageModifiers/ReadSyncs';
|
||||
import { SeenStatus } from '../MessageSeenStatus';
|
||||
import { SendActionType, sendStateReducer } from '../messages/MessageSendState';
|
||||
import { ViewOnceOpenSyncs } from '../messageModifiers/ViewOnceOpenSyncs';
|
||||
import { ViewSyncs } from '../messageModifiers/ViewSyncs';
|
||||
import { canConversationBeUnarchived } from './canConversationBeUnarchived';
|
||||
import { deleteForEveryone } from './deleteForEveryone';
|
||||
import { handleEditMessage } from './handleEditMessage';
|
||||
|
@ -48,33 +45,31 @@ export async function modifyTargetMessage(
|
|||
const sourceServiceId = getSourceServiceId(message.attributes);
|
||||
|
||||
if (type === 'outgoing' || (type === 'story' && ourAci === sourceServiceId)) {
|
||||
const sendActions = MessageReceipts.getSingleton()
|
||||
.forMessage(message)
|
||||
.map(receipt => {
|
||||
let sendActionType: SendActionType;
|
||||
const receiptType = receipt.get('type');
|
||||
switch (receiptType) {
|
||||
case MessageReceiptType.Delivery:
|
||||
sendActionType = SendActionType.GotDeliveryReceipt;
|
||||
break;
|
||||
case MessageReceiptType.Read:
|
||||
sendActionType = SendActionType.GotReadReceipt;
|
||||
break;
|
||||
case MessageReceiptType.View:
|
||||
sendActionType = SendActionType.GotViewedReceipt;
|
||||
break;
|
||||
default:
|
||||
throw missingCaseError(receiptType);
|
||||
}
|
||||
const sendActions = MessageReceipts.forMessage(message).map(receipt => {
|
||||
let sendActionType: SendActionType;
|
||||
const receiptType = receipt.type;
|
||||
switch (receiptType) {
|
||||
case MessageReceipts.MessageReceiptType.Delivery:
|
||||
sendActionType = SendActionType.GotDeliveryReceipt;
|
||||
break;
|
||||
case MessageReceipts.MessageReceiptType.Read:
|
||||
sendActionType = SendActionType.GotReadReceipt;
|
||||
break;
|
||||
case MessageReceipts.MessageReceiptType.View:
|
||||
sendActionType = SendActionType.GotViewedReceipt;
|
||||
break;
|
||||
default:
|
||||
throw missingCaseError(receiptType);
|
||||
}
|
||||
|
||||
return {
|
||||
destinationConversationId: receipt.get('sourceConversationId'),
|
||||
action: {
|
||||
type: sendActionType,
|
||||
updatedAt: receipt.get('receiptTimestamp'),
|
||||
},
|
||||
};
|
||||
});
|
||||
return {
|
||||
destinationConversationId: receipt.sourceConversationId,
|
||||
action: {
|
||||
type: sendActionType,
|
||||
updatedAt: receipt.receiptTimestamp,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const oldSendStateByConversationId =
|
||||
message.get('sendStateByConversationId') || {};
|
||||
|
@ -111,10 +106,10 @@ export async function modifyTargetMessage(
|
|||
if (type === 'incoming') {
|
||||
// In a followup (see DESKTOP-2100), we want to make `ReadSyncs#forMessage` return
|
||||
// an array, not an object. This array wrapping makes that future a bit easier.
|
||||
const readSync = ReadSyncs.getSingleton().forMessage(message);
|
||||
const readSync = ReadSyncs.forMessage(message);
|
||||
const readSyncs = readSync ? [readSync] : [];
|
||||
|
||||
const viewSyncs = ViewSyncs.getSingleton().forMessage(message);
|
||||
const viewSyncs = ViewSyncs.forMessage(message);
|
||||
|
||||
const isGroupStoryReply =
|
||||
isGroup(conversation.attributes) && message.get('storyId');
|
||||
|
@ -122,8 +117,8 @@ export async function modifyTargetMessage(
|
|||
if (readSyncs.length !== 0 || viewSyncs.length !== 0) {
|
||||
const markReadAt = Math.min(
|
||||
Date.now(),
|
||||
...readSyncs.map(sync => sync.get('readAt')),
|
||||
...viewSyncs.map(sync => sync.get('viewedAt'))
|
||||
...readSyncs.map(sync => sync.readAt),
|
||||
...viewSyncs.map(sync => sync.viewedAt)
|
||||
);
|
||||
|
||||
if (message.get('expireTimer')) {
|
||||
|
@ -181,8 +176,7 @@ export async function modifyTargetMessage(
|
|||
|
||||
// Check for out-of-order view once open syncs
|
||||
if (isTapToView(message.attributes)) {
|
||||
const viewOnceOpenSync =
|
||||
ViewOnceOpenSyncs.getSingleton().forMessage(message);
|
||||
const viewOnceOpenSync = ViewOnceOpenSyncs.forMessage(message);
|
||||
if (viewOnceOpenSync) {
|
||||
await message.markViewOnceMessageViewed({ fromSync: true });
|
||||
changed = true;
|
||||
|
@ -191,7 +185,7 @@ export async function modifyTargetMessage(
|
|||
}
|
||||
|
||||
if (isStory(message.attributes)) {
|
||||
const viewSyncs = ViewSyncs.getSingleton().forMessage(message);
|
||||
const viewSyncs = ViewSyncs.forMessage(message);
|
||||
|
||||
if (viewSyncs.length !== 0) {
|
||||
message.set({
|
||||
|
@ -202,7 +196,7 @@ export async function modifyTargetMessage(
|
|||
|
||||
const markReadAt = Math.min(
|
||||
Date.now(),
|
||||
...viewSyncs.map(sync => sync.get('viewedAt'))
|
||||
...viewSyncs.map(sync => sync.viewedAt)
|
||||
);
|
||||
message.setPendingMarkRead(
|
||||
Math.min(message.getPendingMarkRead() ?? Date.now(), markReadAt)
|
||||
|
@ -220,12 +214,12 @@ export async function modifyTargetMessage(
|
|||
}
|
||||
|
||||
// Does message message have any pending, previously-received associated reactions?
|
||||
const reactions = Reactions.getSingleton().forMessage(message);
|
||||
const reactions = Reactions.forMessage(message);
|
||||
await Promise.all(
|
||||
reactions.map(async reaction => {
|
||||
if (isStory(message.attributes)) {
|
||||
// We don't set changed = true here, because we don't modify the original story
|
||||
const generatedMessage = reaction.get('storyReactionMessage');
|
||||
const generatedMessage = reaction.storyReactionMessage;
|
||||
strictAssert(
|
||||
generatedMessage,
|
||||
'Story reactions must provide storyReactionMessage'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue