On send, pull data from target edit if sending edit
This commit is contained in:
parent
146b562c91
commit
48245eeea6
12 changed files with 529 additions and 135 deletions
|
@ -39,7 +39,6 @@ import type {
|
|||
} from '../textsecure/Types.d';
|
||||
import { SendMessageProtoError } from '../textsecure/Errors';
|
||||
import { getUserLanguages } from '../util/userLanguages';
|
||||
import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp';
|
||||
import { copyCdnFields } from '../util/attachments';
|
||||
|
||||
import type { ReactionType } from '../types/Reactions';
|
||||
|
@ -156,6 +155,11 @@ import { getSenderIdentifier } from '../util/getSenderIdentifier';
|
|||
import { getNotificationDataForMessage } from '../util/getNotificationDataForMessage';
|
||||
import { getNotificationTextForMessage } from '../util/getNotificationTextForMessage';
|
||||
import { getMessageAuthorText } from '../util/getMessageAuthorText';
|
||||
import {
|
||||
getPropForTimestamp,
|
||||
setPropForTimestamp,
|
||||
hasEditBeenSent,
|
||||
} from '../util/editHelpers';
|
||||
|
||||
/* eslint-disable more/no-then */
|
||||
|
||||
|
@ -831,18 +835,40 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
* Change any Pending send state to Failed. Note that this will not mark successful
|
||||
* sends failed.
|
||||
*/
|
||||
public markFailed(): void {
|
||||
public markFailed(editMessageTimestamp?: number): void {
|
||||
const now = Date.now();
|
||||
this.set(
|
||||
'sendStateByConversationId',
|
||||
mapValues(this.get('sendStateByConversationId') || {}, sendState =>
|
||||
|
||||
const targetTimestamp = editMessageTimestamp || this.get('timestamp');
|
||||
const sendStateByConversationId = getPropForTimestamp({
|
||||
log,
|
||||
message: this,
|
||||
prop: 'sendStateByConversationId',
|
||||
targetTimestamp,
|
||||
});
|
||||
|
||||
const newSendStateByConversationId = mapValues(
|
||||
sendStateByConversationId || {},
|
||||
sendState =>
|
||||
sendStateReducer(sendState, {
|
||||
type: SendActionType.Failed,
|
||||
updatedAt: now,
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
setPropForTimestamp({
|
||||
log,
|
||||
message: this,
|
||||
prop: 'sendStateByConversationId',
|
||||
targetTimestamp,
|
||||
value: newSendStateByConversationId,
|
||||
});
|
||||
|
||||
// We aren't trying to send this message anymore, so we'll delete these caches
|
||||
delete this.cachedOutgoingContactData;
|
||||
delete this.cachedOutgoingPreviewData;
|
||||
delete this.cachedOutgoingQuoteData;
|
||||
delete this.cachedOutgoingStickerData;
|
||||
|
||||
this.notifyStorySendFailed();
|
||||
}
|
||||
|
||||
|
@ -886,10 +912,15 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
return errors[0][0];
|
||||
}
|
||||
|
||||
async send(
|
||||
promise: Promise<CallbackResultType | void | null>,
|
||||
saveErrors?: (errors: Array<Error>) => void
|
||||
): Promise<void> {
|
||||
async send({
|
||||
promise,
|
||||
saveErrors,
|
||||
targetTimestamp,
|
||||
}: {
|
||||
promise: Promise<CallbackResultType | void | null>;
|
||||
saveErrors?: (errors: Array<Error>) => void;
|
||||
targetTimestamp: number;
|
||||
}): Promise<void> {
|
||||
const updateLeftPane =
|
||||
this.getConversation()?.debouncedUpdateLastMessage ?? noop;
|
||||
|
||||
|
@ -926,7 +957,12 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
}
|
||||
|
||||
const sendStateByConversationId = {
|
||||
...(this.get('sendStateByConversationId') || {}),
|
||||
...(getPropForTimestamp({
|
||||
log,
|
||||
message: this,
|
||||
prop: 'sendStateByConversationId',
|
||||
targetTimestamp,
|
||||
}) || {}),
|
||||
};
|
||||
|
||||
const sendIsNotFinal =
|
||||
|
@ -970,9 +1006,13 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
});
|
||||
|
||||
// Integrate sends via sealed sender
|
||||
const latestEditTimestamp = this.get('editMessageTimestamp');
|
||||
const sendIsLatest =
|
||||
!latestEditTimestamp || targetTimestamp === latestEditTimestamp;
|
||||
const previousUnidentifiedDeliveries =
|
||||
this.get('unidentifiedDeliveries') || [];
|
||||
const newUnidentifiedDeliveries =
|
||||
sendIsLatest &&
|
||||
sendIsFinal &&
|
||||
'unidentifiedDeliveries' in result.value &&
|
||||
Array.isArray(result.value.unidentifiedDeliveries)
|
||||
|
@ -1051,7 +1091,6 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
}
|
||||
});
|
||||
|
||||
attributesToUpdate.sendStateByConversationId = sendStateByConversationId;
|
||||
// Only update the expirationStartTimestamp if we don't already have one set
|
||||
if (!this.get('expirationStartTimestamp')) {
|
||||
attributesToUpdate.expirationStartTimestamp = sentToAtLeastOneRecipient
|
||||
|
@ -1073,6 +1112,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
void this.saveErrors(errorsToSave, { skipSave: true });
|
||||
}
|
||||
|
||||
setPropForTimestamp({
|
||||
log,
|
||||
message: this,
|
||||
prop: 'sendStateByConversationId',
|
||||
targetTimestamp,
|
||||
value: sendStateByConversationId,
|
||||
});
|
||||
|
||||
if (!this.doNotSave) {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
|
@ -1082,13 +1129,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
updateLeftPane();
|
||||
|
||||
if (sentToAtLeastOneRecipient && !this.doNotSendSyncMessage) {
|
||||
promises.push(this.sendSyncMessage());
|
||||
promises.push(this.sendSyncMessage(targetTimestamp));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const isTotalSuccess: boolean =
|
||||
result.success && !this.get('errors')?.length;
|
||||
|
||||
if (isTotalSuccess) {
|
||||
delete this.cachedOutgoingContactData;
|
||||
delete this.cachedOutgoingPreviewData;
|
||||
|
@ -1099,10 +1147,15 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
updateLeftPane();
|
||||
}
|
||||
|
||||
async sendSyncMessageOnly(
|
||||
dataMessage: Uint8Array,
|
||||
saveErrors?: (errors: Array<Error>) => void
|
||||
): Promise<CallbackResultType | void> {
|
||||
async sendSyncMessageOnly({
|
||||
targetTimestamp,
|
||||
dataMessage,
|
||||
saveErrors,
|
||||
}: {
|
||||
targetTimestamp: number;
|
||||
dataMessage: Uint8Array;
|
||||
saveErrors?: (errors: Array<Error>) => void;
|
||||
}): Promise<CallbackResultType | void> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const conv = this.getConversation()!;
|
||||
this.set({ dataMessage });
|
||||
|
@ -1115,7 +1168,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
expirationStartTimestamp: Date.now(),
|
||||
errors: [],
|
||||
});
|
||||
const result = await this.sendSyncMessage();
|
||||
const result = await this.sendSyncMessage(targetTimestamp);
|
||||
this.set({
|
||||
// We have to do this afterward, since we didn't have a previous send!
|
||||
unidentifiedDeliveries:
|
||||
|
@ -1147,7 +1200,9 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
}
|
||||
}
|
||||
|
||||
async sendSyncMessage(): Promise<CallbackResultType | void> {
|
||||
async sendSyncMessage(
|
||||
targetTimestamp: number
|
||||
): Promise<CallbackResultType | void> {
|
||||
const ourConversation =
|
||||
window.ConversationController.getOurConversationOrThrow();
|
||||
const sendOptions = await getSendOptions(ourConversation.attributes, {
|
||||
|
@ -1173,8 +1228,8 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
if (!dataMessage) {
|
||||
return;
|
||||
}
|
||||
const isEditedMessage = Boolean(this.get('editHistory'));
|
||||
const isUpdate = Boolean(this.get('synced')) && !isEditedMessage;
|
||||
const wasEditSent = hasEditBeenSent(this);
|
||||
const isUpdate = Boolean(this.get('synced')) && !wasEditSent;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const conv = this.getConversation()!;
|
||||
|
||||
|
@ -1206,9 +1261,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
map(conversationsWithSealedSender, c => c.id)
|
||||
);
|
||||
|
||||
const timestamp = getMessageSentTimestamp(this.attributes, { log });
|
||||
|
||||
const encodedContent = isEditedMessage
|
||||
const encodedContent = wasEditSent
|
||||
? {
|
||||
encodedEditMessage: dataMessage,
|
||||
}
|
||||
|
@ -1219,7 +1272,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
return handleMessageSend(
|
||||
messaging.sendSyncMessage({
|
||||
...encodedContent,
|
||||
timestamp,
|
||||
timestamp: targetTimestamp,
|
||||
destination: conv.get('e164'),
|
||||
destinationServiceId: conv.getServiceId(),
|
||||
expirationStartTimestamp:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue