Assume everyone is GV2-capable
This commit is contained in:
parent
0a52318be6
commit
effe5aae6f
22 changed files with 16 additions and 405 deletions
|
@ -2393,20 +2393,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chooseGroupMembers__cant-add-member__title": {
|
|
||||||
"message": "Can’t 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$\" can’t be added to the group because they’re using an old version of Signal. You can add them to the group after they’ve 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"
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
49
ts/groups.ts
49
ts/groups.ts
|
@ -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.`
|
||||||
);
|
);
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
(
|
(
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue