From bd0e08d6fdb00d62ebeaeeab4adac2ea28e44258 Mon Sep 17 00:00:00 2001 From: trevor-signal <131492920+trevor-signal@users.noreply.github.com> Date: Fri, 12 May 2023 14:20:10 -0400 Subject: [PATCH] Update call-only conversation message request UI --- ts/models/conversations.ts | 34 +++----- ts/services/expiringMessagesDeletion.ts | 8 -- ts/state/ducks/conversations.ts | 21 +---- ts/state/smart/ConversationDetails.tsx | 1 - .../messaging/unknown_contact_test.ts | 82 +++++++++++++++++++ 5 files changed, 93 insertions(+), 53 deletions(-) create mode 100644 ts/test-mock/messaging/unknown_contact_test.ts diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts index e59f6c60dfeb..9f50781dea63 100644 --- a/ts/models/conversations.ts +++ b/ts/models/conversations.ts @@ -2260,16 +2260,6 @@ export class ConversationModel extends window.Backbone return undefined; } - decrementMessageCount(numberOfMessages = 1): void { - this.set({ - messageCount: Math.max( - (this.get('messageCount') || 0) - numberOfMessages, - 0 - ), - }); - window.Signal.Data.updateConversation(this.attributes); - } - incrementSentMessageCount({ dry = false }: { dry?: boolean } = {}): | Partial | undefined { @@ -2287,20 +2277,6 @@ export class ConversationModel extends window.Backbone return undefined; } - decrementSentMessageCount(numberOfMessages = 1): void { - this.set({ - messageCount: Math.max( - (this.get('messageCount') || 0) - numberOfMessages, - 0 - ), - sentMessageCount: Math.max( - (this.get('sentMessageCount') || 0) - numberOfMessages, - 0 - ), - }); - window.Signal.Data.updateConversation(this.attributes); - } - /** * This function is called when a message request is accepted in order to * handle sending read receipts and download any pending attachments. @@ -3464,7 +3440,17 @@ export class ConversationModel extends window.Backbone }) ); + if ( + detailsToSave.callMode === CallMode.Direct && + !detailsToSave.wasIncoming + ) { + this.incrementSentMessageCount(); + } else { + this.incrementMessageCount(); + } + this.trigger('newmessage', model); + void this.updateUnread(); this.set('active_at', timestamp); diff --git a/ts/services/expiringMessagesDeletion.ts b/ts/services/expiringMessagesDeletion.ts index 20d369199d18..ceee06d72a79 100644 --- a/ts/services/expiringMessagesDeletion.ts +++ b/ts/services/expiringMessagesDeletion.ts @@ -53,17 +53,9 @@ class ExpiringMessagesDeletionService { sentAt: message.get('sent_at'), }); - const conversation = message.getConversation(); - // We do this to update the UI, if this message is being displayed somewhere message.trigger('expired'); window.reduxActions.conversations.messageExpired(message.id); - - if (conversation) { - // An expired message only counts as decrementing the message count, not - // the sent message count - conversation.decrementMessageCount(); - } }); if (messages.length > 0) { diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index a0a6567e935e..02ad0893d2d1 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -111,11 +111,7 @@ import { import { missingCaseError } from '../../util/missingCaseError'; import { viewSyncJobQueue } from '../../jobs/viewSyncJobQueue'; import { ReadStatus } from '../../messages/MessageReadStatus'; -import { - isIncoming, - isOutgoing, - processBodyRanges, -} from '../selectors/message'; +import { isIncoming, processBodyRanges } from '../selectors/message'; import { getActiveCallState } from '../selectors/calling'; import { sendDeleteForEveryoneMessage } from '../../util/sendDeleteForEveryoneMessage'; import type { ShowToastActionType } from './toast'; @@ -1638,9 +1634,6 @@ function deleteMessages({ throw new Error('deleteMessage: No conversation found'); } - let outgoingDeleted = 0; - let incomingDeleted = 0; - await Promise.all( messageIds.map(async messageId => { const message = await getMessageById(messageId); @@ -1654,12 +1647,6 @@ function deleteMessages({ `deleteMessages: message conversation ${messageConversationId} doesn't match provided conversation ${conversationId}` ); } - - if (isOutgoing(message.attributes)) { - outgoingDeleted += 1; - } else { - incomingDeleted += 1; - } }) ); @@ -1682,12 +1669,6 @@ function deleteMessages({ await window.Signal.Data.removeMessages(messageIds); - if (outgoingDeleted > 0) { - conversation.decrementSentMessageCount(outgoingDeleted); - } - if (incomingDeleted > 0) { - conversation.decrementMessageCount(incomingDeleted); - } popPanelForConversation()(dispatch, getState, undefined); if (nearbyMessageId != null) { diff --git a/ts/state/smart/ConversationDetails.tsx b/ts/state/smart/ConversationDetails.tsx index 6402465a25fc..12a4209828cc 100644 --- a/ts/state/smart/ConversationDetails.tsx +++ b/ts/state/smart/ConversationDetails.tsx @@ -94,7 +94,6 @@ const mapStateToProps = ( const maxGroupSize = getGroupSizeHardLimit(1001); const maxRecommendedGroupSize = getGroupSizeRecommendedLimit(151); - return { ...props, areWeASubscriber: getAreWeASubscriber(state), diff --git a/ts/test-mock/messaging/unknown_contact_test.ts b/ts/test-mock/messaging/unknown_contact_test.ts new file mode 100644 index 000000000000..a2c9d6168c25 --- /dev/null +++ b/ts/test-mock/messaging/unknown_contact_test.ts @@ -0,0 +1,82 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { PrimaryDevice } from '@signalapp/mock-server'; +import createDebug from 'debug'; +import Long from 'long'; +import type { Page } from 'playwright'; +import assert from 'assert'; +import * as durations from '../../util/durations'; +import type { App } from '../playwright'; +import { Bootstrap } from '../bootstrap'; + +export const debug = createDebug('mock:test:edit'); + +describe('unknown contacts', function unknownContacts() { + this.timeout(durations.MINUTE); + + let bootstrap: Bootstrap; + let app: App; + let page: Page; + let unknownContact: PrimaryDevice; + + beforeEach(async () => { + bootstrap = new Bootstrap(); + await bootstrap.init(); + app = await bootstrap.link(); + page = await app.getWindow(); + + const { server, desktop } = bootstrap; + unknownContact = await server.createPrimaryDevice({ + profileName: 'Hugh Ameye', + }); + + const ourKey = await desktop.popSingleUseKey(); + await unknownContact.addSingleUseKey(desktop, ourKey); + }); + + afterEach(async function after() { + if (!bootstrap) { + return; + } + + if (this.currentTest?.state !== 'passed') { + await bootstrap.saveLogs(app); + } + + await app.close(); + await bootstrap.teardown(); + }); + + it('blocks incoming calls from unknown contacts & shows message request', async () => { + const { desktop } = bootstrap; + + debug('sending calling offer message'); + await unknownContact.sendRaw(desktop, { + callingMessage: { + offer: { + callId: new Long(Math.floor(Math.random() * 1e10)), + }, + }, + }); + + debug('opening conversation'); + const leftPane = page.locator('.left-pane-wrapper'); + + const conversationListItem = leftPane.getByRole('button', { + name: 'Chat with Unknown contact', + }); + await conversationListItem.getByText('Message Request').click(); + + const conversationStack = page.locator('.conversation-stack'); + await conversationStack.getByText('Missed voice call').waitFor(); + + debug('accepting message request'); + await page.getByText('message you and share your name').waitFor(); + await page.getByRole('button', { name: 'Accept' }).click(); + assert.strictEqual( + await page.getByText('message you and share your name').count(), + 0 + ); + }); +});