From 3c91dce99368522d2b576d40c2f64ffee5988d69 Mon Sep 17 00:00:00 2001 From: Evan Hahn <69474926+EvanHahn-Signal@users.noreply.github.com> Date: Tue, 5 Oct 2021 16:11:40 -0500 Subject: [PATCH] Don't show group call start notifications more than once --- ts/models/conversations.ts | 25 +++++++++++++++++-------- ts/services/calling.ts | 37 +++++++++++++++++++------------------ ts/state/ducks/calling.ts | 19 +------------------ 3 files changed, 37 insertions(+), 44 deletions(-) diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts index 4be92ac20e4..7b7508da14b 100644 --- a/ts/models/conversations.ts +++ b/ts/models/conversations.ts @@ -2722,10 +2722,16 @@ export class ConversationModel extends window.Backbone this.trigger('newmessage', model); } + /** + * Adds a group call history message if one is needed. It won't add history messages for + * the same group call era ID. + * + * Resolves with `true` if a new message was added, and `false` otherwise. + */ async updateCallHistoryForGroupCall( eraId: string, creatorUuid: string - ): Promise { + ): Promise { // We want to update the cache quickly in case this function is called multiple times. const oldCachedEraId = this.cachedLatestGroupCallEraId; this.cachedLatestGroupCallEraId = eraId; @@ -2734,14 +2740,17 @@ export class ConversationModel extends window.Backbone (oldCachedEraId && oldCachedEraId === eraId) || (await window.Signal.Data.hasGroupCallHistoryMessage(this.id, eraId)); - if (!alreadyHasMessage) { - this.addCallHistory({ - callMode: CallMode.Group, - creatorUuid, - eraId, - startedTime: Date.now(), - }); + if (alreadyHasMessage) { + return false; } + + await this.addCallHistory({ + callMode: CallMode.Group, + creatorUuid, + eraId, + startedTime: Date.now(), + }); + return true; } async addProfileChange( diff --git a/ts/services/calling.ts b/ts/services/calling.ts index ddd1bfc874d..f686d644158 100644 --- a/ts/services/calling.ts +++ b/ts/services/calling.ts @@ -2007,10 +2007,10 @@ export class CallingClass { }); } - public updateCallHistoryForGroupCall( + public async updateCallHistoryForGroupCall( conversationId: string, peekInfo: undefined | PeekInfo - ): void { + ): Promise { // If we don't have the necessary pieces to peek, bail. (It's okay if we don't.) if (!peekInfo || !peekInfo.eraId || !peekInfo.creator) { return; @@ -2020,6 +2020,7 @@ export class CallingClass { log.error('updateCallHistoryForGroupCall(): bad creator UUID'); return; } + const creatorConversation = window.ConversationController.get(creatorUuid); const conversation = window.ConversationController.get(conversationId); if (!conversation) { @@ -2027,24 +2028,24 @@ export class CallingClass { return; } - conversation.updateCallHistoryForGroupCall(peekInfo.eraId, creatorUuid); - } - - public notifyForGroupCall( - conversationId: string, - creatorBytes: undefined | Readonly - ): void { - const conversation = window.ConversationController.get(conversationId); - if (conversation?.isMuted()) { - return; - } + const isNewCall = await conversation.updateCallHistoryForGroupCall( + peekInfo.eraId, + creatorUuid + ); + const wasStartedByMe = Boolean( + creatorConversation && isMe(creatorConversation.attributes) + ); + const isAnybodyElseInGroupCall = Boolean(peekInfo.joinedMembers.length); - const creatorUuid = creatorBytes ? bytesToUuid(creatorBytes) : undefined; - const creatorConversation = window.ConversationController.get(creatorUuid); - if (creatorConversation && isMe(creatorConversation.attributes)) { - return; + if (isNewCall && !wasStartedByMe && isAnybodyElseInGroupCall) { + this.notifyForGroupCall(conversation, creatorConversation); } + } + private notifyForGroupCall( + conversation: Readonly, + creatorConversation: undefined | Readonly + ): void { let notificationTitle: string; let notificationMessage: string; @@ -2074,7 +2075,7 @@ export class CallingClass { message: notificationMessage, onNotificationClick: () => { this.uxActions?.startCallingLobby({ - conversationId, + conversationId: conversation.id, isVideoCall: true, }); }, diff --git a/ts/state/ducks/calling.ts b/ts/state/ducks/calling.ts index 6f2974b0b47..b220139ae22 100644 --- a/ts/state/ducks/calling.ts +++ b/ts/state/ducks/calling.ts @@ -859,7 +859,6 @@ function peekNotConnectedGroupCall( queue.add(async () => { const state = getState(); - const { ourUuid } = state.user; // We make sure we're not trying to peek at a connected (or connecting, or // reconnecting) call. Because this is asynchronous, it's possible that the call @@ -893,7 +892,7 @@ function peekNotConnectedGroupCall( return; } - calling.updateCallHistoryForGroupCall(conversationId, peekInfo); + await calling.updateCallHistoryForGroupCall(conversationId, peekInfo); const formattedPeekInfo = calling.formatGroupCallPeekInfoForRedux( peekInfo @@ -907,22 +906,6 @@ function peekNotConnectedGroupCall( ourConversationId: state.user.ourConversationId, }, }); - - // We want to show "Alice started a group call" only if a call isn't ringing or - // active. We wait a moment to make sure that we don't accidentally show a ring - // notification followed swiftly by a less urgent notification. - if (!isAnybodyElseInGroupCall(formattedPeekInfo, ourUuid)) { - return; - } - await sleep(1000); - const newCallingState = getState().calling; - if ( - getActiveCall(newCallingState)?.conversationId === conversationId || - getIncomingCall(newCallingState.callsByConversation, ourUuid) - ) { - return; - } - calling.notifyForGroupCall(conversationId, peekInfo.creator); }); }; }