diff --git a/package.json b/package.json index 76c854d0e..fdeffc5bc 100644 --- a/package.json +++ b/package.json @@ -189,7 +189,7 @@ "@electron/fuses": "1.5.0", "@formatjs/intl": "2.6.7", "@mixer/parallel-prettier": "2.0.3", - "@signalapp/mock-server": "2.18.0", + "@signalapp/mock-server": "2.20.0", "@storybook/addon-a11y": "6.5.6", "@storybook/addon-actions": "6.5.6", "@storybook/addon-controls": "6.5.6", diff --git a/ts/jobs/conversationJobQueue.ts b/ts/jobs/conversationJobQueue.ts index 861d0d2ce..5a3ee8f39 100644 --- a/ts/jobs/conversationJobQueue.ts +++ b/ts/jobs/conversationJobQueue.ts @@ -118,6 +118,8 @@ const normalMessageSendJobDataSchema = z.object({ messageId: z.string(), // Note: recipients are baked into the message itself revision: z.number().optional(), + // See sendEditedMessage + editedMessageTimestamp: z.number().optional(), }); export type NormalMessageSendJobData = z.infer< typeof normalMessageSendJobDataSchema diff --git a/ts/jobs/helpers/sendNormalMessage.ts b/ts/jobs/helpers/sendNormalMessage.ts index c5e0cc22c..18fd1f988 100644 --- a/ts/jobs/helpers/sendNormalMessage.ts +++ b/ts/jobs/helpers/sendNormalMessage.ts @@ -68,7 +68,7 @@ export async function sendNormalMessage( ): Promise { const { Message } = window.Signal.Types; - const { messageId, revision } = data; + const { messageId, revision, editedMessageTimestamp } = data; const message = await getMessageById(messageId); if (!message) { log.info( @@ -164,7 +164,6 @@ export async function sendNormalMessage( body, contact, deletedForEveryoneTimestamp, - editedMessageTimestamp, expireTimer, bodyRanges, messageTimestamp, @@ -489,7 +488,6 @@ async function getMessageSendData({ body: undefined | string; contact?: Array; deletedForEveryoneTimestamp: undefined | number; - editedMessageTimestamp: number | undefined; expireTimer: undefined | DurationInSeconds; bodyRanges: undefined | ReadonlyArray; messageTimestamp: number; @@ -571,8 +569,6 @@ async function getMessageSendData({ const storyReaction = message.get('storyReaction'); - const isEditedMessage = Boolean(message.get('editHistory')); - return { attachments: [ ...(maybeUploadedLongAttachment ? [maybeUploadedLongAttachment] : []), @@ -581,7 +577,6 @@ async function getMessageSendData({ body, contact, deletedForEveryoneTimestamp: message.get('deletedForEveryoneTimestamp'), - editedMessageTimestamp: isEditedMessage ? mainMessageTimestamp : undefined, expireTimer: message.get('expireTimer'), // TODO: we want filtration here if feature flag doesn't allow format/spoiler sends bodyRanges: message.get('bodyRanges'), diff --git a/ts/test-mock/messaging/edit_test.ts b/ts/test-mock/messaging/edit_test.ts index c76f02069..8375b0e41 100644 --- a/ts/test-mock/messaging/edit_test.ts +++ b/ts/test-mock/messaging/edit_test.ts @@ -212,4 +212,98 @@ describe('editing', function needsName() { ); } }); + + it('sends edited messages with correct timestamps', async () => { + const { contacts, desktop } = bootstrap; + + const window = await app.getWindow(); + + const [friend] = contacts; + + debug('incoming message'); + await friend.sendText(desktop, 'hello', { + timestamp: bootstrap.getTimestamp(), + }); + + debug('opening conversation'); + const leftPane = window.locator('.left-pane-wrapper'); + await leftPane + .locator('.module-conversation-list__item--contact-or-conversation') + .first() + .click(); + await window.locator('.module-conversation-hero').waitFor(); + + debug('checking for message'); + await window.locator('.module-message__text >> "hello"').waitFor(); + + debug('finding composition input and clicking it'); + { + const input = await app.waitForEnabledComposer(); + + debug('entering original message text'); + await input.type('edit message 1'); + await input.press('Enter'); + } + + debug('waiting for the original message from the app'); + const { dataMessage: originalMessage } = await friend.waitForMessage(); + assert.strictEqual(originalMessage.body, 'edit message 1'); + + const message = window.locator( + `.module-message[data-testid="${originalMessage.timestamp}"]` + ); + await message.waitFor(); + + debug('opening context menu'); + await message.locator('[aria-label="More actions"]').click(); + + debug('starting message edit'); + await window.locator('.module-message__context__edit-message').click(); + + { + const input = await app.waitForEnabledComposer(); + await input.press('Backspace'); + await input.type('2'); + await input.press('Enter'); + } + + const { editMessage: firstEdit } = await friend.waitForEditMessage(); + assert.strictEqual( + firstEdit.targetSentTimestamp?.toNumber(), + originalMessage.timestamp?.toNumber() + ); + assert.strictEqual(firstEdit.dataMessage?.body, 'edit message 2'); + + debug('opening context menu again'); + await message.locator('[aria-label="More actions"]').click(); + + debug('starting second message edit'); + await window.locator('.module-message__context__edit-message').click(); + + { + const input = await app.waitForEnabledComposer(); + await input.press('Backspace'); + await input.type('3'); + await input.press('Enter'); + } + + const { editMessage: secondEdit } = await friend.waitForEditMessage(); + assert.strictEqual( + secondEdit.targetSentTimestamp?.toNumber(), + firstEdit.dataMessage?.timestamp?.toNumber() + ); + assert.strictEqual(secondEdit.dataMessage?.body, 'edit message 3'); + + debug('opening edit history'); + await message.locator('.module-message__metadata__edited').click(); + + const history = await window.locator( + '.EditHistoryMessagesModal .module-message' + ); + assert.strictEqual(await history.count(), 3); + + assert.isTrue(await history.locator('"edit message 1"').isVisible()); + assert.isTrue(await history.locator('"edit message 2"').isVisible()); + assert.isTrue(await history.locator('"edit message 3"').isVisible()); + }); }); diff --git a/ts/util/canEditMessages.ts b/ts/util/canEditMessages.ts index 19a4276ed..756884f60 100644 --- a/ts/util/canEditMessages.ts +++ b/ts/util/canEditMessages.ts @@ -4,5 +4,7 @@ import { isEnabled } from '../RemoteConfig'; export function canEditMessages(): boolean { - return isEnabled('desktop.editMessageSend'); + return ( + isEnabled('desktop.internalUser') || isEnabled('desktop.editMessageSend') + ); } diff --git a/ts/util/sendEditedMessage.ts b/ts/util/sendEditedMessage.ts index cc3929bb7..9d705475b 100644 --- a/ts/util/sendEditedMessage.ts +++ b/ts/util/sendEditedMessage.ts @@ -212,6 +212,7 @@ export async function sendEditedMessage( conversationId, messageId: targetMessageId, revision: conversation.get('revision'), + editedMessageTimestamp: targetSentTimestamp, }, async jobToInsert => { log.info( diff --git a/yarn.lock b/yarn.lock index df26058f5..b74229310 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2264,7 +2264,7 @@ bindings "^1.5.0" tar "^6.1.0" -"@signalapp/libsignal-client@0.22.0", "@signalapp/libsignal-client@^0.22.0": +"@signalapp/libsignal-client@0.22.0": version "0.22.0" resolved "https://registry.yarnpkg.com/@signalapp/libsignal-client/-/libsignal-client-0.22.0.tgz#d57441612df46f90df68fc5d9ad45b857b9d2c44" integrity sha512-f1PJuxpcbmhvHxzbf0BvSJhNA3sqXrwnTf2GtfFB2CQoqTEiGCRYfyFZjwUBByiFFI5mTWKER6WGAw5AvG/3+A== @@ -2272,12 +2272,20 @@ node-gyp-build "^4.2.3" uuid "^8.3.0" -"@signalapp/mock-server@2.18.0": - version "2.18.0" - resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-2.18.0.tgz#fc0d14227c4807ebfb3b701963f1b0746cf6b31f" - integrity sha512-/zXdAlw32Fr/vR34w/Loni9UrYNmTKU4kifzJWbZppqYpV6rauFkiOmSmlTU6UDeRS+mNMZ1oY03BmMyi2d67g== +"@signalapp/libsignal-client@^0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@signalapp/libsignal-client/-/libsignal-client-0.24.0.tgz#4c52194071f1b0f7e0ad27a3f091c881d624897a" + integrity sha512-8IjvfD1wdkKcxwwM4KC1m8yWly5NJVAUaoiGMKiok9L+sD7HnY5DKpBXb/dpgkiSfSMdr3r4219+zFG1tq2UQQ== dependencies: - "@signalapp/libsignal-client" "^0.22.0" + node-gyp-build "^4.2.3" + uuid "^8.3.0" + +"@signalapp/mock-server@2.20.0": + version "2.20.0" + resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-2.20.0.tgz#073e0ef1a4c077d638440003a66be05feafb8bd3" + integrity sha512-RdwGZOlZLdsNfM3uzpaU/RkpCAhswF74NC96F7Sw1yOE05Ig/4Cpdx9M9gU6XE6ZWLhjPJ/Kll1GaKK+WPSwBw== + dependencies: + "@signalapp/libsignal-client" "^0.24.0" debug "^4.3.2" long "^4.0.0" micro "^9.3.4"