Support for announcement-only groups
This commit is contained in:
parent
863ae9ed83
commit
56d5d283bd
43 changed files with 1057 additions and 455 deletions
|
@ -541,6 +541,16 @@ export class ConversationModel extends window.Backbone
|
|||
);
|
||||
}
|
||||
|
||||
if (
|
||||
this.get('announcementsOnly') &&
|
||||
!toRequest.get('capabilities')?.announcementGroup
|
||||
) {
|
||||
window.log.warn(
|
||||
`addPendingApprovalRequest/${idLog}: member needs to upgrade.`
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// We need the user's profileKeyCredential, which requires a roundtrip with the
|
||||
// server, and most definitely their profileKey. A getProfiles() call will
|
||||
// ensure that we have as much as we can get with the data we have.
|
||||
|
@ -585,6 +595,16 @@ export class ConversationModel extends window.Backbone
|
|||
);
|
||||
}
|
||||
|
||||
if (
|
||||
this.get('announcementsOnly') &&
|
||||
!toRequest.get('capabilities')?.announcementGroup
|
||||
) {
|
||||
window.log.warn(
|
||||
`addMember/${idLog}: ${conversationId} needs to upgrade.`
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// We need the user's profileKeyCredential, which requires a roundtrip with the
|
||||
// server, and most definitely their profileKey. A getProfiles() call will
|
||||
// ensure that we have as much as we can get with the data we have.
|
||||
|
@ -1436,6 +1456,8 @@ export class ConversationModel extends window.Backbone
|
|||
?.addFromInviteLink,
|
||||
accessControlAttributes: this.get('accessControl')?.attributes,
|
||||
accessControlMembers: this.get('accessControl')?.members,
|
||||
announcementsOnly: Boolean(this.get('announcementsOnly')),
|
||||
announcementsOnlyReady: this.canBeAnnouncementGroup(),
|
||||
expireTimer: this.get('expireTimer'),
|
||||
muteExpiresAt: this.get('muteExpiresAt')!,
|
||||
name: this.get('name')!,
|
||||
|
@ -1830,6 +1852,20 @@ export class ConversationModel extends window.Backbone
|
|||
}
|
||||
|
||||
async addMembersV2(conversationIds: ReadonlyArray<string>): Promise<void> {
|
||||
if (this.get('announcementsOnly')) {
|
||||
const isEveryMemberCapable = conversationIds.every(conversationId => {
|
||||
const model = window.ConversationController.get(conversationId);
|
||||
return Boolean(model?.get('capabilities')?.announcementGroup);
|
||||
});
|
||||
if (!isEveryMemberCapable) {
|
||||
const error = new Error(
|
||||
'addMembersV2: some or all members need to upgrade.'
|
||||
);
|
||||
error.code = 'E_NO_CAPABILITY';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
await this.modifyGroupV2({
|
||||
name: 'addMembersV2',
|
||||
createGroupChange: () =>
|
||||
|
@ -2975,6 +3011,17 @@ export class ConversationModel extends window.Backbone
|
|||
);
|
||||
}
|
||||
|
||||
canBeAnnouncementGroup(): boolean {
|
||||
if (!isGroupV2(this.attributes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const members = getConversationMembers(this.attributes);
|
||||
return members.every(conversationAttrs =>
|
||||
Boolean(conversationAttrs.capabilities?.announcementGroup)
|
||||
);
|
||||
}
|
||||
|
||||
getMemberIds(): Array<string> {
|
||||
const members = this.getMembers();
|
||||
return members.map(member => member.id);
|
||||
|
@ -4004,6 +4051,23 @@ export class ConversationModel extends window.Backbone
|
|||
});
|
||||
}
|
||||
|
||||
async updateAnnouncementsOnly(value: boolean): Promise<void> {
|
||||
if (!isGroupV2(this.attributes) || !this.canBeAnnouncementGroup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.modifyGroupV2({
|
||||
name: 'updateAnnouncementsOnly',
|
||||
createGroupChange: async () =>
|
||||
window.Signal.Groups.buildAnnouncementsOnlyChange(
|
||||
this.attributes,
|
||||
value
|
||||
),
|
||||
});
|
||||
|
||||
this.set({ announcementsOnly: value });
|
||||
}
|
||||
|
||||
async updateExpirationTimer(
|
||||
providedExpireTimer: number | undefined,
|
||||
providedSource?: unknown,
|
||||
|
@ -5150,6 +5214,12 @@ export class ConversationModel extends window.Backbone
|
|||
return;
|
||||
}
|
||||
|
||||
// Drop typing indicators for announcement only groups where the sender
|
||||
// is not an admin
|
||||
if (this.get('announcementsOnly') && !this.isAdmin(senderId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typingToken = `${senderId}.${senderDevice}`;
|
||||
|
||||
this.contactTypingTimers = this.contactTypingTimers || {};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue