Unify shared group computation logic

This commit is contained in:
Fedor Indutny 2025-06-03 15:43:26 -07:00 committed by GitHub
commit c2ff41b520
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 33 deletions

View file

@ -189,7 +189,6 @@ import { getTypingIndicatorSetting } from '../types/Util';
import { INITIAL_EXPIRE_TIMER_VERSION } from '../util/expirationTimer'; import { INITIAL_EXPIRE_TIMER_VERSION } from '../util/expirationTimer';
import { maybeNotify } from '../messages/maybeNotify'; import { maybeNotify } from '../messages/maybeNotify';
/* eslint-disable more/no-then */
window.Whisper = window.Whisper || {}; window.Whisper = window.Whisper || {};
const { Message } = window.Signal.Types; const { Message } = window.Signal.Types;
@ -3241,12 +3240,9 @@ export class ConversationModel extends window.Backbone
} }
if (isDirectConversation(this.attributes) && serviceId) { if (isDirectConversation(this.attributes) && serviceId) {
const groups = const groups = await this.#getSharedGroups();
await window.ConversationController.getAllGroupsInvolvingServiceId( groups?.forEach(group => {
serviceId drop(group.addKeyChange('addKeyChange - group fan-out', serviceId));
);
groups.forEach(group => {
void group.addKeyChange('addKeyChange - group fan-out', serviceId);
}); });
} }
@ -3372,12 +3368,9 @@ export class ConversationModel extends window.Backbone
const serviceId = this.getServiceId(); const serviceId = this.getServiceId();
if (isDirectConversation(this.attributes) && serviceId) { if (isDirectConversation(this.attributes) && serviceId) {
void window.ConversationController.getAllGroupsInvolvingServiceId( const groups = await this.#getSharedGroups();
serviceId groups?.forEach(group => {
).then(groups => { drop(group.addVerifiedChange(this.id, verified, options));
groups.forEach(group => {
void group.addVerifiedChange(this.id, verified, options);
});
}); });
} }
} }
@ -3409,12 +3402,9 @@ export class ConversationModel extends window.Backbone
if (isDirectConversation(this.attributes) && serviceId) { if (isDirectConversation(this.attributes) && serviceId) {
this.set({ profileLastUpdatedAt: Date.now() }); this.set({ profileLastUpdatedAt: Date.now() });
void window.ConversationController.getAllGroupsInvolvingServiceId( const groups = await this.#getSharedGroups();
serviceId groups?.forEach(group => {
).then(groups => { drop(group.addProfileChange(profileChange, this.id));
groups.forEach(group => {
void group.addProfileChange(profileChange, this.id);
});
}); });
} }
} }
@ -3597,12 +3587,7 @@ export class ConversationModel extends window.Backbone
`notification for ${sourceServiceId} from ${oldValue} to ${newValue}` `notification for ${sourceServiceId} from ${oldValue} to ${newValue}`
); );
const convos = [ const convos = [this, ...((await this.#getSharedGroups()) ?? [])];
this,
...(await window.ConversationController.getAllGroupsInvolvingServiceId(
sourceServiceId
)),
];
await Promise.all( await Promise.all(
convos.map(convo => { convos.map(convo => {
@ -4859,32 +4844,40 @@ export class ConversationModel extends window.Backbone
} }
} }
// This is an expensive operation we use to populate the message request hero row. It async #getSharedGroups(): Promise<Array<ConversationModel> | undefined> {
// shows groups the current user has in common with this potential new contact.
async updateSharedGroups(): Promise<void> {
if (!isDirectConversation(this.attributes)) { if (!isDirectConversation(this.attributes)) {
return; return undefined;
} }
if (isMe(this.attributes)) { if (isMe(this.attributes)) {
return; return undefined;
} }
const ourAci = window.textsecure.storage.user.getCheckedAci(); const ourAci = window.textsecure.storage.user.getCheckedAci();
const theirAci = this.getAci(); const theirAci = this.getAci();
if (!theirAci) { if (!theirAci) {
return; return undefined;
} }
const ourGroups = const ourGroups =
await window.ConversationController.getAllGroupsInvolvingServiceId( await window.ConversationController.getAllGroupsInvolvingServiceId(
ourAci ourAci
); );
const sharedGroups = ourGroups return ourGroups
.filter(c => c.hasMember(ourAci) && c.hasMember(theirAci)) .filter(c => c.hasMember(ourAci) && c.hasMember(theirAci))
.sort( .sort(
(left, right) => (left, right) =>
(right.get('timestamp') || 0) - (left.get('timestamp') || 0) (right.get('timestamp') || 0) - (left.get('timestamp') || 0)
); );
}
// This is an expensive operation we use to populate the message request hero row. It
// shows groups the current user has in common with this potential new contact.
async updateSharedGroups(): Promise<void> {
const sharedGroups = await this.#getSharedGroups();
if (sharedGroups == null) {
return;
}
const sharedGroupNames = sharedGroups.map(conversation => const sharedGroupNames = sharedGroups.map(conversation =>
conversation.getTitle() conversation.getTitle()

View file

@ -95,13 +95,17 @@ describe('KeyChangeListener', () => {
let groupConvo: ConversationModel; let groupConvo: ConversationModel;
beforeEach(async () => { beforeEach(async () => {
await window.ConversationController.getOrCreateAndWait(
ourServiceId,
'private'
);
groupConvo = await window.ConversationController.getOrCreateAndWait( groupConvo = await window.ConversationController.getOrCreateAndWait(
Bytes.toBinary( Bytes.toBinary(
new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5]) new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5])
), ),
'group', 'group',
{ {
members: [ourServiceIdWithKeyChange], members: [ourServiceIdWithKeyChange, ourServiceId],
} }
); );
}); });