Do not populate left pane on initial link
This commit is contained in:
parent
f456bbd3db
commit
5e2d48cc2f
|
@ -761,6 +761,10 @@
|
||||||
"message": "Contacts",
|
"message": "Contacts",
|
||||||
"description": "Shown to separate the types of search results"
|
"description": "Shown to separate the types of search results"
|
||||||
},
|
},
|
||||||
|
"groupsHeader": {
|
||||||
|
"message": "Groups",
|
||||||
|
"description": "Shown to separate the types of search results"
|
||||||
|
},
|
||||||
"messagesHeader": {
|
"messagesHeader": {
|
||||||
"message": "Messages",
|
"message": "Messages",
|
||||||
"description": "Shown to separate the types of search results"
|
"description": "Shown to separate the types of search results"
|
||||||
|
@ -1905,6 +1909,10 @@
|
||||||
"message": "No contacts found",
|
"message": "No contacts found",
|
||||||
"description": "Label shown when there are no contacts to compose to"
|
"description": "Label shown when there are no contacts to compose to"
|
||||||
},
|
},
|
||||||
|
"noConversationsFound": {
|
||||||
|
"message": "No conversations found",
|
||||||
|
"description": "Label shown when there are no conversations to compose to"
|
||||||
|
},
|
||||||
"chooseGroupMembers__title": {
|
"chooseGroupMembers__title": {
|
||||||
"message": "Choose members",
|
"message": "Choose members",
|
||||||
"description": "The title for the 'choose group members' left pane screen"
|
"description": "The title for the 'choose group members' left pane screen"
|
||||||
|
@ -5130,5 +5138,19 @@
|
||||||
"MessageAudio--slider": {
|
"MessageAudio--slider": {
|
||||||
"message": "Playback time of audio attachment",
|
"message": "Playback time of audio attachment",
|
||||||
"description": "Aria label for audio attachment's playback time slider"
|
"description": "Aria label for audio attachment's playback time slider"
|
||||||
|
},
|
||||||
|
"emptyInboxMessage": {
|
||||||
|
"message": "Click the $composeIcon$ above and search for your contacts or groups to message.",
|
||||||
|
"description": "Shown in the left-pane when the inbox is empty",
|
||||||
|
"placeholders": {
|
||||||
|
"composeIcon": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "compose button"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"composeIcon": {
|
||||||
|
"message": "compose button",
|
||||||
|
"description": "Shown in the left-pane when the inbox is empty. Describes the button that composes a new message."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,8 @@
|
||||||
},
|
},
|
||||||
render_attributes: {
|
render_attributes: {
|
||||||
welcomeToSignal: i18n('welcomeToSignal'),
|
welcomeToSignal: i18n('welcomeToSignal'),
|
||||||
selectAContact: i18n('selectAContact'),
|
// TODO DESKTOP-1451: add back the selectAContact message
|
||||||
|
selectAContact: '',
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
click: 'onClick',
|
click: 'onClick',
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
initialize(options = {}) {
|
initialize(options = {}) {
|
||||||
window.readyForUpdates();
|
window.readyForUpdates();
|
||||||
|
|
||||||
this.didLink = false;
|
|
||||||
this.selectStep(Steps.SCAN_QR_CODE);
|
this.selectStep(Steps.SCAN_QR_CODE);
|
||||||
this.connect();
|
this.connect();
|
||||||
this.on('disconnected', this.reconnect);
|
this.on('disconnected', this.reconnect);
|
||||||
|
@ -197,7 +196,7 @@
|
||||||
this.selectStep(Steps.PROGRESS_BAR);
|
this.selectStep(Steps.PROGRESS_BAR);
|
||||||
|
|
||||||
const finish = () => {
|
const finish = () => {
|
||||||
this.didLink = true;
|
window.Signal.Util.postLinkExperience.start();
|
||||||
return resolve(name);
|
return resolve(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7401,6 +7401,36 @@ button.module-image__border-overlay:focus {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.module-left-pane__empty {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 32px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&--composer_icon {
|
||||||
|
align-items: center;
|
||||||
|
background-color: $color-gray-05;
|
||||||
|
border-radius: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
height: 28px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: -2px;
|
||||||
|
margin-left: 4px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
width: 28px;
|
||||||
|
|
||||||
|
&--icon {
|
||||||
|
$icon: '../images/icons/v2/compose-outline-24.svg';
|
||||||
|
@include color-svg($icon, $color-gray-90);
|
||||||
|
display: inline-block;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.module-left-pane__header {
|
.module-left-pane__header {
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
|
@ -2398,13 +2398,6 @@ export async function startApp(): Promise<void> {
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
const conversation = window.ConversationController.get(detailsId)!;
|
const conversation = window.ConversationController.get(detailsId)!;
|
||||||
let activeAt = conversation.get('active_at');
|
|
||||||
|
|
||||||
// The idea is to make any new contact show up in the left pane. If
|
|
||||||
// activeAt is null, then this contact has been purposefully hidden.
|
|
||||||
if (activeAt !== null) {
|
|
||||||
activeAt = activeAt || Date.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (details.profileKey) {
|
if (details.profileKey) {
|
||||||
const profileKey = window.Signal.Crypto.arrayBufferToBase64(
|
const profileKey = window.Signal.Crypto.arrayBufferToBase64(
|
||||||
|
@ -2424,7 +2417,6 @@ export async function startApp(): Promise<void> {
|
||||||
conversation.set({
|
conversation.set({
|
||||||
name: details.name,
|
name: details.name,
|
||||||
color: details.color,
|
color: details.color,
|
||||||
active_at: activeAt,
|
|
||||||
inbox_position: details.inboxPosition,
|
inbox_position: details.inboxPosition,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2480,8 +2472,7 @@ export async function startApp(): Promise<void> {
|
||||||
await onVerified(verifiedEvent);
|
await onVerified(verifiedEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { appView } = window.owsDesktopApp;
|
if (window.Signal.Util.postLinkExperience.isActive()) {
|
||||||
if (appView && appView.installView && appView.installView.didLink) {
|
|
||||||
window.log.info(
|
window.log.info(
|
||||||
'onContactReceived: Adding the message history disclaimer on link'
|
'onContactReceived: Adding the message history disclaimer on link'
|
||||||
);
|
);
|
||||||
|
@ -2538,13 +2529,6 @@ export async function startApp(): Promise<void> {
|
||||||
} as WhatIsThis;
|
} as WhatIsThis;
|
||||||
|
|
||||||
if (details.active) {
|
if (details.active) {
|
||||||
const activeAt = conversation.get('active_at');
|
|
||||||
|
|
||||||
// The idea is to make any new group show up in the left pane. If
|
|
||||||
// activeAt is null, then this group has been purposefully hidden.
|
|
||||||
if (activeAt !== null) {
|
|
||||||
updates.active_at = activeAt || Date.now();
|
|
||||||
}
|
|
||||||
updates.left = false;
|
updates.left = false;
|
||||||
} else {
|
} else {
|
||||||
updates.left = true;
|
updates.left = true;
|
||||||
|
@ -2575,8 +2559,7 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
window.Signal.Data.updateConversation(conversation.attributes);
|
window.Signal.Data.updateConversation(conversation.attributes);
|
||||||
|
|
||||||
const { appView } = window.owsDesktopApp;
|
if (window.Signal.Util.postLinkExperience.isActive()) {
|
||||||
if (appView && appView.installView && appView.installView.didLink) {
|
|
||||||
window.log.info(
|
window.log.info(
|
||||||
'onGroupReceived: Adding the message history disclaimer on link'
|
'onGroupReceived: Adding the message history disclaimer on link'
|
||||||
);
|
);
|
||||||
|
@ -2846,9 +2829,6 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
// Finally create the V2 group normally
|
// Finally create the V2 group normally
|
||||||
const conversationId = window.ConversationController.ensureGroup(id, {
|
const conversationId = window.ConversationController.ensureGroup(id, {
|
||||||
// Note: We don't set active_at, because we don't want the group to show until
|
|
||||||
// we have information about it beyond these initial details.
|
|
||||||
// see maybeUpdateGroup().
|
|
||||||
groupVersion: 2,
|
groupVersion: 2,
|
||||||
masterKey: message.groupV2.masterKey,
|
masterKey: message.groupV2.masterKey,
|
||||||
secretParams: message.groupV2.secretParams,
|
secretParams: message.groupV2.secretParams,
|
||||||
|
|
|
@ -35,6 +35,25 @@ const defaultConversations: Array<ConversationListItemPropsType> = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const defaultGroups: Array<ConversationListItemPropsType> = [
|
||||||
|
{
|
||||||
|
id: 'biking-group',
|
||||||
|
isSelected: false,
|
||||||
|
lastUpdated: Date.now(),
|
||||||
|
markedUnread: false,
|
||||||
|
title: 'Mtn Biking Arizona 🚵☀️⛰',
|
||||||
|
type: 'group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'dance-group',
|
||||||
|
isSelected: false,
|
||||||
|
lastUpdated: Date.now(),
|
||||||
|
markedUnread: false,
|
||||||
|
title: 'Are we dancers? 💃',
|
||||||
|
type: 'group',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const defaultArchivedConversations: Array<ConversationListItemPropsType> = [
|
const defaultArchivedConversations: Array<ConversationListItemPropsType> = [
|
||||||
{
|
{
|
||||||
id: 'michelle-archive-convo',
|
id: 'michelle-archive-convo',
|
||||||
|
@ -352,12 +371,13 @@ story.add('Archive: archived conversations', () => (
|
||||||
|
|
||||||
// Compose stories
|
// Compose stories
|
||||||
|
|
||||||
story.add('Compose: no contacts', () => (
|
story.add('Compose: no contacts or groups', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...createProps({
|
{...createProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
mode: LeftPaneMode.Compose,
|
mode: LeftPaneMode.Compose,
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
|
@ -365,12 +385,13 @@ story.add('Compose: no contacts', () => (
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
story.add('Compose: some contacts, no search term', () => (
|
story.add('Compose: some contacts, no groups, no search term', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...createProps({
|
{...createProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
mode: LeftPaneMode.Compose,
|
mode: LeftPaneMode.Compose,
|
||||||
composeContacts: defaultConversations,
|
composeContacts: defaultConversations,
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
|
@ -378,14 +399,71 @@ story.add('Compose: some contacts, no search term', () => (
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
story.add('Compose: some contacts with a search term', () => (
|
story.add('Compose: some contacts, no groups, with a search term', () => (
|
||||||
<LeftPane
|
<LeftPane
|
||||||
{...createProps({
|
{...createProps({
|
||||||
modeSpecificProps: {
|
modeSpecificProps: {
|
||||||
mode: LeftPaneMode.Compose,
|
mode: LeftPaneMode.Compose,
|
||||||
composeContacts: defaultConversations,
|
composeContacts: defaultConversations,
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'ar',
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
story.add('Compose: some groups, no contacts, no search term', () => (
|
||||||
|
<LeftPane
|
||||||
|
{...createProps({
|
||||||
|
modeSpecificProps: {
|
||||||
|
mode: LeftPaneMode.Compose,
|
||||||
|
composeContacts: [],
|
||||||
|
composeGroups: defaultGroups,
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: '',
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
story.add('Compose: some groups, no contacts, with search term', () => (
|
||||||
|
<LeftPane
|
||||||
|
{...createProps({
|
||||||
|
modeSpecificProps: {
|
||||||
|
mode: LeftPaneMode.Compose,
|
||||||
|
composeContacts: [],
|
||||||
|
composeGroups: defaultGroups,
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'ar',
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
story.add('Compose: some contacts, some groups, no search term', () => (
|
||||||
|
<LeftPane
|
||||||
|
{...createProps({
|
||||||
|
modeSpecificProps: {
|
||||||
|
mode: LeftPaneMode.Compose,
|
||||||
|
composeContacts: defaultConversations,
|
||||||
|
composeGroups: defaultGroups,
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: '',
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
story.add('Compose: some contacts, some groups, with a search term', () => (
|
||||||
|
<LeftPane
|
||||||
|
{...createProps({
|
||||||
|
modeSpecificProps: {
|
||||||
|
mode: LeftPaneMode.Compose,
|
||||||
|
composeContacts: defaultConversations,
|
||||||
|
composeGroups: defaultGroups,
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'ar',
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { LocalizerType } from '../../../../types/Util';
|
||||||
import { assert } from '../../../../util/assert';
|
import { assert } from '../../../../util/assert';
|
||||||
import { getOwn } from '../../../../util/getOwn';
|
import { getOwn } from '../../../../util/getOwn';
|
||||||
import { missingCaseError } from '../../../../util/missingCaseError';
|
import { missingCaseError } from '../../../../util/missingCaseError';
|
||||||
import { filterAndSortContacts } from '../../../../util/filterAndSortContacts';
|
import { filterAndSortConversations } from '../../../../util/filterAndSortConversations';
|
||||||
import { ConversationType } from '../../../../state/ducks/conversations';
|
import { ConversationType } from '../../../../state/ducks/conversations';
|
||||||
import { ModalHost } from '../../../ModalHost';
|
import { ModalHost } from '../../../ModalHost';
|
||||||
import { ContactPills } from '../../../ContactPills';
|
import { ContactPills } from '../../../ContactPills';
|
||||||
|
@ -72,13 +72,13 @@ export const ChooseGroupMembersModal: FunctionComponent<PropsType> = ({
|
||||||
const canContinue = Boolean(selectedContacts.length);
|
const canContinue = Boolean(selectedContacts.length);
|
||||||
|
|
||||||
const [filteredContacts, setFilteredContacts] = useState(
|
const [filteredContacts, setFilteredContacts] = useState(
|
||||||
filterAndSortContacts(candidateContacts, '')
|
filterAndSortConversations(candidateContacts, '')
|
||||||
);
|
);
|
||||||
const normalizedSearchTerm = searchTerm.trim();
|
const normalizedSearchTerm = searchTerm.trim();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
setFilteredContacts(
|
setFilteredContacts(
|
||||||
filterAndSortContacts(candidateContacts, normalizedSearchTerm)
|
filterAndSortConversations(candidateContacts, normalizedSearchTerm)
|
||||||
);
|
);
|
||||||
}, 200);
|
}, 200);
|
||||||
return () => {
|
return () => {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { PhoneNumber } from 'google-libphonenumber';
|
||||||
import { LeftPaneHelper } from './LeftPaneHelper';
|
import { LeftPaneHelper } from './LeftPaneHelper';
|
||||||
import { Row, RowType } from '../ConversationList';
|
import { Row, RowType } from '../ConversationList';
|
||||||
import { PropsDataType as ContactListItemPropsType } from '../conversationList/ContactListItem';
|
import { PropsDataType as ContactListItemPropsType } from '../conversationList/ContactListItem';
|
||||||
|
import { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
import {
|
import {
|
||||||
instance as phoneNumberInstance,
|
instance as phoneNumberInstance,
|
||||||
|
@ -18,6 +19,7 @@ import { isStorageWriteFeatureEnabled } from '../../storage/isFeatureEnabled';
|
||||||
|
|
||||||
export type LeftPaneComposePropsType = {
|
export type LeftPaneComposePropsType = {
|
||||||
composeContacts: ReadonlyArray<ContactListItemPropsType>;
|
composeContacts: ReadonlyArray<ContactListItemPropsType>;
|
||||||
|
composeGroups: ReadonlyArray<ContactListItemPropsType>;
|
||||||
regionCode: string;
|
regionCode: string;
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
};
|
};
|
||||||
|
@ -35,20 +37,24 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<
|
||||||
> {
|
> {
|
||||||
private readonly composeContacts: ReadonlyArray<ContactListItemPropsType>;
|
private readonly composeContacts: ReadonlyArray<ContactListItemPropsType>;
|
||||||
|
|
||||||
|
private readonly composeGroups: ReadonlyArray<ConversationListItemPropsType>;
|
||||||
|
|
||||||
private readonly searchTerm: string;
|
private readonly searchTerm: string;
|
||||||
|
|
||||||
private readonly phoneNumber: undefined | PhoneNumber;
|
private readonly phoneNumber: undefined | PhoneNumber;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
composeContacts,
|
composeContacts,
|
||||||
|
composeGroups,
|
||||||
regionCode,
|
regionCode,
|
||||||
searchTerm,
|
searchTerm,
|
||||||
}: Readonly<LeftPaneComposePropsType>) {
|
}: Readonly<LeftPaneComposePropsType>) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.composeContacts = composeContacts;
|
|
||||||
this.searchTerm = searchTerm;
|
this.searchTerm = searchTerm;
|
||||||
this.phoneNumber = parsePhoneNumber(searchTerm, regionCode);
|
this.phoneNumber = parsePhoneNumber(searchTerm, regionCode);
|
||||||
|
this.composeGroups = composeGroups;
|
||||||
|
this.composeContacts = composeContacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHeaderContents({
|
getHeaderContents({
|
||||||
|
@ -103,7 +109,7 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<
|
||||||
|
|
||||||
{this.getRowCount() ? null : (
|
{this.getRowCount() ? null : (
|
||||||
<div className="module-left-pane__compose-no-contacts">
|
<div className="module-left-pane__compose-no-contacts">
|
||||||
{i18n('noContactsFound')}
|
{i18n('noConversationsFound')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
@ -111,62 +117,89 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<
|
||||||
}
|
}
|
||||||
|
|
||||||
getRowCount(): number {
|
getRowCount(): number {
|
||||||
let result = this.composeContacts.length;
|
let result = this.composeContacts.length + this.composeGroups.length;
|
||||||
if (this.hasTopButton()) {
|
if (this.hasTopButton()) {
|
||||||
result += 1;
|
result += 1;
|
||||||
}
|
}
|
||||||
if (this.hasContactsHeader()) {
|
if (this.hasContactsHeader()) {
|
||||||
result += 1;
|
result += 1;
|
||||||
}
|
}
|
||||||
|
if (this.hasGroupsHeader()) {
|
||||||
|
result += 1;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRow(rowIndex: number): undefined | Row {
|
getRow(actualRowIndex: number): undefined | Row {
|
||||||
if (rowIndex === 0) {
|
let virtualRowIndex = actualRowIndex;
|
||||||
const topButton = this.getTopButton();
|
if (this.hasTopButton()) {
|
||||||
switch (topButton) {
|
if (virtualRowIndex === 0) {
|
||||||
case TopButton.None:
|
const topButton = this.getTopButton();
|
||||||
break;
|
switch (topButton) {
|
||||||
case TopButton.StartNewConversation:
|
case TopButton.None:
|
||||||
assert(
|
break;
|
||||||
this.phoneNumber,
|
case TopButton.StartNewConversation:
|
||||||
'LeftPaneComposeHelper: we should have a phone number if the top button is "Start new conversation"'
|
assert(
|
||||||
);
|
|
||||||
return {
|
|
||||||
type: RowType.StartNewConversation,
|
|
||||||
phoneNumber: phoneNumberInstance.format(
|
|
||||||
this.phoneNumber,
|
this.phoneNumber,
|
||||||
PhoneNumberFormat.E164
|
'LeftPaneComposeHelper: we should have a phone number if the top button is "Start new conversation"'
|
||||||
),
|
);
|
||||||
};
|
return {
|
||||||
case TopButton.CreateNewGroup:
|
type: RowType.StartNewConversation,
|
||||||
return { type: RowType.CreateNewGroup };
|
phoneNumber: phoneNumberInstance.format(
|
||||||
default:
|
this.phoneNumber,
|
||||||
throw missingCaseError(topButton);
|
PhoneNumberFormat.E164
|
||||||
|
),
|
||||||
|
};
|
||||||
|
case TopButton.CreateNewGroup:
|
||||||
|
return { type: RowType.CreateNewGroup };
|
||||||
|
default:
|
||||||
|
throw missingCaseError(topButton);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtualRowIndex -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rowIndex === 1 && this.hasContactsHeader()) {
|
if (this.hasContactsHeader()) {
|
||||||
|
if (virtualRowIndex === 0) {
|
||||||
|
return {
|
||||||
|
type: RowType.Header,
|
||||||
|
i18nKey: 'contactsHeader',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtualRowIndex -= 1;
|
||||||
|
|
||||||
|
const contact = this.composeContacts[virtualRowIndex];
|
||||||
|
if (contact) {
|
||||||
|
return {
|
||||||
|
type: RowType.Contact,
|
||||||
|
contact,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtualRowIndex -= this.composeContacts.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.hasGroupsHeader()) {
|
||||||
|
if (virtualRowIndex === 0) {
|
||||||
|
return {
|
||||||
|
type: RowType.Header,
|
||||||
|
i18nKey: 'groupsHeader',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtualRowIndex -= 1;
|
||||||
|
|
||||||
|
const group = this.composeGroups[virtualRowIndex];
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Conversation,
|
||||||
i18nKey: 'contactsHeader',
|
conversation: group,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let contactIndex: number;
|
return undefined;
|
||||||
if (this.hasTopButton()) {
|
|
||||||
contactIndex = rowIndex - 2;
|
|
||||||
} else {
|
|
||||||
contactIndex = rowIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
const contact = this.composeContacts[contactIndex];
|
|
||||||
return contact
|
|
||||||
? {
|
|
||||||
type: RowType.Contact,
|
|
||||||
contact,
|
|
||||||
}
|
|
||||||
: undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is deliberately unimplemented because these keyboard shortcuts shouldn't work in
|
// This is deliberately unimplemented because these keyboard shortcuts shouldn't work in
|
||||||
|
@ -183,10 +216,17 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldRecomputeRowHeights(old: Readonly<LeftPaneComposePropsType>): boolean {
|
shouldRecomputeRowHeights(
|
||||||
|
exProps: Readonly<LeftPaneComposePropsType>
|
||||||
|
): boolean {
|
||||||
|
const prev = new LeftPaneComposeHelper(exProps);
|
||||||
|
const currHeaderIndices = this.getHeaderIndices();
|
||||||
|
const prevHeaderIndices = prev.getHeaderIndices();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
this.hasContactsHeader() !==
|
currHeaderIndices.top !== prevHeaderIndices.top ||
|
||||||
new LeftPaneComposeHelper(old).hasContactsHeader()
|
currHeaderIndices.contact !== prevHeaderIndices.contact ||
|
||||||
|
currHeaderIndices.group !== prevHeaderIndices.group
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +245,39 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<
|
||||||
}
|
}
|
||||||
|
|
||||||
private hasContactsHeader(): boolean {
|
private hasContactsHeader(): boolean {
|
||||||
return this.hasTopButton() && Boolean(this.composeContacts.length);
|
return Boolean(this.composeContacts.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private hasGroupsHeader(): boolean {
|
||||||
|
return Boolean(this.composeGroups.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getHeaderIndices(): {
|
||||||
|
top?: number;
|
||||||
|
contact?: number;
|
||||||
|
group?: number;
|
||||||
|
} {
|
||||||
|
let top: number | undefined;
|
||||||
|
let contact: number | undefined;
|
||||||
|
let group: number | undefined;
|
||||||
|
let rowCount = 0;
|
||||||
|
if (this.hasTopButton()) {
|
||||||
|
top = 0;
|
||||||
|
rowCount += 1;
|
||||||
|
}
|
||||||
|
if (this.composeContacts.length) {
|
||||||
|
contact = rowCount;
|
||||||
|
rowCount += this.composeContacts.length;
|
||||||
|
}
|
||||||
|
if (this.composeGroups.length) {
|
||||||
|
group = rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
top,
|
||||||
|
contact,
|
||||||
|
group,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { last } from 'lodash';
|
import { last } from 'lodash';
|
||||||
|
import React, { ReactChild } from 'react';
|
||||||
|
|
||||||
|
import { Intl } from '../Intl';
|
||||||
import { LeftPaneHelper, ToFindType } from './LeftPaneHelper';
|
import { LeftPaneHelper, ToFindType } from './LeftPaneHelper';
|
||||||
import { getConversationInDirection } from './getConversationInDirection';
|
import { getConversationInDirection } from './getConversationInDirection';
|
||||||
import { Row, RowType } from '../ConversationList';
|
import { Row, RowType } from '../ConversationList';
|
||||||
import { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
import { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
||||||
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
|
||||||
export type LeftPaneInboxPropsType = {
|
export type LeftPaneInboxPropsType = {
|
||||||
conversations: ReadonlyArray<ConversationListItemPropsType>;
|
conversations: ReadonlyArray<ConversationListItemPropsType>;
|
||||||
|
@ -56,6 +59,33 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPreRowsNode({
|
||||||
|
i18n,
|
||||||
|
}: Readonly<{ i18n: LocalizerType }>): null | ReactChild {
|
||||||
|
if (this.getRowCount() === 0) {
|
||||||
|
return (
|
||||||
|
<div className="module-left-pane__empty">
|
||||||
|
<div>
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="emptyInboxMessage"
|
||||||
|
components={[
|
||||||
|
<span>
|
||||||
|
<strong>{i18n('composeIcon')}</strong>
|
||||||
|
<span className="module-left-pane__empty--composer_icon">
|
||||||
|
<i className="module-left-pane__empty--composer_icon--icon" />
|
||||||
|
</span>
|
||||||
|
</span>,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
getRow(rowIndex: number): undefined | Row {
|
getRow(rowIndex: number): undefined | Row {
|
||||||
const { conversations, archivedConversations, pinnedConversations } = this;
|
const { conversations, archivedConversations, pinnedConversations } = this;
|
||||||
|
|
74
ts/groups.ts
74
ts/groups.ts
|
@ -2598,7 +2598,8 @@ type MaybeUpdatePropsType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function waitThenMaybeUpdateGroup(
|
export async function waitThenMaybeUpdateGroup(
|
||||||
options: MaybeUpdatePropsType
|
options: MaybeUpdatePropsType,
|
||||||
|
{ viaSync = false } = {}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// First wait to process all incoming messages on the websocket
|
// First wait to process all incoming messages on the websocket
|
||||||
await window.waitForEmptyEventQueue();
|
await window.waitForEmptyEventQueue();
|
||||||
|
@ -2609,7 +2610,7 @@ export async function waitThenMaybeUpdateGroup(
|
||||||
await conversation.queueJob(async () => {
|
await conversation.queueJob(async () => {
|
||||||
try {
|
try {
|
||||||
// And finally try to update the group
|
// And finally try to update the group
|
||||||
await maybeUpdateGroup(options);
|
await maybeUpdateGroup(options, { viaSync });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.log.error(
|
||||||
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: maybeUpdateGroup failure:`,
|
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: maybeUpdateGroup failure:`,
|
||||||
|
@ -2619,14 +2620,17 @@ export async function waitThenMaybeUpdateGroup(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function maybeUpdateGroup({
|
export async function maybeUpdateGroup(
|
||||||
conversation,
|
{
|
||||||
dropInitialJoinMessage,
|
conversation,
|
||||||
groupChangeBase64,
|
dropInitialJoinMessage,
|
||||||
newRevision,
|
groupChangeBase64,
|
||||||
receivedAt,
|
newRevision,
|
||||||
sentAt,
|
receivedAt,
|
||||||
}: MaybeUpdatePropsType): Promise<void> {
|
sentAt,
|
||||||
|
}: MaybeUpdatePropsType,
|
||||||
|
{ viaSync = false } = {}
|
||||||
|
): Promise<void> {
|
||||||
const logId = conversation.idForLogging();
|
const logId = conversation.idForLogging();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -2641,7 +2645,10 @@ export async function maybeUpdateGroup({
|
||||||
dropInitialJoinMessage,
|
dropInitialJoinMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateGroup({ conversation, receivedAt, sentAt, updates });
|
await updateGroup(
|
||||||
|
{ conversation, receivedAt, sentAt, updates },
|
||||||
|
{ viaSync }
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.log.error(
|
||||||
`maybeUpdateGroup/${logId}: Failed to update group:`,
|
`maybeUpdateGroup/${logId}: Failed to update group:`,
|
||||||
|
@ -2651,17 +2658,20 @@ export async function maybeUpdateGroup({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateGroup({
|
async function updateGroup(
|
||||||
conversation,
|
{
|
||||||
receivedAt,
|
conversation,
|
||||||
sentAt,
|
receivedAt,
|
||||||
updates,
|
sentAt,
|
||||||
}: {
|
updates,
|
||||||
conversation: ConversationModel;
|
}: {
|
||||||
receivedAt?: number;
|
conversation: ConversationModel;
|
||||||
sentAt?: number;
|
receivedAt?: number;
|
||||||
updates: UpdatesResultType;
|
sentAt?: number;
|
||||||
}): Promise<void> {
|
updates: UpdatesResultType;
|
||||||
|
},
|
||||||
|
{ viaSync = false } = {}
|
||||||
|
): Promise<void> {
|
||||||
const { newAttributes, groupChangeMessages, members } = updates;
|
const { newAttributes, groupChangeMessages, members } = updates;
|
||||||
|
|
||||||
const startingRevision = conversation.get('revision');
|
const startingRevision = conversation.get('revision');
|
||||||
|
@ -2684,15 +2694,21 @@ async function updateGroup({
|
||||||
const previousId = conversation.get('groupId');
|
const previousId = conversation.get('groupId');
|
||||||
const idChanged = previousId && previousId !== newAttributes.groupId;
|
const idChanged = previousId && previousId !== newAttributes.groupId;
|
||||||
|
|
||||||
|
// We force this conversation into the left pane if this is the first time we've
|
||||||
|
// fetched data about it, and we were able to fetch its name. Nobody likes to see
|
||||||
|
// Unknown Group in the left pane.
|
||||||
|
let activeAt = null;
|
||||||
|
if (viaSync) {
|
||||||
|
activeAt = null;
|
||||||
|
} else if ((isInitialDataFetch || justJoinedGroup) && newAttributes.name) {
|
||||||
|
activeAt = initialSentAt;
|
||||||
|
} else {
|
||||||
|
activeAt = newAttributes.active_at;
|
||||||
|
}
|
||||||
|
|
||||||
conversation.set({
|
conversation.set({
|
||||||
...newAttributes,
|
...newAttributes,
|
||||||
// We force this conversation into the left pane if this is the first time we've
|
active_at: activeAt,
|
||||||
// fetched data about it, and we were able to fetch its name. Nobody likes to see
|
|
||||||
// Unknown Group in the left pane.
|
|
||||||
active_at:
|
|
||||||
(isInitialDataFetch || justJoinedGroup) && newAttributes.name
|
|
||||||
? initialSentAt
|
|
||||||
: newAttributes.active_at,
|
|
||||||
temporaryMemberCount: isInGroup
|
temporaryMemberCount: isInGroup
|
||||||
? undefined
|
? undefined
|
||||||
: newAttributes.temporaryMemberCount,
|
: newAttributes.temporaryMemberCount,
|
||||||
|
|
|
@ -1035,6 +1035,7 @@ async function sync(): Promise<ManifestRecordClass | undefined> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.Signal.Util.postLinkExperience.stop();
|
||||||
window.log.info('storageService.sync: complete');
|
window.log.info('storageService.sync: complete');
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
|
|
@ -685,10 +685,13 @@ export async function mergeGroupV2Record(
|
||||||
|
|
||||||
// We don't await this because this could take a very long time, waiting for queues to
|
// We don't await this because this could take a very long time, waiting for queues to
|
||||||
// empty, etc.
|
// empty, etc.
|
||||||
waitThenMaybeUpdateGroup({
|
waitThenMaybeUpdateGroup(
|
||||||
conversation,
|
{
|
||||||
dropInitialJoinMessage,
|
conversation,
|
||||||
});
|
dropInitialJoinMessage,
|
||||||
|
},
|
||||||
|
{ viaSync: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasPendingChanges;
|
return hasPendingChanges;
|
||||||
|
|
|
@ -259,11 +259,11 @@ type ComposerGroupCreationState = {
|
||||||
type ComposerStateType =
|
type ComposerStateType =
|
||||||
| {
|
| {
|
||||||
step: ComposerStep.StartDirectConversation;
|
step: ComposerStep.StartDirectConversation;
|
||||||
contactSearchTerm: string;
|
searchTerm: string;
|
||||||
}
|
}
|
||||||
| ({
|
| ({
|
||||||
step: ComposerStep.ChooseGroupMembers;
|
step: ComposerStep.ChooseGroupMembers;
|
||||||
contactSearchTerm: string;
|
searchTerm: string;
|
||||||
cantAddContactIdForModal: undefined | string;
|
cantAddContactIdForModal: undefined | string;
|
||||||
} & ComposerGroupCreationState)
|
} & ComposerGroupCreationState)
|
||||||
| ({
|
| ({
|
||||||
|
@ -529,7 +529,7 @@ type SetComposeGroupNameActionType = {
|
||||||
};
|
};
|
||||||
type SetComposeSearchTermActionType = {
|
type SetComposeSearchTermActionType = {
|
||||||
type: 'SET_COMPOSE_SEARCH_TERM';
|
type: 'SET_COMPOSE_SEARCH_TERM';
|
||||||
payload: { contactSearchTerm: string };
|
payload: { searchTerm: string };
|
||||||
};
|
};
|
||||||
type SetRecentMediaItemsActionType = {
|
type SetRecentMediaItemsActionType = {
|
||||||
type: 'SET_RECENT_MEDIA_ITEMS';
|
type: 'SET_RECENT_MEDIA_ITEMS';
|
||||||
|
@ -1012,11 +1012,11 @@ function setComposeGroupName(groupName: string): SetComposeGroupNameActionType {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setComposeSearchTerm(
|
function setComposeSearchTerm(
|
||||||
contactSearchTerm: string
|
searchTerm: string
|
||||||
): SetComposeSearchTermActionType {
|
): SetComposeSearchTermActionType {
|
||||||
return {
|
return {
|
||||||
type: 'SET_COMPOSE_SEARCH_TERM',
|
type: 'SET_COMPOSE_SEARCH_TERM',
|
||||||
payload: { contactSearchTerm },
|
payload: { searchTerm },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2117,7 +2117,7 @@ export function reducer(
|
||||||
showArchived: false,
|
showArchived: false,
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2154,7 +2154,7 @@ export function reducer(
|
||||||
showArchived: false,
|
showArchived: false,
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds,
|
selectedConversationIds,
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState,
|
recommendedGroupSizeModalState,
|
||||||
|
@ -2253,7 +2253,7 @@ export function reducer(
|
||||||
...state,
|
...state,
|
||||||
composer: {
|
composer: {
|
||||||
...composer,
|
...composer,
|
||||||
contactSearchTerm: action.payload.contactSearchTerm,
|
searchTerm: action.payload.searchTerm,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import { PropsDataType as TimelinePropsType } from '../../components/conversatio
|
||||||
import { TimelineItemType } from '../../components/conversation/TimelineItem';
|
import { TimelineItemType } from '../../components/conversation/TimelineItem';
|
||||||
import { assert } from '../../util/assert';
|
import { assert } from '../../util/assert';
|
||||||
import { isConversationUnregistered } from '../../util/isConversationUnregistered';
|
import { isConversationUnregistered } from '../../util/isConversationUnregistered';
|
||||||
import { filterAndSortContacts } from '../../util/filterAndSortContacts';
|
import { filterAndSortConversations } from '../../util/filterAndSortConversations';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getInteractionMode,
|
getInteractionMode,
|
||||||
|
@ -323,24 +323,33 @@ export const getMe = createSelector(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getComposerContactSearchTerm = createSelector(
|
export const getComposerConversationSearchTerm = createSelector(
|
||||||
getComposerState,
|
getComposerState,
|
||||||
(composer): string => {
|
(composer): string => {
|
||||||
if (!composer) {
|
if (!composer) {
|
||||||
assert(false, 'getComposerContactSearchTerm: composer is not open');
|
assert(false, 'getComposerConversationSearchTerm: composer is not open');
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (composer.step === ComposerStep.SetGroupMetadata) {
|
if (composer.step === ComposerStep.SetGroupMetadata) {
|
||||||
assert(
|
assert(
|
||||||
false,
|
false,
|
||||||
'getComposerContactSearchTerm: composer does not have a search term'
|
'getComposerConversationSearchTerm: composer does not have a search term'
|
||||||
);
|
);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return composer.contactSearchTerm;
|
return composer.searchTerm;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function canComposeConversation(conversation: ConversationType): boolean {
|
||||||
|
return Boolean(
|
||||||
|
!conversation.isMe &&
|
||||||
|
!conversation.isBlocked &&
|
||||||
|
!isConversationUnregistered(conversation) &&
|
||||||
|
(isString(conversation.name) || conversation.profileSharing)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This returns contacts for the composer and group members, which isn't just your primary
|
* This returns contacts for the composer and group members, which isn't just your primary
|
||||||
* system contacts. It may include false positives, which is better than missing contacts.
|
* system contacts. It may include false positives, which is better than missing contacts.
|
||||||
|
@ -349,21 +358,26 @@ export const getComposerContactSearchTerm = createSelector(
|
||||||
* current time, it's possible for this to return stale contacts that have unregistered
|
* current time, it's possible for this to return stale contacts that have unregistered
|
||||||
* if no other conversations change. This should be a rare false positive.
|
* if no other conversations change. This should be a rare false positive.
|
||||||
*/
|
*/
|
||||||
export const getContacts = createSelector(
|
export const getComposableContacts = createSelector(
|
||||||
getConversationLookup,
|
getConversationLookup,
|
||||||
(conversationLookup: ConversationLookupType): Array<ConversationType> =>
|
(conversationLookup: ConversationLookupType): Array<ConversationType> =>
|
||||||
Object.values(conversationLookup).filter(
|
Object.values(conversationLookup).filter(
|
||||||
contact =>
|
conversation =>
|
||||||
contact.type === 'direct' &&
|
conversation.type === 'direct' && canComposeConversation(conversation)
|
||||||
!contact.isMe &&
|
|
||||||
!contact.isBlocked &&
|
|
||||||
!isConversationUnregistered(contact) &&
|
|
||||||
(isString(contact.name) || contact.profileSharing)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const getNormalizedComposerContactSearchTerm = createSelector(
|
export const getComposableGroups = createSelector(
|
||||||
getComposerContactSearchTerm,
|
getConversationLookup,
|
||||||
|
(conversationLookup: ConversationLookupType): Array<ConversationType> =>
|
||||||
|
Object.values(conversationLookup).filter(
|
||||||
|
conversation =>
|
||||||
|
conversation.type === 'group' && canComposeConversation(conversation)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const getNormalizedComposerConversationSearchTerm = createSelector(
|
||||||
|
getComposerConversationSearchTerm,
|
||||||
(searchTerm: string): string => searchTerm.trim()
|
(searchTerm: string): string => searchTerm.trim()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -372,8 +386,8 @@ const getNoteToSelfTitle = createSelector(getIntl, (i18n: LocalizerType) =>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getComposeContacts = createSelector(
|
export const getComposeContacts = createSelector(
|
||||||
getNormalizedComposerContactSearchTerm,
|
getNormalizedComposerConversationSearchTerm,
|
||||||
getContacts,
|
getComposableContacts,
|
||||||
getMe,
|
getMe,
|
||||||
getNoteToSelfTitle,
|
getNoteToSelfTitle,
|
||||||
(
|
(
|
||||||
|
@ -382,7 +396,7 @@ export const getComposeContacts = createSelector(
|
||||||
noteToSelf: ConversationType,
|
noteToSelf: ConversationType,
|
||||||
noteToSelfTitle: string
|
noteToSelfTitle: string
|
||||||
): Array<ConversationType> => {
|
): Array<ConversationType> => {
|
||||||
const result: Array<ConversationType> = filterAndSortContacts(
|
const result: Array<ConversationType> = filterAndSortConversations(
|
||||||
contacts,
|
contacts,
|
||||||
searchTerm
|
searchTerm
|
||||||
);
|
);
|
||||||
|
@ -393,10 +407,21 @@ export const getComposeContacts = createSelector(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const getComposeGroups = createSelector(
|
||||||
|
getNormalizedComposerConversationSearchTerm,
|
||||||
|
getComposableGroups,
|
||||||
|
(
|
||||||
|
searchTerm: string,
|
||||||
|
groups: Array<ConversationType>
|
||||||
|
): Array<ConversationType> => {
|
||||||
|
return filterAndSortConversations(groups, searchTerm);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export const getCandidateContactsForNewGroup = createSelector(
|
export const getCandidateContactsForNewGroup = createSelector(
|
||||||
getContacts,
|
getComposableContacts,
|
||||||
getNormalizedComposerContactSearchTerm,
|
getNormalizedComposerConversationSearchTerm,
|
||||||
filterAndSortContacts
|
filterAndSortConversations
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getCantAddContactForModal = createSelector(
|
export const getCantAddContactForModal = createSelector(
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
StateProps,
|
StateProps,
|
||||||
} from '../../components/conversation/conversation-details/ConversationDetails';
|
} from '../../components/conversation/conversation-details/ConversationDetails';
|
||||||
import {
|
import {
|
||||||
getContacts,
|
getComposableContacts,
|
||||||
getConversationSelector,
|
getConversationSelector,
|
||||||
} from '../selectors/conversations';
|
} from '../selectors/conversations';
|
||||||
import { getIntl } from '../selectors/user';
|
import { getIntl } from '../selectors/user';
|
||||||
|
@ -50,7 +50,7 @@ const mapStateToProps = (
|
||||||
? conversation.canEditGroupInfo
|
? conversation.canEditGroupInfo
|
||||||
: false;
|
: false;
|
||||||
const isAdmin = Boolean(conversation?.areWeAdmin);
|
const isAdmin = Boolean(conversation?.areWeAdmin);
|
||||||
const candidateContactsToAdd = getContacts(state);
|
const candidateContactsToAdd = getComposableContacts(state);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...props,
|
...props,
|
||||||
|
|
|
@ -19,10 +19,11 @@ import {
|
||||||
getCandidateContactsForNewGroup,
|
getCandidateContactsForNewGroup,
|
||||||
getCantAddContactForModal,
|
getCantAddContactForModal,
|
||||||
getComposeContacts,
|
getComposeContacts,
|
||||||
|
getComposeGroups,
|
||||||
getComposeGroupAvatar,
|
getComposeGroupAvatar,
|
||||||
getComposeGroupName,
|
getComposeGroupName,
|
||||||
getComposeSelectedContacts,
|
getComposeSelectedContacts,
|
||||||
getComposerContactSearchTerm,
|
getComposerConversationSearchTerm,
|
||||||
getComposerStep,
|
getComposerStep,
|
||||||
getLeftPaneLists,
|
getLeftPaneLists,
|
||||||
getMaximumGroupSizeModalState,
|
getMaximumGroupSizeModalState,
|
||||||
|
@ -96,8 +97,9 @@ const getModeSpecificProps = (
|
||||||
return {
|
return {
|
||||||
mode: LeftPaneMode.Compose,
|
mode: LeftPaneMode.Compose,
|
||||||
composeContacts: getComposeContacts(state),
|
composeContacts: getComposeContacts(state),
|
||||||
|
composeGroups: getComposeGroups(state),
|
||||||
regionCode: getRegionCode(state),
|
regionCode: getRegionCode(state),
|
||||||
searchTerm: getComposerContactSearchTerm(state),
|
searchTerm: getComposerConversationSearchTerm(state),
|
||||||
};
|
};
|
||||||
case ComposerStep.ChooseGroupMembers:
|
case ComposerStep.ChooseGroupMembers:
|
||||||
return {
|
return {
|
||||||
|
@ -109,7 +111,7 @@ const getModeSpecificProps = (
|
||||||
OneTimeModalState.Showing,
|
OneTimeModalState.Showing,
|
||||||
isShowingMaximumGroupSizeModal:
|
isShowingMaximumGroupSizeModal:
|
||||||
getMaximumGroupSizeModalState(state) === OneTimeModalState.Showing,
|
getMaximumGroupSizeModalState(state) === OneTimeModalState.Showing,
|
||||||
searchTerm: getComposerContactSearchTerm(state),
|
searchTerm: getComposerConversationSearchTerm(state),
|
||||||
selectedContacts: getComposeSelectedContacts(state),
|
selectedContacts: getComposeSelectedContacts(state),
|
||||||
};
|
};
|
||||||
case ComposerStep.SetGroupMetadata:
|
case ComposerStep.SetGroupMetadata:
|
||||||
|
|
|
@ -16,10 +16,11 @@ import {
|
||||||
getCandidateContactsForNewGroup,
|
getCandidateContactsForNewGroup,
|
||||||
getCantAddContactForModal,
|
getCantAddContactForModal,
|
||||||
getComposeContacts,
|
getComposeContacts,
|
||||||
|
getComposeGroups,
|
||||||
getComposeGroupAvatar,
|
getComposeGroupAvatar,
|
||||||
getComposeGroupName,
|
getComposeGroupName,
|
||||||
getComposeSelectedContacts,
|
getComposeSelectedContacts,
|
||||||
getComposerContactSearchTerm,
|
getComposerConversationSearchTerm,
|
||||||
getComposerStep,
|
getComposerStep,
|
||||||
getConversationSelector,
|
getConversationSelector,
|
||||||
getInvitedContactsForNewlyCreatedGroup,
|
getInvitedContactsForNewlyCreatedGroup,
|
||||||
|
@ -271,7 +272,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation as const,
|
step: ComposerStep.StartDirectConversation as const,
|
||||||
contactSearchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -287,7 +288,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: 'foo',
|
searchTerm: 'foo',
|
||||||
selectedConversationIds: ['abc'],
|
selectedConversationIds: ['abc'],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -337,7 +338,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -398,7 +399,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -449,7 +450,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#getComposeContacts', () => {
|
describe('#getComposeContacts', () => {
|
||||||
const getRootState = (contactSearchTerm = ''): StateType => {
|
const getRootState = (searchTerm = ''): StateType => {
|
||||||
const rootState = getEmptyRootState();
|
const rootState = getEmptyRootState();
|
||||||
return {
|
return {
|
||||||
...rootState,
|
...rootState,
|
||||||
|
@ -463,7 +464,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
},
|
},
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm,
|
searchTerm,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
|
@ -474,10 +475,8 @@ describe('both/state/selectors/conversations', () => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRootStateWithConverastions = (
|
const getRootStateWithConversations = (searchTerm = ''): StateType => {
|
||||||
contactSearchTerm = ''
|
const result = getRootState(searchTerm);
|
||||||
): StateType => {
|
|
||||||
const result = getRootState(contactSearchTerm);
|
|
||||||
Object.assign(result.conversations.conversationLookup, {
|
Object.assign(result.conversations.conversationLookup, {
|
||||||
'convo-1': {
|
'convo-1': {
|
||||||
...getDefaultConversation('convo-1'),
|
...getDefaultConversation('convo-1'),
|
||||||
|
@ -534,7 +533,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns contacts with Note to Self at the end when there is no search term', () => {
|
it('returns contacts with Note to Self at the end when there is no search term', () => {
|
||||||
const state = getRootStateWithConverastions();
|
const state = getRootStateWithConversations();
|
||||||
const result = getComposeContacts(state);
|
const result = getComposeContacts(state);
|
||||||
|
|
||||||
const ids = result.map(contact => contact.id);
|
const ids = result.map(contact => contact.id);
|
||||||
|
@ -547,7 +546,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can search for contacts', () => {
|
it('can search for contacts', () => {
|
||||||
const state = getRootStateWithConverastions('in system');
|
const state = getRootStateWithConversations('in system');
|
||||||
const result = getComposeContacts(state);
|
const result = getComposeContacts(state);
|
||||||
|
|
||||||
const ids = result.map(contact => contact.id);
|
const ids = result.map(contact => contact.id);
|
||||||
|
@ -556,8 +555,90 @@ describe('both/state/selectors/conversations', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#getComposeGroups', () => {
|
||||||
|
const getState = (searchTerm = ''): StateType => {
|
||||||
|
const rootState = getEmptyRootState();
|
||||||
|
return {
|
||||||
|
...rootState,
|
||||||
|
conversations: {
|
||||||
|
...getEmptyState(),
|
||||||
|
conversationLookup: {
|
||||||
|
'our-conversation-id': {
|
||||||
|
...getDefaultConversation('our-conversation-id'),
|
||||||
|
isMe: true,
|
||||||
|
},
|
||||||
|
'convo-1': {
|
||||||
|
...getDefaultConversation('convo-1'),
|
||||||
|
name: 'In System Contacts',
|
||||||
|
title: 'Should be dropped (contact)',
|
||||||
|
},
|
||||||
|
'convo-2': {
|
||||||
|
...getDefaultConversation('convo-2'),
|
||||||
|
title: 'Should be dropped (contact)',
|
||||||
|
},
|
||||||
|
'convo-3': {
|
||||||
|
...getDefaultConversation('convo-3'),
|
||||||
|
type: 'group',
|
||||||
|
name: 'Hello World',
|
||||||
|
title: 'Hello World',
|
||||||
|
},
|
||||||
|
'convo-4': {
|
||||||
|
...getDefaultConversation('convo-4'),
|
||||||
|
type: 'group',
|
||||||
|
isBlocked: true,
|
||||||
|
title: 'Should be dropped (blocked)',
|
||||||
|
},
|
||||||
|
'convo-5': {
|
||||||
|
...getDefaultConversation('convo-5'),
|
||||||
|
type: 'group',
|
||||||
|
title: 'Unknown Group',
|
||||||
|
},
|
||||||
|
'convo-6': {
|
||||||
|
...getDefaultConversation('convo-6'),
|
||||||
|
type: 'group',
|
||||||
|
name: 'Signal',
|
||||||
|
title: 'Signal',
|
||||||
|
},
|
||||||
|
'convo-7': {
|
||||||
|
...getDefaultConversation('convo-7'),
|
||||||
|
profileSharing: false,
|
||||||
|
type: 'group',
|
||||||
|
name: 'Signal Fake',
|
||||||
|
title: 'Signal Fake',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
composer: {
|
||||||
|
step: ComposerStep.StartDirectConversation,
|
||||||
|
searchTerm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
...rootState.user,
|
||||||
|
ourConversationId: 'our-conversation-id',
|
||||||
|
i18n,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
it('can search for groups', () => {
|
||||||
|
const state = getState('hello');
|
||||||
|
const result = getComposeGroups(state);
|
||||||
|
|
||||||
|
const ids = result.map(group => group.id);
|
||||||
|
assert.deepEqual(ids, ['convo-3']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not return unknown groups when getting all groups (no search term)', () => {
|
||||||
|
const state = getState();
|
||||||
|
const result = getComposeGroups(state);
|
||||||
|
|
||||||
|
const ids = result.map(group => group.id);
|
||||||
|
assert.deepEqual(ids, ['convo-3', 'convo-6', 'convo-7']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('#getCandidateContactsForNewGroup', () => {
|
describe('#getCandidateContactsForNewGroup', () => {
|
||||||
const getRootState = (contactSearchTerm = ''): StateType => {
|
const getRootState = (searchTerm = ''): StateType => {
|
||||||
const rootState = getEmptyRootState();
|
const rootState = getEmptyRootState();
|
||||||
return {
|
return {
|
||||||
...rootState,
|
...rootState,
|
||||||
|
@ -603,7 +684,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
},
|
},
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm,
|
searchTerm,
|
||||||
selectedConversationIds: ['abc'],
|
selectedConversationIds: ['abc'],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -648,7 +729,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -663,7 +744,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -687,7 +768,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
conversationLookup: { abc123: conversation },
|
conversationLookup: { abc123: conversation },
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: 'abc123',
|
cantAddContactIdForModal: 'abc123',
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -702,16 +783,16 @@ describe('both/state/selectors/conversations', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#getComposerContactSearchTerm', () => {
|
describe('#getComposerConversationSearchTerm', () => {
|
||||||
it("returns the composer's contact search term", () => {
|
it("returns the composer's contact search term", () => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
getComposerContactSearchTerm({
|
getComposerConversationSearchTerm({
|
||||||
...getEmptyRootState(),
|
...getEmptyRootState(),
|
||||||
conversations: {
|
conversations: {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
@ -966,7 +1047,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
contactSearchTerm: 'to be cleared',
|
searchTerm: 'to be cleared',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.Showing,
|
maximumGroupSizeModalState: OneTimeModalState.Showing,
|
||||||
|
@ -991,7 +1072,7 @@ describe('both/state/selectors/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
contactSearchTerm: 'to be cleared',
|
searchTerm: 'to be cleared',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import { getDefaultConversation } from '../helpers/getDefaultConversation';
|
import { getDefaultConversation } from '../helpers/getDefaultConversation';
|
||||||
|
|
||||||
import { filterAndSortContacts } from '../../util/filterAndSortContacts';
|
import { filterAndSortConversations } from '../../util/filterAndSortConversations';
|
||||||
|
|
||||||
describe('filterAndSortContacts', () => {
|
describe('filterAndSortConversations', () => {
|
||||||
const conversations = [
|
const conversations = [
|
||||||
getDefaultConversation({
|
getDefaultConversation({
|
||||||
title: '+16505551234',
|
title: '+16505551234',
|
||||||
|
@ -34,7 +34,7 @@ describe('filterAndSortContacts', () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
it('without a search term, sorts conversations by title (but puts no-name contacts at the bottom)', () => {
|
it('without a search term, sorts conversations by title (but puts no-name contacts at the bottom)', () => {
|
||||||
const titles = filterAndSortContacts(conversations, '').map(
|
const titles = filterAndSortConversations(conversations, '').map(
|
||||||
contact => contact.title
|
contact => contact.title
|
||||||
);
|
);
|
||||||
assert.deepEqual(titles, [
|
assert.deepEqual(titles, [
|
||||||
|
@ -47,14 +47,14 @@ describe('filterAndSortContacts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can search for contacts by title', () => {
|
it('can search for contacts by title', () => {
|
||||||
const titles = filterAndSortContacts(conversations, 'belind').map(
|
const titles = filterAndSortConversations(conversations, 'belind').map(
|
||||||
contact => contact.title
|
contact => contact.title
|
||||||
);
|
);
|
||||||
assert.sameMembers(titles, ['Belinda Beetle', 'Belinda Zephyr']);
|
assert.sameMembers(titles, ['Belinda Beetle', 'Belinda Zephyr']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can search for contacts by phone number (and puts no-name contacts at the bottom)', () => {
|
it('can search for contacts by phone number (and puts no-name contacts at the bottom)', () => {
|
||||||
const titles = filterAndSortContacts(conversations, '650555').map(
|
const titles = filterAndSortConversations(conversations, '650555').map(
|
||||||
contact => contact.title
|
contact => contact.title
|
||||||
);
|
);
|
||||||
assert.sameMembers(titles, ['Carlos Santana', '+16505551234']);
|
assert.sameMembers(titles, ['Carlos Santana', '+16505551234']);
|
|
@ -467,7 +467,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -530,7 +530,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: 'abc123',
|
cantAddContactIdForModal: 'abc123',
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -556,7 +556,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: 'abc123',
|
cantAddContactIdForModal: 'abc123',
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.Showing,
|
maximumGroupSizeModalState: OneTimeModalState.Showing,
|
||||||
|
@ -581,7 +581,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: 'abc123',
|
cantAddContactIdForModal: 'abc123',
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -601,7 +601,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: 'abc123',
|
cantAddContactIdForModal: 'abc123',
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.Shown,
|
maximumGroupSizeModalState: OneTimeModalState.Shown,
|
||||||
|
@ -623,7 +623,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: 'abc123',
|
cantAddContactIdForModal: 'abc123',
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -648,7 +648,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: 'abc123',
|
cantAddContactIdForModal: 'abc123',
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -668,7 +668,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: 'abc123',
|
cantAddContactIdForModal: 'abc123',
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1232,7 +1232,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation as const,
|
step: ComposerStep.StartDirectConversation as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const action = setComposeSearchTerm('foo bar');
|
const action = setComposeSearchTerm('foo bar');
|
||||||
|
@ -1240,7 +1240,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
|
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1306,7 +1306,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation as const,
|
step: ComposerStep.StartDirectConversation as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const action = showArchivedConversations();
|
const action = showArchivedConversations();
|
||||||
|
@ -1344,7 +1344,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation as const,
|
step: ComposerStep.StartDirectConversation as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const action = showInbox();
|
const action = showInbox();
|
||||||
|
@ -1361,7 +1361,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation as const,
|
step: ComposerStep.StartDirectConversation as const,
|
||||||
contactSearchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const action = startComposing();
|
const action = startComposing();
|
||||||
|
@ -1370,7 +1370,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1379,7 +1379,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
contactSearchTerm: 'to be cleared',
|
searchTerm: 'to be cleared',
|
||||||
groupAvatar: undefined,
|
groupAvatar: undefined,
|
||||||
groupName: '',
|
groupName: '',
|
||||||
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
maximumGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1394,7 +1394,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1418,7 +1418,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1430,7 +1430,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1445,7 +1445,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.StartDirectConversation,
|
step: ComposerStep.StartDirectConversation,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1456,7 +1456,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.StartDirectConversation as const,
|
step: ComposerStep.StartDirectConversation as const,
|
||||||
contactSearchTerm: 'to be cleared',
|
searchTerm: 'to be cleared',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const action = showChooseGroupMembers();
|
const action = showChooseGroupMembers();
|
||||||
|
@ -1465,7 +1465,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1480,7 +1480,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1516,7 +1516,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1534,7 +1534,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1555,7 +1555,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
assert.isFalse(result.showArchived);
|
assert.isFalse(result.showArchived);
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1572,7 +1572,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
selectedConversationIds: ['abc', 'def'],
|
selectedConversationIds: ['abc', 'def'],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1601,7 +1601,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
selectedConversationIds: ['abc', 'def'],
|
selectedConversationIds: ['abc', 'def'],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1681,7 +1681,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1695,7 +1695,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
|
|
||||||
assert.deepEqual(two.composer, {
|
assert.deepEqual(two.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: ['abc', 'def'],
|
selectedConversationIds: ['abc', 'def'],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1710,7 +1710,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: ['abc', 'def'],
|
selectedConversationIds: ['abc', 'def'],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1724,7 +1724,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
|
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: ['def'],
|
selectedConversationIds: ['def'],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1742,7 +1742,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: oldSelectedConversationIds,
|
selectedConversationIds: oldSelectedConversationIds,
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1756,7 +1756,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
|
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [...oldSelectedConversationIds, newUuid],
|
selectedConversationIds: [...oldSelectedConversationIds, newUuid],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.Showing,
|
recommendedGroupSizeModalState: OneTimeModalState.Showing,
|
||||||
|
@ -1774,7 +1774,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: oldSelectedConversationIds,
|
selectedConversationIds: oldSelectedConversationIds,
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
||||||
|
@ -1788,7 +1788,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
|
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [...oldSelectedConversationIds, newUuid],
|
selectedConversationIds: [...oldSelectedConversationIds, newUuid],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
||||||
|
@ -1808,7 +1808,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1831,7 +1831,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: oldSelectedConversationIds,
|
selectedConversationIds: oldSelectedConversationIds,
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
||||||
|
@ -1845,7 +1845,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
|
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [...oldSelectedConversationIds, newUuid],
|
selectedConversationIds: [...oldSelectedConversationIds, newUuid],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
||||||
|
@ -1863,7 +1863,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: oldSelectedConversationIds,
|
selectedConversationIds: oldSelectedConversationIds,
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
||||||
|
@ -1877,7 +1877,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
|
|
||||||
assert.deepEqual(result.composer, {
|
assert.deepEqual(result.composer, {
|
||||||
step: ComposerStep.ChooseGroupMembers,
|
step: ComposerStep.ChooseGroupMembers,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [...oldSelectedConversationIds, newUuid],
|
selectedConversationIds: [...oldSelectedConversationIds, newUuid],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
recommendedGroupSizeModalState: OneTimeModalState.Shown,
|
||||||
|
@ -1892,7 +1892,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: times(1000, () => uuid()),
|
selectedConversationIds: times(1000, () => uuid()),
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1919,7 +1919,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
@ -1945,7 +1945,7 @@ describe('both/state/ducks/conversations', () => {
|
||||||
...getEmptyState(),
|
...getEmptyState(),
|
||||||
composer: {
|
composer: {
|
||||||
step: ComposerStep.ChooseGroupMembers as const,
|
step: ComposerStep.ChooseGroupMembers as const,
|
||||||
contactSearchTerm: '',
|
searchTerm: '',
|
||||||
selectedConversationIds: [],
|
selectedConversationIds: [],
|
||||||
cantAddContactIdForModal: undefined,
|
cantAddContactIdForModal: undefined,
|
||||||
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
recommendedGroupSizeModalState: OneTimeModalState.NeverShown,
|
||||||
|
|
|
@ -11,7 +11,7 @@ import * as remoteConfig from '../../../RemoteConfig';
|
||||||
import { LeftPaneComposeHelper } from '../../../components/leftPane/LeftPaneComposeHelper';
|
import { LeftPaneComposeHelper } from '../../../components/leftPane/LeftPaneComposeHelper';
|
||||||
|
|
||||||
describe('LeftPaneComposeHelper', () => {
|
describe('LeftPaneComposeHelper', () => {
|
||||||
const fakeContact = () => ({
|
const fakeConvo = () => ({
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
title: uuid(),
|
title: uuid(),
|
||||||
type: 'direct' as const,
|
type: 'direct' as const,
|
||||||
|
@ -40,6 +40,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
const showInbox = sinon.fake();
|
const showInbox = sinon.fake();
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
|
@ -53,6 +54,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
new LeftPaneComposeHelper({
|
new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
|
@ -63,7 +65,8 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
it('returns the number of contacts + 2 (for the "new group" button and header) if not searching', () => {
|
it('returns the number of contacts + 2 (for the "new group" button and header) if not searching', () => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
new LeftPaneComposeHelper({
|
new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
|
@ -71,10 +74,23 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the number of contacts if searching, but not for a phone number', () => {
|
it('returns the number of contacts + number of groups + 3 (for the "new group" button and the headers) if not searching', () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
new LeftPaneComposeHelper({
|
||||||
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [fakeConvo(), fakeConvo()],
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: '',
|
||||||
|
}).getRowCount(),
|
||||||
|
7
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the number of conversations + the headers, but not for a phone number', () => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
new LeftPaneComposeHelper({
|
new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
|
@ -82,11 +98,21 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
new LeftPaneComposeHelper({
|
new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
2
|
3
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
new LeftPaneComposeHelper({
|
||||||
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [fakeConvo()],
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'foo bar',
|
||||||
|
}).getRowCount(),
|
||||||
|
5
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -94,6 +120,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
new LeftPaneComposeHelper({
|
new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '+16505551234',
|
searchTerm: '+16505551234',
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
|
@ -104,7 +131,8 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
it('returns the number of contacts + 2 (for the "Start new conversation" button and header) if searching for a phone number', () => {
|
it('returns the number of contacts + 2 (for the "Start new conversation" button and header) if searching for a phone number', () => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
new LeftPaneComposeHelper({
|
new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '+16505551234',
|
searchTerm: '+16505551234',
|
||||||
}).getRowCount(),
|
}).getRowCount(),
|
||||||
|
@ -117,6 +145,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
it('returns a "new group" button if not searching and there are no contacts', () => {
|
it('returns a "new group" button if not searching and there are no contacts', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
|
@ -128,9 +157,10 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a "new group" button, a header, and contacts if not searching', () => {
|
it('returns a "new group" button, a header, and contacts if not searching', () => {
|
||||||
const composeContacts = [fakeContact(), fakeContact()];
|
const composeContacts = [fakeConvo(), fakeConvo()];
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts,
|
composeContacts,
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
|
@ -152,6 +182,45 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns a "new group" button, a header, contacts, groups header, and groups -- if not searching', () => {
|
||||||
|
const composeContacts = [fakeConvo(), fakeConvo()];
|
||||||
|
const composeGroups = [fakeConvo(), fakeConvo()];
|
||||||
|
const helper = new LeftPaneComposeHelper({
|
||||||
|
composeContacts,
|
||||||
|
composeGroups,
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.deepEqual(helper.getRow(0), {
|
||||||
|
type: RowType.CreateNewGroup,
|
||||||
|
});
|
||||||
|
assert.deepEqual(helper.getRow(1), {
|
||||||
|
type: RowType.Header,
|
||||||
|
i18nKey: 'contactsHeader',
|
||||||
|
});
|
||||||
|
assert.deepEqual(helper.getRow(2), {
|
||||||
|
type: RowType.Contact,
|
||||||
|
contact: composeContacts[0],
|
||||||
|
});
|
||||||
|
assert.deepEqual(helper.getRow(3), {
|
||||||
|
type: RowType.Contact,
|
||||||
|
contact: composeContacts[1],
|
||||||
|
});
|
||||||
|
assert.deepEqual(helper.getRow(4), {
|
||||||
|
type: RowType.Header,
|
||||||
|
i18nKey: 'groupsHeader',
|
||||||
|
});
|
||||||
|
assert.deepEqual(helper.getRow(5), {
|
||||||
|
type: RowType.Conversation,
|
||||||
|
conversation: composeGroups[0],
|
||||||
|
});
|
||||||
|
assert.deepEqual(helper.getRow(6), {
|
||||||
|
type: RowType.Conversation,
|
||||||
|
conversation: composeGroups[1],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("doesn't let you create new groups if storage service write is disabled", () => {
|
it("doesn't let you create new groups if storage service write is disabled", () => {
|
||||||
remoteConfigStub
|
remoteConfigStub
|
||||||
.withArgs('desktop.storage')
|
.withArgs('desktop.storage')
|
||||||
|
@ -162,6 +231,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
assert.isUndefined(
|
assert.isUndefined(
|
||||||
new LeftPaneComposeHelper({
|
new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
}).getRow(0)
|
}).getRow(0)
|
||||||
|
@ -176,6 +246,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
assert.isUndefined(
|
assert.isUndefined(
|
||||||
new LeftPaneComposeHelper({
|
new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
}).getRow(0)
|
}).getRow(0)
|
||||||
|
@ -185,6 +256,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
it('returns no rows if searching and there are no results', () => {
|
it('returns no rows if searching and there are no results', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
});
|
});
|
||||||
|
@ -194,18 +266,19 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns one row per contact if searching', () => {
|
it('returns one row per contact if searching', () => {
|
||||||
const composeContacts = [fakeContact(), fakeContact()];
|
const composeContacts = [fakeConvo(), fakeConvo()];
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts,
|
composeContacts,
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
contact: composeContacts[0],
|
contact: composeContacts[0],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(2), {
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
contact: composeContacts[1],
|
contact: composeContacts[1],
|
||||||
});
|
});
|
||||||
|
@ -214,6 +287,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
it('returns a "start new conversation" row if searching for a phone number and there are no results', () => {
|
it('returns a "start new conversation" row if searching for a phone number and there are no results', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [],
|
composeContacts: [],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '+16505551234',
|
searchTerm: '+16505551234',
|
||||||
});
|
});
|
||||||
|
@ -226,9 +300,10 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a "start new conversation" row, a header, and contacts if searching for a phone number', () => {
|
it('returns a "start new conversation" row, a header, and contacts if searching for a phone number', () => {
|
||||||
const composeContacts = [fakeContact(), fakeContact()];
|
const composeContacts = [fakeConvo(), fakeConvo()];
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts,
|
composeContacts,
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '+16505551234',
|
searchTerm: '+16505551234',
|
||||||
});
|
});
|
||||||
|
@ -255,7 +330,8 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
describe('getConversationAndMessageAtIndex', () => {
|
describe('getConversationAndMessageAtIndex', () => {
|
||||||
it('returns undefined because keyboard shortcuts are not supported', () => {
|
it('returns undefined because keyboard shortcuts are not supported', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
});
|
});
|
||||||
|
@ -267,7 +343,8 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
describe('getConversationAndMessageInDirection', () => {
|
describe('getConversationAndMessageInDirection', () => {
|
||||||
it('returns undefined because keyboard shortcuts are not supported', () => {
|
it('returns undefined because keyboard shortcuts are not supported', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
});
|
});
|
||||||
|
@ -285,21 +362,24 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
describe('shouldRecomputeRowHeights', () => {
|
describe('shouldRecomputeRowHeights', () => {
|
||||||
it('returns false if going from "no header" to "no header"', () => {
|
it('returns false if going from "no header" to "no header"', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isFalse(
|
assert.isFalse(
|
||||||
helper.shouldRecomputeRowHeights({
|
helper.shouldRecomputeRowHeights({
|
||||||
composeContacts: [fakeContact()],
|
composeContacts: [fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert.isFalse(
|
assert.isFalse(
|
||||||
helper.shouldRecomputeRowHeights({
|
helper.shouldRecomputeRowHeights({
|
||||||
composeContacts: [fakeContact(), fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'bing bong',
|
searchTerm: 'bing bong',
|
||||||
})
|
})
|
||||||
|
@ -308,21 +388,24 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
|
|
||||||
it('returns false if going from "has header" to "has header"', () => {
|
it('returns false if going from "has header" to "has header"', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isFalse(
|
assert.isFalse(
|
||||||
helper.shouldRecomputeRowHeights({
|
helper.shouldRecomputeRowHeights({
|
||||||
composeContacts: [fakeContact()],
|
composeContacts: [fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert.isFalse(
|
assert.isFalse(
|
||||||
helper.shouldRecomputeRowHeights({
|
helper.shouldRecomputeRowHeights({
|
||||||
composeContacts: [fakeContact()],
|
composeContacts: [fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '+16505559876',
|
searchTerm: '+16505559876',
|
||||||
})
|
})
|
||||||
|
@ -331,21 +414,24 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
|
|
||||||
it('returns true if going from "no header" to "has header"', () => {
|
it('returns true if going from "no header" to "has header"', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isTrue(
|
assert.isTrue(
|
||||||
helper.shouldRecomputeRowHeights({
|
helper.shouldRecomputeRowHeights({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert.isTrue(
|
assert.isTrue(
|
||||||
helper.shouldRecomputeRowHeights({
|
helper.shouldRecomputeRowHeights({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '+16505551234',
|
searchTerm: '+16505551234',
|
||||||
})
|
})
|
||||||
|
@ -354,18 +440,72 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
|
|
||||||
it('returns true if going from "has header" to "no header"', () => {
|
it('returns true if going from "has header" to "no header"', () => {
|
||||||
const helper = new LeftPaneComposeHelper({
|
const helper = new LeftPaneComposeHelper({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.isTrue(
|
assert.isTrue(
|
||||||
helper.shouldRecomputeRowHeights({
|
helper.shouldRecomputeRowHeights({
|
||||||
composeContacts: [fakeContact(), fakeContact()],
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
regionCode: 'US',
|
regionCode: 'US',
|
||||||
searchTerm: 'foo bar',
|
searchTerm: 'foo bar',
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be true if going from contact to group or vice versa', () => {
|
||||||
|
const helperContacts = new LeftPaneComposeHelper({
|
||||||
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'foo bar',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.isTrue(
|
||||||
|
helperContacts.shouldRecomputeRowHeights({
|
||||||
|
composeContacts: [],
|
||||||
|
composeGroups: [fakeConvo(), fakeConvo()],
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'foo bar',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const helperGroups = new LeftPaneComposeHelper({
|
||||||
|
composeContacts: [],
|
||||||
|
composeGroups: [fakeConvo(), fakeConvo()],
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'foo bar',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.isTrue(
|
||||||
|
helperGroups.shouldRecomputeRowHeights({
|
||||||
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [],
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'foo bar',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be true if the headers are in different row indices as before', () => {
|
||||||
|
const helperContacts = new LeftPaneComposeHelper({
|
||||||
|
composeContacts: [fakeConvo(), fakeConvo()],
|
||||||
|
composeGroups: [fakeConvo()],
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'soup',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.isTrue(
|
||||||
|
helperContacts.shouldRecomputeRowHeights({
|
||||||
|
composeContacts: [fakeConvo()],
|
||||||
|
composeGroups: [fakeConvo(), fakeConvo()],
|
||||||
|
regionCode: 'US',
|
||||||
|
searchTerm: 'sandwich',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,17 +28,17 @@ const FUSE_OPTIONS: FuseOptions<ConversationType> = {
|
||||||
|
|
||||||
const collator = new Intl.Collator();
|
const collator = new Intl.Collator();
|
||||||
|
|
||||||
export function filterAndSortContacts(
|
export function filterAndSortConversations(
|
||||||
contacts: ReadonlyArray<ConversationType>,
|
conversations: ReadonlyArray<ConversationType>,
|
||||||
searchTerm: string
|
searchTerm: string
|
||||||
): Array<ConversationType> {
|
): Array<ConversationType> {
|
||||||
if (searchTerm.length) {
|
if (searchTerm.length) {
|
||||||
return new Fuse<ConversationType>(contacts, FUSE_OPTIONS).search(
|
return new Fuse<ConversationType>(conversations, FUSE_OPTIONS).search(
|
||||||
searchTerm
|
searchTerm
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return contacts.concat().sort((a, b) => {
|
return conversations.concat().sort((a, b) => {
|
||||||
const aHasName = hasName(a);
|
const aHasName = hasName(a);
|
||||||
const bHasName = hasName(b);
|
const bHasName = hasName(b);
|
||||||
|
|
|
@ -34,6 +34,7 @@ import {
|
||||||
} from './sessionTranslation';
|
} from './sessionTranslation';
|
||||||
import * as zkgroup from './zkgroup';
|
import * as zkgroup from './zkgroup';
|
||||||
import { StartupQueue } from './StartupQueue';
|
import { StartupQueue } from './StartupQueue';
|
||||||
|
import { postLinkExperience } from './postLinkExperience';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
GoogleChrome,
|
GoogleChrome,
|
||||||
|
@ -58,6 +59,7 @@ export {
|
||||||
mapToSupportLocale,
|
mapToSupportLocale,
|
||||||
missingCaseError,
|
missingCaseError,
|
||||||
parseRemoteClientExpiration,
|
parseRemoteClientExpiration,
|
||||||
|
postLinkExperience,
|
||||||
queueUpdateMessage,
|
queueUpdateMessage,
|
||||||
saveNewMessageBatcher,
|
saveNewMessageBatcher,
|
||||||
setBatchingStrategy,
|
setBatchingStrategy,
|
||||||
|
|
|
@ -645,7 +645,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('.call-manager-placeholder').append(this.callManagerView.el);",
|
"line": " this.$('.call-manager-placeholder').append(this.callManagerView.el);",
|
||||||
"lineNumber": 127,
|
"lineNumber": 128,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Adding sub-view to DOM"
|
"reasonDetail": "Adding sub-view to DOM"
|
||||||
|
@ -654,7 +654,7 @@
|
||||||
"rule": "jQuery-append(",
|
"rule": "jQuery-append(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('.call-manager-placeholder').append(this.callManagerView.el);",
|
"line": " this.$('.call-manager-placeholder').append(this.callManagerView.el);",
|
||||||
"lineNumber": 127,
|
"lineNumber": 128,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Adding sub-view to DOM"
|
"reasonDetail": "Adding sub-view to DOM"
|
||||||
|
@ -663,7 +663,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('.left-pane-placeholder').append(this.leftPaneView.el);",
|
"line": " this.$('.left-pane-placeholder').append(this.leftPaneView.el);",
|
||||||
"lineNumber": 138,
|
"lineNumber": 139,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Adding sub-view to DOM"
|
"reasonDetail": "Adding sub-view to DOM"
|
||||||
|
@ -672,7 +672,7 @@
|
||||||
"rule": "jQuery-append(",
|
"rule": "jQuery-append(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('.left-pane-placeholder').append(this.leftPaneView.el);",
|
"line": " this.$('.left-pane-placeholder').append(this.leftPaneView.el);",
|
||||||
"lineNumber": 138,
|
"lineNumber": 139,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Adding sub-view to DOM"
|
"reasonDetail": "Adding sub-view to DOM"
|
||||||
|
@ -681,7 +681,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " if (e && this.$(e.target).closest('.placeholder').length) {",
|
"line": " if (e && this.$(e.target).closest('.placeholder').length) {",
|
||||||
"lineNumber": 191,
|
"lineNumber": 192,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, read-only access"
|
"reasonDetail": "Static selector, read-only access"
|
||||||
|
@ -690,15 +690,6 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('#header, .gutter').addClass('inactive');",
|
"line": " this.$('#header, .gutter').addClass('inactive');",
|
||||||
"lineNumber": 195,
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, adding or removing classes"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/inbox_view.js",
|
|
||||||
"line": " this.$('.conversation-stack').removeClass('inactive');",
|
|
||||||
"lineNumber": 196,
|
"lineNumber": 196,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
|
@ -707,8 +698,8 @@
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('.conversation-stack').addClass('inactive');",
|
"line": " this.$('.conversation-stack').removeClass('inactive');",
|
||||||
"lineNumber": 199,
|
"lineNumber": 197,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, adding or removing classes"
|
"reasonDetail": "Static selector, adding or removing classes"
|
||||||
|
@ -716,7 +707,7 @@
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('#header, .gutter').removeClass('inactive');",
|
"line": " this.$('.conversation-stack').addClass('inactive');",
|
||||||
"lineNumber": 200,
|
"lineNumber": 200,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
|
@ -725,17 +716,26 @@
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('.conversation:first .menu').trigger('close');",
|
"line": " this.$('#header, .gutter').removeClass('inactive');",
|
||||||
"lineNumber": 201,
|
"lineNumber": 201,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
|
"reasonDetail": "Static selector, adding or removing classes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": "jQuery-$(",
|
||||||
|
"path": "js/views/inbox_view.js",
|
||||||
|
"line": " this.$('.conversation:first .menu').trigger('close');",
|
||||||
|
"lineNumber": 202,
|
||||||
|
"reasonCategory": "usageTrusted",
|
||||||
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, trigging DOM event"
|
"reasonDetail": "Static selector, trigging DOM event"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " if (e && this.$(e.target).closest('.capture-audio').length > 0) {",
|
"line": " if (e && this.$(e.target).closest('.capture-audio').length > 0) {",
|
||||||
"lineNumber": 223,
|
"lineNumber": 224,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, read-only access"
|
"reasonDetail": "Static selector, read-only access"
|
||||||
|
@ -744,7 +744,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('.conversation:first .recorder').trigger('close');",
|
"line": " this.$('.conversation:first .recorder').trigger('close');",
|
||||||
"lineNumber": 226,
|
"lineNumber": 227,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, triggering DOM event"
|
"reasonDetail": "Static selector, triggering DOM event"
|
||||||
|
@ -771,7 +771,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#qr img').remove();",
|
"line": " this.$('#qr img').remove();",
|
||||||
"lineNumber": 161,
|
"lineNumber": 160,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2018-09-19T21:59:32.770Z",
|
"updated": "2018-09-19T21:59:32.770Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -780,7 +780,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#qr canvas').remove();",
|
"line": " this.$('#qr canvas').remove();",
|
||||||
"lineNumber": 162,
|
"lineNumber": 161,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-09-11T17:24:56.124Z",
|
"updated": "2020-09-11T17:24:56.124Z",
|
||||||
"reasonDetail": "Static selector argument"
|
"reasonDetail": "Static selector argument"
|
||||||
|
@ -789,7 +789,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#qr .container').show();",
|
"line": " this.$('#qr .container').show();",
|
||||||
"lineNumber": 163,
|
"lineNumber": 162,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2018-09-19T21:59:32.770Z",
|
"updated": "2018-09-19T21:59:32.770Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -798,7 +798,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#qr').removeClass('ready');",
|
"line": " this.$('#qr').removeClass('ready');",
|
||||||
"lineNumber": 164,
|
"lineNumber": 163,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-09-11T17:24:56.124Z",
|
"updated": "2020-09-11T17:24:56.124Z",
|
||||||
"reasonDetail": "Static selector argument"
|
"reasonDetail": "Static selector argument"
|
||||||
|
@ -807,7 +807,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " if ($('#qr').length === 0) {",
|
"line": " if ($('#qr').length === 0) {",
|
||||||
"lineNumber": 167,
|
"lineNumber": 166,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2018-09-19T21:59:32.770Z",
|
"updated": "2018-09-19T21:59:32.770Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -816,7 +816,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#qr .container').hide();",
|
"line": " this.$('#qr .container').hide();",
|
||||||
"lineNumber": 173,
|
"lineNumber": 172,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-03-24T19:03:04.861Z",
|
"updated": "2020-03-24T19:03:04.861Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -825,7 +825,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.qr = new QRCode(this.$('#qr')[0]).makeCode(url);",
|
"line": " this.qr = new QRCode(this.$('#qr')[0]).makeCode(url);",
|
||||||
"lineNumber": 174,
|
"lineNumber": 173,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-03-24T19:03:04.861Z",
|
"updated": "2020-03-24T19:03:04.861Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -834,7 +834,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#qr').removeAttr('title');",
|
"line": " this.$('#qr').removeAttr('title');",
|
||||||
"lineNumber": 175,
|
"lineNumber": 174,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-09-11T17:24:56.124Z",
|
"updated": "2020-09-11T17:24:56.124Z",
|
||||||
"reasonDetail": "Static selector argument"
|
"reasonDetail": "Static selector argument"
|
||||||
|
@ -843,7 +843,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#qr').addClass('ready');",
|
"line": " this.$('#qr').addClass('ready');",
|
||||||
"lineNumber": 176,
|
"lineNumber": 175,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-03-24T19:03:04.861Z",
|
"updated": "2020-03-24T19:03:04.861Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -852,7 +852,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$(DEVICE_NAME_SELECTOR).val(deviceName || window.getHostName());",
|
"line": " this.$(DEVICE_NAME_SELECTOR).val(deviceName || window.getHostName());",
|
||||||
"lineNumber": 181,
|
"lineNumber": 180,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-03-24T19:03:04.861Z",
|
"updated": "2020-03-24T19:03:04.861Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -861,7 +861,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$(DEVICE_NAME_SELECTOR).focus();",
|
"line": " this.$(DEVICE_NAME_SELECTOR).focus();",
|
||||||
"lineNumber": 182,
|
"lineNumber": 181,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-09-11T17:24:56.124Z",
|
"updated": "2020-09-11T17:24:56.124Z",
|
||||||
"reasonDetail": "Static selector argument"
|
"reasonDetail": "Static selector argument"
|
||||||
|
@ -870,7 +870,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#link-phone').submit();",
|
"line": " this.$('#link-phone').submit();",
|
||||||
"lineNumber": 186,
|
"lineNumber": 185,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-03-24T19:03:04.861Z",
|
"updated": "2020-03-24T19:03:04.861Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -879,7 +879,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$('#link-phone').submit(e => {",
|
"line": " this.$('#link-phone').submit(e => {",
|
||||||
"lineNumber": 228,
|
"lineNumber": 227,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-03-24T19:03:04.861Z",
|
"updated": "2020-03-24T19:03:04.861Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -888,7 +888,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " let name = this.$(DEVICE_NAME_SELECTOR).val();",
|
"line": " let name = this.$(DEVICE_NAME_SELECTOR).val();",
|
||||||
"lineNumber": 232,
|
"lineNumber": 231,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-03-24T19:03:04.861Z",
|
"updated": "2020-03-24T19:03:04.861Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
@ -897,7 +897,7 @@
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/install_view.js",
|
"path": "js/views/install_view.js",
|
||||||
"line": " this.$(DEVICE_NAME_SELECTOR).focus();",
|
"line": " this.$(DEVICE_NAME_SELECTOR).focus();",
|
||||||
"lineNumber": 235,
|
"lineNumber": 234,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-03-24T19:03:04.861Z",
|
"updated": "2020-03-24T19:03:04.861Z",
|
||||||
"reasonDetail": "Protected from arbitrary input"
|
"reasonDetail": "Protected from arbitrary input"
|
||||||
|
|
32
ts/util/postLinkExperience.ts
Normal file
32
ts/util/postLinkExperience.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { onTimeout } from '../services/timers';
|
||||||
|
|
||||||
|
class PostLinkExperience {
|
||||||
|
private hasNotFinishedSync: boolean;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.hasNotFinishedSync = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.hasNotFinishedSync = true;
|
||||||
|
|
||||||
|
// timeout "post link" after 10 minutes in case the syncs don't complete
|
||||||
|
// in time or are never called.
|
||||||
|
onTimeout(Date.now() + 60 * 60 * 10 * 1000, () => {
|
||||||
|
this.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
this.hasNotFinishedSync = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isActive(): boolean {
|
||||||
|
return this.hasNotFinishedSync === true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const postLinkExperience = new PostLinkExperience();
|
Loading…
Reference in a new issue