Assume everyone is GV2-capable

This commit is contained in:
Evan Hahn 2022-03-04 13:48:44 -06:00 committed by GitHub
parent 0a52318be6
commit effe5aae6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 16 additions and 405 deletions

View file

@ -2393,20 +2393,6 @@
} }
} }
}, },
"chooseGroupMembers__cant-add-member__title": {
"message": "Cant add member",
"description": "Shown in the alert when you try to add someone who can't be added to a group"
},
"chooseGroupMembers__cant-add-member__body": {
"message": "\"$name$\" cant be added to the group because theyre using an old version of Signal. You can add them to the group after theyve updated Signal.",
"description": "Shown in the alert when you try to add someone who can't be added to a group",
"placeholders": {
"max": {
"content": "$1",
"example": "Jane Doe"
}
}
},
"setGroupMetadata__title": { "setGroupMetadata__title": {
"message": "Name this group", "message": "Name this group",
"description": "The title for the 'set group metadata' left pane screen" "description": "The title for the 'set group metadata' left pane screen"

View file

@ -1,4 +1,4 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import React from 'react'; import React from 'react';
@ -22,14 +22,6 @@ const defaultProps = {
onClose: action('onClose'), onClose: action('onClose'),
}; };
story.add("Can't add a contact", () => (
<AddGroupMemberErrorDialog
{...defaultProps}
mode={AddGroupMemberErrorDialogMode.CantAddContact}
contact={{ title: 'Foo Bar' }}
/>
));
story.add('Maximum group size', () => ( story.add('Maximum group size', () => (
<AddGroupMemberErrorDialog <AddGroupMemberErrorDialog
{...defaultProps} {...defaultProps}

View file

@ -1,4 +1,4 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { FunctionComponent, ReactNode } from 'react'; import type { FunctionComponent, ReactNode } from 'react';
@ -6,21 +6,14 @@ import React from 'react';
import type { LocalizerType } from '../types/Util'; import type { LocalizerType } from '../types/Util';
import { Alert } from './Alert'; import { Alert } from './Alert';
import { Intl } from './Intl';
import { ContactName } from './conversation/ContactName';
import { missingCaseError } from '../util/missingCaseError'; import { missingCaseError } from '../util/missingCaseError';
export enum AddGroupMemberErrorDialogMode { export enum AddGroupMemberErrorDialogMode {
CantAddContact,
MaximumGroupSize, MaximumGroupSize,
RecommendedMaximumGroupSize, RecommendedMaximumGroupSize,
} }
type PropsDataType = type PropsDataType =
| {
mode: AddGroupMemberErrorDialogMode.CantAddContact;
contact: { title: string };
}
| { | {
mode: AddGroupMemberErrorDialogMode.MaximumGroupSize; mode: AddGroupMemberErrorDialogMode.MaximumGroupSize;
maximumNumberOfContacts: number; maximumNumberOfContacts: number;
@ -42,18 +35,6 @@ export const AddGroupMemberErrorDialog: FunctionComponent<PropsType> =
let title: string; let title: string;
let body: ReactNode; let body: ReactNode;
switch (props.mode) { switch (props.mode) {
case AddGroupMemberErrorDialogMode.CantAddContact: {
const { contact } = props;
title = i18n('chooseGroupMembers__cant-add-member__title');
body = (
<Intl
i18n={i18n}
id="chooseGroupMembers__cant-add-member__body"
components={[<ContactName key="name" title={contact.title} />]}
/>
);
break;
}
case AddGroupMemberErrorDialogMode.MaximumGroupSize: { case AddGroupMemberErrorDialogMode.MaximumGroupSize: {
const { maximumNumberOfContacts } = props; const { maximumNumberOfContacts } = props;
title = i18n('chooseGroupMembers__maximum-group-size__title'); title = i18n('chooseGroupMembers__maximum-group-size__title');

View file

@ -1,4 +1,4 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import React, { useContext } from 'react'; import React, { useContext } from 'react';
@ -195,12 +195,6 @@ story.add('Contact checkboxes: disabled', () => (
isChecked: false, isChecked: false,
disabledReason: ContactCheckboxDisabledReason.MaximumContactsSelected, disabledReason: ContactCheckboxDisabledReason.MaximumContactsSelected,
}, },
{
type: RowType.ContactCheckbox,
contact: defaultConversations[1],
isChecked: false,
disabledReason: ContactCheckboxDisabledReason.NotCapable,
},
{ {
type: RowType.ContactCheckbox, type: RowType.ContactCheckbox,
contact: defaultConversations[2], contact: defaultConversations[2],

View file

@ -90,11 +90,9 @@ const defaultModeSpecificProps = {
const emptySearchResultsGroup = { isLoading: false, results: [] }; const emptySearchResultsGroup = { isLoading: false, results: [] };
const useProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({ const useProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
cantAddContactToGroup: action('cantAddContactToGroup'),
clearConversationSearch: action('clearConversationSearch'), clearConversationSearch: action('clearConversationSearch'),
clearGroupCreationError: action('clearGroupCreationError'), clearGroupCreationError: action('clearGroupCreationError'),
clearSearch: action('clearSearch'), clearSearch: action('clearSearch'),
closeCantAddContactToGroupModal: action('closeCantAddContactToGroupModal'),
closeMaximumGroupSizeModal: action('closeMaximumGroupSizeModal'), closeMaximumGroupSizeModal: action('closeMaximumGroupSizeModal'),
closeRecommendedGroupSizeModal: action('closeRecommendedGroupSizeModal'), closeRecommendedGroupSizeModal: action('closeRecommendedGroupSizeModal'),
composeDeleteAvatarFromDisk: action('composeDeleteAvatarFromDisk'), composeDeleteAvatarFromDisk: action('composeDeleteAvatarFromDisk'),

View file

@ -95,11 +95,9 @@ export type PropsType = {
theme: ThemeType; theme: ThemeType;
// Action Creators // Action Creators
cantAddContactToGroup: (conversationId: string) => void;
clearConversationSearch: () => void; clearConversationSearch: () => void;
clearGroupCreationError: () => void; clearGroupCreationError: () => void;
clearSearch: () => void; clearSearch: () => void;
closeCantAddContactToGroupModal: () => void;
closeMaximumGroupSizeModal: () => void; closeMaximumGroupSizeModal: () => void;
closeRecommendedGroupSizeModal: () => void; closeRecommendedGroupSizeModal: () => void;
createGroup: () => void; createGroup: () => void;
@ -149,13 +147,11 @@ export type PropsType = {
}; };
export const LeftPane: React.FC<PropsType> = ({ export const LeftPane: React.FC<PropsType> = ({
cantAddContactToGroup,
challengeStatus, challengeStatus,
crashReportCount, crashReportCount,
clearConversationSearch, clearConversationSearch,
clearGroupCreationError, clearGroupCreationError,
clearSearch, clearSearch,
closeCantAddContactToGroupModal,
closeMaximumGroupSizeModal, closeMaximumGroupSizeModal,
closeRecommendedGroupSizeModal, closeRecommendedGroupSizeModal,
composeDeleteAvatarFromDisk, composeDeleteAvatarFromDisk,
@ -466,7 +462,6 @@ export const LeftPane: React.FC<PropsType> = ({
clearConversationSearch, clearConversationSearch,
clearGroupCreationError, clearGroupCreationError,
clearSearch, clearSearch,
closeCantAddContactToGroupModal,
closeMaximumGroupSizeModal, closeMaximumGroupSizeModal,
closeRecommendedGroupSizeModal, closeRecommendedGroupSizeModal,
composeDeleteAvatarFromDisk, composeDeleteAvatarFromDisk,
@ -607,9 +602,6 @@ export const LeftPane: React.FC<PropsType> = ({
case ContactCheckboxDisabledReason.MaximumContactsSelected: case ContactCheckboxDisabledReason.MaximumContactsSelected:
// These are no-ops. // These are no-ops.
break; break;
case ContactCheckboxDisabledReason.NotCapable:
cantAddContactToGroup(conversationId);
break;
default: default:
throw missingCaseError(disabledReason); throw missingCaseError(disabledReason);
} }

View file

@ -1,4 +1,4 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { FunctionComponent } from 'react'; import type { FunctionComponent } from 'react';
@ -46,7 +46,6 @@ enum Stage {
} }
type StateType = { type StateType = {
cantAddContactForModal: undefined | ConversationType;
maximumGroupSizeModalState: OneTimeModalState; maximumGroupSizeModalState: OneTimeModalState;
recommendedGroupSizeModalState: OneTimeModalState; recommendedGroupSizeModalState: OneTimeModalState;
searchTerm: string; searchTerm: string;
@ -60,7 +59,6 @@ enum ActionType {
ConfirmAdds, ConfirmAdds,
RemoveSelectedContact, RemoveSelectedContact,
ReturnToContactChooser, ReturnToContactChooser,
SetCantAddContactForModal,
ToggleSelectedContact, ToggleSelectedContact,
UpdateSearchTerm, UpdateSearchTerm,
} }
@ -71,10 +69,6 @@ type Action =
| { type: ActionType.ConfirmAdds } | { type: ActionType.ConfirmAdds }
| { type: ActionType.ReturnToContactChooser } | { type: ActionType.ReturnToContactChooser }
| { type: ActionType.RemoveSelectedContact; conversationId: string } | { type: ActionType.RemoveSelectedContact; conversationId: string }
| {
type: ActionType.SetCantAddContactForModal;
contact: undefined | ConversationType;
}
| { | {
type: ActionType.ToggleSelectedContact; type: ActionType.ToggleSelectedContact;
conversationId: string; conversationId: string;
@ -118,11 +112,6 @@ function reducer(
action.conversationId action.conversationId
), ),
}; };
case ActionType.SetCantAddContactForModal:
return {
...state,
cantAddContactForModal: action.contact,
};
case ActionType.ToggleSelectedContact: case ActionType.ToggleSelectedContact:
return { return {
...state, ...state,
@ -167,7 +156,6 @@ export const AddGroupMembersModal: FunctionComponent<PropsType> = ({
const [ const [
{ {
cantAddContactForModal,
maximumGroupSizeModalState, maximumGroupSizeModalState,
recommendedGroupSizeModalState, recommendedGroupSizeModalState,
searchTerm, searchTerm,
@ -176,7 +164,6 @@ export const AddGroupMembersModal: FunctionComponent<PropsType> = ({
}, },
dispatch, dispatch,
] = useReducer(reducer, { ] = useReducer(reducer, {
cantAddContactForModal: undefined,
maximumGroupSizeModalState: isGroupAlreadyFull maximumGroupSizeModalState: isGroupAlreadyFull
? OneTimeModalState.Showing ? OneTimeModalState.Showing
: OneTimeModalState.NeverShown, : OneTimeModalState.NeverShown,
@ -198,22 +185,6 @@ export const AddGroupMembersModal: FunctionComponent<PropsType> = ({
selectedConversationIds selectedConversationIds
); );
if (cantAddContactForModal) {
return (
<AddGroupMemberErrorDialog
contact={cantAddContactForModal}
i18n={i18n}
mode={AddGroupMemberErrorDialogMode.CantAddContact}
onClose={() => {
dispatch({
type: ActionType.SetCantAddContactForModal,
contact: undefined,
});
}}
/>
);
}
if (maximumGroupSizeModalState === OneTimeModalState.Showing) { if (maximumGroupSizeModalState === OneTimeModalState.Showing) {
return ( return (
<AddGroupMemberErrorDialog <AddGroupMemberErrorDialog
@ -254,14 +225,6 @@ export const AddGroupMembersModal: FunctionComponent<PropsType> = ({
conversationId, conversationId,
}); });
}; };
const setCantAddContactForModal = (
contact: undefined | Readonly<ConversationType>
) => {
dispatch({
type: ActionType.SetCantAddContactForModal,
contact,
});
};
const setSearchTerm = (term: string) => { const setSearchTerm = (term: string) => {
dispatch({ dispatch({
type: ActionType.UpdateSearchTerm, type: ActionType.UpdateSearchTerm,
@ -280,7 +243,6 @@ export const AddGroupMembersModal: FunctionComponent<PropsType> = ({
<ChooseGroupMembersModal <ChooseGroupMembersModal
candidateContacts={candidateContacts} candidateContacts={candidateContacts}
confirmAdds={confirmAdds} confirmAdds={confirmAdds}
contactLookup={contactLookup}
conversationIdsAlreadyInGroup={conversationIdsAlreadyInGroup} conversationIdsAlreadyInGroup={conversationIdsAlreadyInGroup}
getPreferredBadge={getPreferredBadge} getPreferredBadge={getPreferredBadge}
i18n={i18n} i18n={i18n}
@ -289,7 +251,6 @@ export const AddGroupMembersModal: FunctionComponent<PropsType> = ({
removeSelectedContact={removeSelectedContact} removeSelectedContact={removeSelectedContact}
searchTerm={searchTerm} searchTerm={searchTerm}
selectedContacts={selectedContacts} selectedContacts={selectedContacts}
setCantAddContactForModal={setCantAddContactForModal}
setSearchTerm={setSearchTerm} setSearchTerm={setSearchTerm}
theme={theme} theme={theme}
toggleSelectedContact={toggleSelectedContact} toggleSelectedContact={toggleSelectedContact}

View file

@ -8,7 +8,6 @@ import Measure from 'react-measure';
import type { LocalizerType, ThemeType } from '../../../../types/Util'; import type { LocalizerType, ThemeType } from '../../../../types/Util';
import { assert } from '../../../../util/assert'; import { assert } from '../../../../util/assert';
import { getOwn } from '../../../../util/getOwn';
import { refMerger } from '../../../../util/refMerger'; import { refMerger } from '../../../../util/refMerger';
import { useRestoreFocus } from '../../../../hooks/useRestoreFocus'; import { useRestoreFocus } from '../../../../hooks/useRestoreFocus';
import { missingCaseError } from '../../../../util/missingCaseError'; import { missingCaseError } from '../../../../util/missingCaseError';
@ -27,7 +26,6 @@ import { SearchInput } from '../../../SearchInput';
type PropsType = { type PropsType = {
candidateContacts: ReadonlyArray<ConversationType>; candidateContacts: ReadonlyArray<ConversationType>;
confirmAdds: () => void; confirmAdds: () => void;
contactLookup: Record<string, ConversationType>;
conversationIdsAlreadyInGroup: Set<string>; conversationIdsAlreadyInGroup: Set<string>;
getPreferredBadge: PreferredBadgeSelectorType; getPreferredBadge: PreferredBadgeSelectorType;
i18n: LocalizerType; i18n: LocalizerType;
@ -36,9 +34,6 @@ type PropsType = {
removeSelectedContact: (_: string) => void; removeSelectedContact: (_: string) => void;
searchTerm: string; searchTerm: string;
selectedContacts: ReadonlyArray<ConversationType>; selectedContacts: ReadonlyArray<ConversationType>;
setCantAddContactForModal: (
_: Readonly<undefined | ConversationType>
) => void;
setSearchTerm: (_: string) => void; setSearchTerm: (_: string) => void;
theme: ThemeType; theme: ThemeType;
toggleSelectedContact: (conversationId: string) => void; toggleSelectedContact: (conversationId: string) => void;
@ -48,7 +43,6 @@ type PropsType = {
export const ChooseGroupMembersModal: FunctionComponent<PropsType> = ({ export const ChooseGroupMembersModal: FunctionComponent<PropsType> = ({
candidateContacts, candidateContacts,
confirmAdds, confirmAdds,
contactLookup,
conversationIdsAlreadyInGroup, conversationIdsAlreadyInGroup,
getPreferredBadge, getPreferredBadge,
i18n, i18n,
@ -57,7 +51,6 @@ export const ChooseGroupMembersModal: FunctionComponent<PropsType> = ({
removeSelectedContact, removeSelectedContact,
searchTerm, searchTerm,
selectedContacts, selectedContacts,
setCantAddContactForModal,
setSearchTerm, setSearchTerm,
theme, theme,
toggleSelectedContact, toggleSelectedContact,
@ -111,8 +104,6 @@ export const ChooseGroupMembersModal: FunctionComponent<PropsType> = ({
disabledReason = ContactCheckboxDisabledReason.AlreadyAdded; disabledReason = ContactCheckboxDisabledReason.AlreadyAdded;
} else if (hasSelectedMaximumNumberOfContacts && !isSelected) { } else if (hasSelectedMaximumNumberOfContacts && !isSelected) {
disabledReason = ContactCheckboxDisabledReason.MaximumContactsSelected; disabledReason = ContactCheckboxDisabledReason.MaximumContactsSelected;
} else if (!contact.isGroupV2Capable) {
disabledReason = ContactCheckboxDisabledReason.NotCapable;
} }
return { return {
@ -212,15 +203,6 @@ export const ChooseGroupMembersModal: FunctionComponent<PropsType> = ({
case ContactCheckboxDisabledReason.MaximumContactsSelected: case ContactCheckboxDisabledReason.MaximumContactsSelected:
// These are no-ops. // These are no-ops.
break; break;
case ContactCheckboxDisabledReason.NotCapable: {
const contact = getOwn(contactLookup, conversationId);
assert(
contact,
'Contact was not in lookup; not showing modal'
);
setCantAddContactForModal(contact);
break;
}
default: default:
throw missingCaseError(disabledReason); throw missingCaseError(disabledReason);
} }

View file

@ -1,4 +1,4 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { FunctionComponent, ReactNode } from 'react'; import type { FunctionComponent, ReactNode } from 'react';
@ -18,7 +18,6 @@ export enum ContactCheckboxDisabledReason {
// We start the enum at 1 because the default starting value of 0 is falsy. // We start the enum at 1 because the default starting value of 0 is falsy.
AlreadyAdded = 1, AlreadyAdded = 1,
MaximumContactsSelected, MaximumContactsSelected,
NotCapable,
} }
export type PropsDataType = { export type PropsDataType = {

View file

@ -25,7 +25,6 @@ import {
export type LeftPaneChooseGroupMembersPropsType = { export type LeftPaneChooseGroupMembersPropsType = {
candidateContacts: ReadonlyArray<ConversationType>; candidateContacts: ReadonlyArray<ConversationType>;
cantAddContactForModal: undefined | ConversationType;
isShowingRecommendedGroupSizeModal: boolean; isShowingRecommendedGroupSizeModal: boolean;
isShowingMaximumGroupSizeModal: boolean; isShowingMaximumGroupSizeModal: boolean;
searchTerm: string; searchTerm: string;
@ -35,10 +34,6 @@ export type LeftPaneChooseGroupMembersPropsType = {
export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneChooseGroupMembersPropsType> { export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneChooseGroupMembersPropsType> {
private readonly candidateContacts: ReadonlyArray<ConversationType>; private readonly candidateContacts: ReadonlyArray<ConversationType>;
private readonly cantAddContactForModal:
| undefined
| Readonly<{ title: string }>;
private readonly isShowingMaximumGroupSizeModal: boolean; private readonly isShowingMaximumGroupSizeModal: boolean;
private readonly isShowingRecommendedGroupSizeModal: boolean; private readonly isShowingRecommendedGroupSizeModal: boolean;
@ -51,7 +46,6 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
constructor({ constructor({
candidateContacts, candidateContacts,
cantAddContactForModal,
isShowingMaximumGroupSizeModal, isShowingMaximumGroupSizeModal,
isShowingRecommendedGroupSizeModal, isShowingRecommendedGroupSizeModal,
searchTerm, searchTerm,
@ -60,7 +54,6 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
super(); super();
this.candidateContacts = candidateContacts; this.candidateContacts = candidateContacts;
this.cantAddContactForModal = cantAddContactForModal;
this.isShowingMaximumGroupSizeModal = isShowingMaximumGroupSizeModal; this.isShowingMaximumGroupSizeModal = isShowingMaximumGroupSizeModal;
this.isShowingRecommendedGroupSizeModal = this.isShowingRecommendedGroupSizeModal =
isShowingRecommendedGroupSizeModal; isShowingRecommendedGroupSizeModal;
@ -127,13 +120,11 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
} }
override getPreRowsNode({ override getPreRowsNode({
closeCantAddContactToGroupModal,
closeMaximumGroupSizeModal, closeMaximumGroupSizeModal,
closeRecommendedGroupSizeModal, closeRecommendedGroupSizeModal,
i18n, i18n,
removeSelectedContact, removeSelectedContact,
}: Readonly<{ }: Readonly<{
closeCantAddContactToGroupModal: () => unknown;
closeMaximumGroupSizeModal: () => unknown; closeMaximumGroupSizeModal: () => unknown;
closeRecommendedGroupSizeModal: () => unknown; closeRecommendedGroupSizeModal: () => unknown;
i18n: LocalizerType; i18n: LocalizerType;
@ -158,15 +149,6 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
onClose={closeRecommendedGroupSizeModal} onClose={closeRecommendedGroupSizeModal}
/> />
); );
} else if (this.cantAddContactForModal) {
modalNode = (
<AddGroupMemberErrorDialog
i18n={i18n}
contact={this.cantAddContactForModal}
mode={AddGroupMemberErrorDialogMode.CantAddContact}
onClose={closeCantAddContactToGroupModal}
/>
);
} }
return ( return (
@ -254,15 +236,10 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
} }
const isChecked = this.selectedConversationIdsSet.has(contact.id); const isChecked = this.selectedConversationIdsSet.has(contact.id);
const disabledReason =
let disabledReason: undefined | ContactCheckboxDisabledReason; !isChecked && this.hasSelectedMaximumNumberOfContacts()
if (!isChecked) { ? ContactCheckboxDisabledReason.MaximumContactsSelected
if (this.hasSelectedMaximumNumberOfContacts()) { : undefined;
disabledReason = ContactCheckboxDisabledReason.MaximumContactsSelected;
} else if (!contact.isGroupV2Capable) {
disabledReason = ContactCheckboxDisabledReason.NotCapable;
}
}
return { return {
type: RowType.ContactCheckbox, type: RowType.ContactCheckbox,

View file

@ -62,7 +62,6 @@ export abstract class LeftPaneHelper<T> {
clearConversationSearch: () => unknown; clearConversationSearch: () => unknown;
clearGroupCreationError: () => void; clearGroupCreationError: () => void;
clearSearch: () => unknown; clearSearch: () => unknown;
closeCantAddContactToGroupModal: () => unknown;
closeMaximumGroupSizeModal: () => unknown; closeMaximumGroupSizeModal: () => unknown;
closeRecommendedGroupSizeModal: () => unknown; closeRecommendedGroupSizeModal: () => unknown;
composeDeleteAvatarFromDisk: DeleteAvatarFromDiskActionType; composeDeleteAvatarFromDisk: DeleteAvatarFromDiskActionType;

View file

@ -638,22 +638,10 @@ export async function buildAddMembersChange(
} }
// Refresh our local data to be sure // Refresh our local data to be sure
if ( if (!contact.get('profileKey') || !contact.get('profileKeyCredential')) {
!contact.get('capabilities')?.gv2 ||
!contact.get('profileKey') ||
!contact.get('profileKeyCredential')
) {
await contact.getProfiles(); await contact.getProfiles();
} }
if (!contact.get('capabilities')?.gv2) {
assert(
false,
`buildAddMembersChange/${logId}: member is missing GV2 capability; skipping`
);
return;
}
const profileKey = contact.get('profileKey'); const profileKey = contact.get('profileKey');
const profileKeyCredential = contact.get('profileKeyCredential'); const profileKeyCredential = contact.get('profileKeyCredential');
@ -1511,22 +1499,10 @@ export async function createGroupV2({
} }
// Refresh our local data to be sure // Refresh our local data to be sure
if ( if (!contact.get('profileKey') || !contact.get('profileKeyCredential')) {
!contact.get('capabilities')?.gv2 ||
!contact.get('profileKey') ||
!contact.get('profileKeyCredential')
) {
await contact.getProfiles(); await contact.getProfiles();
} }
if (!contact.get('capabilities')?.gv2) {
assert(
false,
`createGroupV2/${logId}: member is missing GV2 capability; skipping`
);
return;
}
if (contact.get('profileKey') && contact.get('profileKeyCredential')) { if (contact.get('profileKey') && contact.get('profileKeyCredential')) {
membersV2.push({ membersV2.push({
uuid: contactUuid, uuid: contactUuid,
@ -1836,22 +1812,14 @@ export async function getGroupMigrationMembers(
// Refresh our local data to be sure // Refresh our local data to be sure
if ( if (
!capabilities || !capabilities?.['gv1-migration'] ||
!capabilities.gv2 ||
!capabilities['gv1-migration'] ||
!contact.get('profileKeyCredential') !contact.get('profileKeyCredential')
) { ) {
await contact.getProfiles(); await contact.getProfiles();
} }
capabilities = contact.get('capabilities'); capabilities = contact.get('capabilities');
if (!capabilities || !capabilities.gv2) { if (!capabilities?.['gv1-migration']) {
log.warn(
`getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv2 capability, skipping.`
);
return null;
}
if (!capabilities || !capabilities['gv1-migration']) {
log.warn( log.warn(
`getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv1-migration capability, skipping.` `getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv1-migration capability, skipping.`
); );
@ -1916,14 +1884,7 @@ export async function getGroupMigrationMembers(
} }
const capabilities = contact.get('capabilities'); const capabilities = contact.get('capabilities');
if (!capabilities || !capabilities.gv2) { if (!capabilities?.['gv1-migration']) {
log.warn(
`getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv2 capability, skipping.`
);
droppedGV2MemberIds.push(conversationId);
return null;
}
if (!capabilities || !capabilities['gv1-migration']) {
log.warn( log.warn(
`getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv1-migration capability, skipping.` `getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv1-migration capability, skipping.`
); );

View file

@ -1815,9 +1815,6 @@ export class ConversationModel extends window.Backbone
isBlocked: this.isBlocked(), isBlocked: this.isBlocked(),
isMe: isMe(this.attributes), isMe: isMe(this.attributes),
isGroupV1AndDisabled: this.isGroupV1AndDisabled(), isGroupV1AndDisabled: this.isGroupV1AndDisabled(),
isGroupV2Capable: isDirectConversation(this.attributes)
? Boolean(this.get('capabilities')?.gv2)
: undefined,
isPinned: this.get('isPinned'), isPinned: this.get('isPinned'),
isUntrusted: this.isUntrusted(), isUntrusted: this.isUntrusted(),
isVerified: this.isVerified(), isVerified: this.isVerified(),

View file

@ -133,7 +133,6 @@ export type ConversationType = {
isArchived?: boolean; isArchived?: boolean;
isBlocked?: boolean; isBlocked?: boolean;
isGroupV1AndDisabled?: boolean; isGroupV1AndDisabled?: boolean;
isGroupV2Capable?: boolean;
isPinned?: boolean; isPinned?: boolean;
isUntrusted?: boolean; isUntrusted?: boolean;
isVerified?: boolean; isVerified?: boolean;
@ -298,7 +297,6 @@ type ComposerStateType =
| ({ | ({
step: ComposerStep.ChooseGroupMembers; step: ComposerStep.ChooseGroupMembers;
searchTerm: string; searchTerm: string;
cantAddContactIdForModal: undefined | string;
} & ComposerGroupCreationState) } & ComposerGroupCreationState)
| ({ | ({
step: ComposerStep.SetGroupMetadata; step: ComposerStep.SetGroupMetadata;
@ -402,12 +400,6 @@ export type CancelVerificationDataByConversationActionType = {
canceledAt: number; canceledAt: number;
}; };
}; };
type CantAddContactToGroupActionType = {
type: 'CANT_ADD_CONTACT_TO_GROUP';
payload: {
conversationId: string;
};
};
type ClearGroupCreationErrorActionType = { type: 'CLEAR_GROUP_CREATION_ERROR' }; type ClearGroupCreationErrorActionType = { type: 'CLEAR_GROUP_CREATION_ERROR' };
type ClearInvitedUuidsForNewlyCreatedGroupActionType = { type ClearInvitedUuidsForNewlyCreatedGroupActionType = {
type: 'CLEAR_INVITED_UUIDS_FOR_NEWLY_CREATED_GROUP'; type: 'CLEAR_INVITED_UUIDS_FOR_NEWLY_CREATED_GROUP';
@ -421,9 +413,6 @@ type ClearCancelledVerificationActionType = {
conversationId: string; conversationId: string;
}; };
}; };
type CloseCantAddContactToGroupModalActionType = {
type: 'CLOSE_CANT_ADD_CONTACT_TO_GROUP_MODAL';
};
type CloseContactSpoofingReviewActionType = { type CloseContactSpoofingReviewActionType = {
type: 'CLOSE_CONTACT_SPOOFING_REVIEW'; type: 'CLOSE_CONTACT_SPOOFING_REVIEW';
}; };
@ -736,14 +725,12 @@ type ReplaceAvatarsActionType = {
}; };
export type ConversationActionType = export type ConversationActionType =
| CancelVerificationDataByConversationActionType | CancelVerificationDataByConversationActionType
| CantAddContactToGroupActionType
| ClearCancelledVerificationActionType | ClearCancelledVerificationActionType
| ClearVerificationDataByConversationActionType | ClearVerificationDataByConversationActionType
| ClearGroupCreationErrorActionType | ClearGroupCreationErrorActionType
| ClearInvitedUuidsForNewlyCreatedGroupActionType | ClearInvitedUuidsForNewlyCreatedGroupActionType
| ClearSelectedMessageActionType | ClearSelectedMessageActionType
| ClearUnreadMetricsActionType | ClearUnreadMetricsActionType
| CloseCantAddContactToGroupModalActionType
| CloseContactSpoofingReviewActionType | CloseContactSpoofingReviewActionType
| CloseMaximumGroupSizeModalActionType | CloseMaximumGroupSizeModalActionType
| CloseRecommendedGroupSizeModalActionType | CloseRecommendedGroupSizeModalActionType
@ -801,14 +788,12 @@ export type ConversationActionType =
export const actions = { export const actions = {
cancelConversationVerification, cancelConversationVerification,
cantAddContactToGroup,
clearCancelledConversationVerification, clearCancelledConversationVerification,
clearGroupCreationError, clearGroupCreationError,
clearInvitedUuidsForNewlyCreatedGroup, clearInvitedUuidsForNewlyCreatedGroup,
clearSelectedMessage, clearSelectedMessage,
clearUnreadMetrics, clearUnreadMetrics,
clearUsernameSave, clearUsernameSave,
closeCantAddContactToGroupModal,
closeContactSpoofingReview, closeContactSpoofingReview,
closeMaximumGroupSizeModal, closeMaximumGroupSizeModal,
closeRecommendedGroupSizeModal, closeRecommendedGroupSizeModal,
@ -1379,14 +1364,6 @@ function composeReplaceAvatar(
}; };
} }
function cantAddContactToGroup(
conversationId: string
): CantAddContactToGroupActionType {
return {
type: 'CANT_ADD_CONTACT_TO_GROUP',
payload: { conversationId },
};
}
function setPreJoinConversation( function setPreJoinConversation(
data: PreJoinConversationType | undefined data: PreJoinConversationType | undefined
): SetPreJoinConversationActionType { ): SetPreJoinConversationActionType {
@ -1722,9 +1699,6 @@ function clearUnreadMetrics(
}, },
}; };
} }
function closeCantAddContactToGroupModal(): CloseCantAddContactToGroupModalActionType {
return { type: 'CLOSE_CANT_ADD_CONTACT_TO_GROUP_MODAL' };
}
function closeContactSpoofingReview(): CloseContactSpoofingReviewActionType { function closeContactSpoofingReview(): CloseContactSpoofingReviewActionType {
return { type: 'CLOSE_CONTACT_SPOOFING_REVIEW' }; return { type: 'CLOSE_CONTACT_SPOOFING_REVIEW' };
} }
@ -2230,21 +2204,6 @@ export function reducer(
}; };
} }
if (action.type === 'CANT_ADD_CONTACT_TO_GROUP') {
const { composer } = state;
if (composer?.step !== ComposerStep.ChooseGroupMembers) {
assert(false, "Can't update modal in this composer step. Doing nothing");
return state;
}
return {
...state,
composer: {
...composer,
cantAddContactIdForModal: action.payload.conversationId,
},
};
}
if (action.type === 'CLEAR_INVITED_UUIDS_FOR_NEWLY_CREATED_GROUP') { if (action.type === 'CLEAR_INVITED_UUIDS_FOR_NEWLY_CREATED_GROUP') {
return omit(state, 'invitedUuidsForNewlyCreatedGroup'); return omit(state, 'invitedUuidsForNewlyCreatedGroup');
} }
@ -2267,24 +2226,6 @@ export function reducer(
}; };
} }
if (action.type === 'CLOSE_CANT_ADD_CONTACT_TO_GROUP_MODAL') {
const { composer } = state;
if (composer?.step !== ComposerStep.ChooseGroupMembers) {
assert(
false,
"Can't close the modal in this composer step. Doing nothing"
);
return state;
}
return {
...state,
composer: {
...composer,
cantAddContactIdForModal: undefined,
},
};
}
if (action.type === 'CLOSE_CONTACT_SPOOFING_REVIEW') { if (action.type === 'CLOSE_CONTACT_SPOOFING_REVIEW') {
return omit(state, 'contactSpoofingReview'); return omit(state, 'contactSpoofingReview');
} }
@ -3139,7 +3080,6 @@ export function reducer(
step: ComposerStep.ChooseGroupMembers, step: ComposerStep.ChooseGroupMembers,
searchTerm: '', searchTerm: '',
selectedConversationIds, selectedConversationIds,
cantAddContactIdForModal: undefined,
recommendedGroupSizeModalState, recommendedGroupSizeModalState,
maximumGroupSizeModalState, maximumGroupSizeModalState,
groupName, groupName,

View file

@ -535,28 +535,6 @@ export const getFilteredCandidateContactsForNewGroup = createSelector(
filterAndSortConversationsByTitle filterAndSortConversationsByTitle
); );
export const getCantAddContactForModal = createSelector(
getConversationLookup,
getComposerState,
(conversationLookup, composerState): undefined | ConversationType => {
if (composerState?.step !== ComposerStep.ChooseGroupMembers) {
return undefined;
}
const conversationId = composerState.cantAddContactIdForModal;
if (!conversationId) {
return undefined;
}
const result = getOwn(conversationLookup, conversationId);
assert(
result,
'getCantAddContactForModal: failed to look up conversation by ID; returning undefined'
);
return result;
}
);
const getGroupCreationComposerState = createSelector( const getGroupCreationComposerState = createSelector(
getComposerState, getComposerState,
( (

View file

@ -26,7 +26,6 @@ import {
getUsernamesEnabled, getUsernamesEnabled,
} from '../selectors/items'; } from '../selectors/items';
import { import {
getCantAddContactForModal,
getComposeAvatarData, getComposeAvatarData,
getComposeGroupAvatar, getComposeGroupAvatar,
getComposeGroupExpireTimer, getComposeGroupExpireTimer,
@ -148,7 +147,6 @@ const getModeSpecificProps = (
return { return {
mode: LeftPaneMode.ChooseGroupMembers, mode: LeftPaneMode.ChooseGroupMembers,
candidateContacts: getFilteredCandidateContactsForNewGroup(state), candidateContacts: getFilteredCandidateContactsForNewGroup(state),
cantAddContactForModal: getCantAddContactForModal(state),
isShowingRecommendedGroupSizeModal: isShowingRecommendedGroupSizeModal:
getRecommendedGroupSizeModalState(state) === getRecommendedGroupSizeModalState(state) ===
OneTimeModalState.Showing, OneTimeModalState.Showing,

View file

@ -1,4 +1,4 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { ComposerStep } from '../../state/ducks/conversationsEnums'; import { ComposerStep } from '../../state/ducks/conversationsEnums';
@ -13,7 +13,6 @@ export const defaultStartDirectConversationComposerState = {
export const defaultChooseGroupMembersComposerState = { export const defaultChooseGroupMembersComposerState = {
step: ComposerStep.ChooseGroupMembers as const, step: ComposerStep.ChooseGroupMembers as const,
searchTerm: '', searchTerm: '',
cantAddContactIdForModal: undefined,
groupAvatar: undefined, groupAvatar: undefined,
groupName: '', groupName: '',
groupExpireTimer: 0, groupExpireTimer: 0,

View file

@ -1,4 +1,4 @@
// Copyright 2020-2021 Signal Messenger, LLC // Copyright 2020-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { v4 as generateUuid } from 'uuid'; import { v4 as generateUuid } from 'uuid';
@ -330,7 +330,6 @@ export function getDefaultConversation(
color: getRandomColor(), color: getRandomColor(),
firstName, firstName,
id: generateUuid(), id: generateUuid(),
isGroupV2Capable: true,
isMe: false, isMe: false,
lastUpdated: Date.now(), lastUpdated: Date.now(),
markedUnread: Boolean(overrideProps.markedUnread), markedUnread: Boolean(overrideProps.markedUnread),

View file

@ -18,7 +18,6 @@ import {
_getLeftPaneLists, _getLeftPaneLists,
getAllComposableConversations, getAllComposableConversations,
getCandidateContactsForNewGroup, getCandidateContactsForNewGroup,
getCantAddContactForModal,
getComposableContacts, getComposableContacts,
getComposableGroups, getComposableGroups,
getComposeGroupAvatar, getComposeGroupAvatar,
@ -1162,53 +1161,6 @@ describe('both/state/selectors/conversations', () => {
}); });
}); });
describe('#getCantAddContactForModal', () => {
it('returns undefined if not in the "choose group members" composer step', () => {
assert.isUndefined(getCantAddContactForModal(getEmptyRootState()));
assert.isUndefined(
getCantAddContactForModal({
...getEmptyRootState(),
conversations: {
...getEmptyState(),
composer: defaultStartDirectConversationComposerState,
},
})
);
});
it("returns undefined if there's no contact marked", () => {
assert.isUndefined(
getCantAddContactForModal({
...getEmptyRootState(),
conversations: {
...getEmptyState(),
composer: defaultChooseGroupMembersComposerState,
},
})
);
});
it('returns the marked contact', () => {
const conversation = makeConversation('abc123');
assert.deepEqual(
getCantAddContactForModal({
...getEmptyRootState(),
conversations: {
...getEmptyState(),
conversationLookup: { abc123: conversation },
composer: {
...defaultChooseGroupMembersComposerState,
cantAddContactIdForModal: 'abc123',
},
},
}),
conversation
);
});
});
describe('#getComposerConversationSearchTerm', () => { describe('#getComposerConversationSearchTerm', () => {
it("returns the composer's contact search term", () => { it("returns the composer's contact search term", () => {
assert.strictEqual( assert.strictEqual(

View file

@ -47,10 +47,8 @@ import {
import { updateRemoteConfig } from '../../../test-both/helpers/RemoteConfigStub'; import { updateRemoteConfig } from '../../../test-both/helpers/RemoteConfigStub';
const { const {
cantAddContactToGroup,
clearGroupCreationError, clearGroupCreationError,
clearInvitedUuidsForNewlyCreatedGroup, clearInvitedUuidsForNewlyCreatedGroup,
closeCantAddContactToGroupModal,
closeContactSpoofingReview, closeContactSpoofingReview,
closeMaximumGroupSizeModal, closeMaximumGroupSizeModal,
closeRecommendedGroupSizeModal, closeRecommendedGroupSizeModal,
@ -461,22 +459,6 @@ describe('both/state/ducks/conversations', () => {
}); });
}); });
describe('CANT_ADD_CONTACT_TO_GROUP', () => {
it('marks the conversation ID as "cannot add"', () => {
const state = {
...getEmptyState(),
composer: defaultChooseGroupMembersComposerState,
};
const action = cantAddContactToGroup('abc123');
const result = reducer(state, action);
assert(
result.composer?.step === ComposerStep.ChooseGroupMembers &&
result.composer.cantAddContactIdForModal === 'abc123'
);
});
});
describe('CLEAR_GROUP_CREATION_ERROR', () => { describe('CLEAR_GROUP_CREATION_ERROR', () => {
it('clears the group creation error', () => { it('clears the group creation error', () => {
const state = { const state = {
@ -512,26 +494,6 @@ describe('both/state/ducks/conversations', () => {
}); });
}); });
describe('CLOSE_CANT_ADD_CONTACT_TO_GROUP_MODAL', () => {
it('closes the "cannot add contact" modal"', () => {
const state = {
...getEmptyState(),
composer: {
...defaultChooseGroupMembersComposerState,
cantAddContactIdForModal: 'abc123',
},
};
const action = closeCantAddContactToGroupModal();
const result = reducer(state, action);
assert(
result.composer?.step === ComposerStep.ChooseGroupMembers &&
result.composer.cantAddContactIdForModal === undefined,
'Expected the contact ID to be cleared'
);
});
});
describe('CLOSE_CONTACT_SPOOFING_REVIEW', () => { describe('CLOSE_CONTACT_SPOOFING_REVIEW', () => {
it('closes the contact spoofing review modal if it was open', () => { it('closes the contact spoofing review modal if it was open', () => {
const state = { const state = {

View file

@ -14,7 +14,6 @@ import { updateRemoteConfig } from '../../../test-both/helpers/RemoteConfigStub'
describe('LeftPaneChooseGroupMembersHelper', () => { describe('LeftPaneChooseGroupMembersHelper', () => {
const defaults = { const defaults = {
candidateContacts: [], candidateContacts: [],
cantAddContactForModal: undefined,
isShowingRecommendedGroupSizeModal: false, isShowingRecommendedGroupSizeModal: false,
isShowingMaximumGroupSizeModal: false, isShowingMaximumGroupSizeModal: false,
searchTerm: '', searchTerm: '',
@ -163,39 +162,5 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
disabledReason: undefined, disabledReason: undefined,
}); });
}); });
it("disables contacts that aren't GV2-capable, unless they are already selected somehow", () => {
const candidateContacts = [
{ ...getDefaultConversation(), isGroupV2Capable: false },
{ ...getDefaultConversation(), isGroupV2Capable: undefined },
{ ...getDefaultConversation(), isGroupV2Capable: false },
];
const helper = new LeftPaneChooseGroupMembersHelper({
...defaults,
candidateContacts,
searchTerm: 'foo bar',
selectedContacts: [candidateContacts[2]],
});
assert.deepEqual(helper.getRow(1), {
type: RowType.ContactCheckbox,
contact: candidateContacts[0],
isChecked: false,
disabledReason: ContactCheckboxDisabledReason.NotCapable,
});
assert.deepEqual(helper.getRow(2), {
type: RowType.ContactCheckbox,
contact: candidateContacts[1],
isChecked: false,
disabledReason: ContactCheckboxDisabledReason.NotCapable,
});
assert.deepEqual(helper.getRow(3), {
type: RowType.ContactCheckbox,
contact: candidateContacts[2],
isChecked: true,
disabledReason: undefined,
});
});
}); });
}); });

View file

@ -658,7 +658,6 @@ export type WebAPIConnectType = {
export type CapabilitiesType = { export type CapabilitiesType = {
announcementGroup: boolean; announcementGroup: boolean;
gv2: boolean;
'gv1-migration': boolean; 'gv1-migration': boolean;
senderKey: boolean; senderKey: boolean;
changeNumber: boolean; changeNumber: boolean;