Update call-only conversation message request UI
This commit is contained in:
parent
ac8bec1ac0
commit
bd0e08d6fd
5 changed files with 93 additions and 53 deletions
|
@ -2260,16 +2260,6 @@ export class ConversationModel extends window.Backbone
|
||||||
return undefined;
|
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 } = {}):
|
incrementSentMessageCount({ dry = false }: { dry?: boolean } = {}):
|
||||||
| Partial<ConversationAttributesType>
|
| Partial<ConversationAttributesType>
|
||||||
| undefined {
|
| undefined {
|
||||||
|
@ -2287,20 +2277,6 @@ export class ConversationModel extends window.Backbone
|
||||||
return undefined;
|
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
|
* This function is called when a message request is accepted in order to
|
||||||
* handle sending read receipts and download any pending attachments.
|
* 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);
|
this.trigger('newmessage', model);
|
||||||
|
|
||||||
void this.updateUnread();
|
void this.updateUnread();
|
||||||
this.set('active_at', timestamp);
|
this.set('active_at', timestamp);
|
||||||
|
|
||||||
|
|
|
@ -53,17 +53,9 @@ class ExpiringMessagesDeletionService {
|
||||||
sentAt: message.get('sent_at'),
|
sentAt: message.get('sent_at'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const conversation = message.getConversation();
|
|
||||||
|
|
||||||
// We do this to update the UI, if this message is being displayed somewhere
|
// We do this to update the UI, if this message is being displayed somewhere
|
||||||
message.trigger('expired');
|
message.trigger('expired');
|
||||||
window.reduxActions.conversations.messageExpired(message.id);
|
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) {
|
if (messages.length > 0) {
|
||||||
|
|
|
@ -111,11 +111,7 @@ import {
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
import { viewSyncJobQueue } from '../../jobs/viewSyncJobQueue';
|
import { viewSyncJobQueue } from '../../jobs/viewSyncJobQueue';
|
||||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||||
import {
|
import { isIncoming, processBodyRanges } from '../selectors/message';
|
||||||
isIncoming,
|
|
||||||
isOutgoing,
|
|
||||||
processBodyRanges,
|
|
||||||
} from '../selectors/message';
|
|
||||||
import { getActiveCallState } from '../selectors/calling';
|
import { getActiveCallState } from '../selectors/calling';
|
||||||
import { sendDeleteForEveryoneMessage } from '../../util/sendDeleteForEveryoneMessage';
|
import { sendDeleteForEveryoneMessage } from '../../util/sendDeleteForEveryoneMessage';
|
||||||
import type { ShowToastActionType } from './toast';
|
import type { ShowToastActionType } from './toast';
|
||||||
|
@ -1638,9 +1634,6 @@ function deleteMessages({
|
||||||
throw new Error('deleteMessage: No conversation found');
|
throw new Error('deleteMessage: No conversation found');
|
||||||
}
|
}
|
||||||
|
|
||||||
let outgoingDeleted = 0;
|
|
||||||
let incomingDeleted = 0;
|
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
messageIds.map(async messageId => {
|
messageIds.map(async messageId => {
|
||||||
const message = await getMessageById(messageId);
|
const message = await getMessageById(messageId);
|
||||||
|
@ -1654,12 +1647,6 @@ function deleteMessages({
|
||||||
`deleteMessages: message conversation ${messageConversationId} doesn't match provided conversation ${conversationId}`
|
`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);
|
await window.Signal.Data.removeMessages(messageIds);
|
||||||
|
|
||||||
if (outgoingDeleted > 0) {
|
|
||||||
conversation.decrementSentMessageCount(outgoingDeleted);
|
|
||||||
}
|
|
||||||
if (incomingDeleted > 0) {
|
|
||||||
conversation.decrementMessageCount(incomingDeleted);
|
|
||||||
}
|
|
||||||
popPanelForConversation()(dispatch, getState, undefined);
|
popPanelForConversation()(dispatch, getState, undefined);
|
||||||
|
|
||||||
if (nearbyMessageId != null) {
|
if (nearbyMessageId != null) {
|
||||||
|
|
|
@ -94,7 +94,6 @@ const mapStateToProps = (
|
||||||
|
|
||||||
const maxGroupSize = getGroupSizeHardLimit(1001);
|
const maxGroupSize = getGroupSizeHardLimit(1001);
|
||||||
const maxRecommendedGroupSize = getGroupSizeRecommendedLimit(151);
|
const maxRecommendedGroupSize = getGroupSizeRecommendedLimit(151);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...props,
|
...props,
|
||||||
areWeASubscriber: getAreWeASubscriber(state),
|
areWeASubscriber: getAreWeASubscriber(state),
|
||||||
|
|
82
ts/test-mock/messaging/unknown_contact_test.ts
Normal file
82
ts/test-mock/messaging/unknown_contact_test.ts
Normal file
|
@ -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
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue