Make it more difficult to blur avatars

This commit is contained in:
Evan Hahn 2021-05-07 17:21:10 -05:00 committed by GitHub
parent 1276368f94
commit d28678dbf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 1118 additions and 889 deletions

View File

@ -43,11 +43,13 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
overrideProps.conversationType || 'direct'
),
i18n,
isMe: false,
loading: boolean('loading', overrideProps.loading || false),
name: text('name', overrideProps.name || ''),
noteToSelf: boolean('noteToSelf', overrideProps.noteToSelf || false),
onClick: action('onClick'),
phoneNumber: text('phoneNumber', overrideProps.phoneNumber || ''),
sharedGroupNames: [],
size: 80,
title: overrideProps.title || '',
});

View File

@ -40,14 +40,14 @@ export type Props = {
color?: ColorType;
loading?: boolean;
acceptedMessageRequest?: boolean;
acceptedMessageRequest: boolean;
conversationType: 'group' | 'direct';
isMe?: boolean;
isMe: boolean;
name?: string;
noteToSelf?: boolean;
phoneNumber?: string;
profileName?: string;
sharedGroupNames?: Array<string>;
sharedGroupNames: Array<string>;
size: AvatarSize;
title: string;
unblurredAvatarPath?: string;

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -28,6 +28,7 @@ const conversationTypeMap: Record<string, Props['conversationType']> = {
};
const createProps = (overrideProps: Partial<Props> = {}): Props => ({
acceptedMessageRequest: true,
avatarPath: text('avatarPath', overrideProps.avatarPath || ''),
color: select('color', colorMap, overrideProps.color || 'blue'),
conversationType: select(
@ -36,6 +37,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
overrideProps.conversationType || 'direct'
),
i18n,
isMe: true,
name: text('name', overrideProps.name || ''),
noteToSelf: boolean('noteToSelf', overrideProps.noteToSelf || false),
onClick: action('onClick'),
@ -43,6 +45,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
onViewPreferences: action('onViewPreferences'),
phoneNumber: text('phoneNumber', overrideProps.phoneNumber || ''),
profileName: text('profileName', overrideProps.profileName || ''),
sharedGroupNames: [],
size: 80,
style: {},
title: text('title', overrideProps.title || ''),

View File

@ -24,18 +24,19 @@ import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const getConversation = () => ({
id: '3051234567',
avatarPath: undefined,
color: select('Callee color', Colors, 'ultramarine' as ColorType),
title: text('Callee Title', 'Rick Sanchez'),
name: text('Callee Name', 'Rick Sanchez'),
phoneNumber: '3051234567',
profileName: 'Rick Sanchez',
markedUnread: false,
type: 'direct' as ConversationTypeType,
lastUpdated: Date.now(),
});
const getConversation = () =>
getDefaultConversation({
id: '3051234567',
avatarPath: undefined,
color: select('Callee color', Colors, 'ultramarine' as ColorType),
title: text('Callee Title', 'Rick Sanchez'),
name: text('Callee Name', 'Rick Sanchez'),
phoneNumber: '3051234567',
profileName: 'Rick Sanchez',
markedUnread: false,
type: 'direct' as ConversationTypeType,
lastUpdated: Date.now(),
});
const getCommonActiveCallData = () => ({
conversation: getConversation(),

View File

@ -14,6 +14,7 @@ type Props = {
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
@ -49,10 +50,12 @@ export const CallNeedPermissionScreen: React.FC<Props> = ({
noteToSelf={false}
conversationType="direct"
i18n={i18n}
isMe={conversation.isMe}
name={conversation.name}
phoneNumber={conversation.phoneNumber}
profileName={conversation.profileName}
title={conversation.title}
sharedGroupNames={conversation.sharedGroupNames}
size={112}
/>

View File

@ -28,7 +28,7 @@ const MAX_PARTICIPANTS = 32;
const i18n = setupI18n('en', enMessages);
const conversation = {
const conversation = getDefaultConversation({
id: '3051234567',
avatarPath: undefined,
color: Colors[0],
@ -36,10 +36,7 @@ const conversation = {
name: 'Rick Sanchez',
phoneNumber: '3051234567',
profileName: 'Rick Sanchez',
markedUnread: false,
type: 'direct' as const,
lastUpdated: Date.now(),
};
});
type OverridePropsBase = {
hasLocalAudio?: boolean;

View File

@ -273,15 +273,20 @@ export const CallScreen: React.FC<PropsType> = ({
<div className="module-ongoing-call__local-preview-fullsize">
<CallBackgroundBlur avatarPath={me.avatarPath} color={me.color}>
<Avatar
acceptedMessageRequest
avatarPath={me.avatarPath}
color={me.color || 'ultramarine'}
noteToSelf={false}
conversationType="direct"
i18n={i18n}
isMe
name={me.name}
phoneNumber={me.phoneNumber}
profileName={me.profileName}
title={me.title}
// `sharedGroupNames` makes no sense for yourself, but `<Avatar>` needs it
// to determine blurring.
sharedGroupNames={[]}
size={80}
/>
<div className="module-calling__video-off--container">
@ -336,15 +341,19 @@ export const CallScreen: React.FC<PropsType> = ({
{!hasLocalVideo && !isLonelyInGroup ? (
<CallBackgroundBlur avatarPath={me.avatarPath} color={me.color}>
<Avatar
acceptedMessageRequest
avatarPath={me.avatarPath}
color={me.color || 'ultramarine'}
noteToSelf={false}
conversationType="direct"
i18n={i18n}
isMe
name={me.name}
phoneNumber={me.phoneNumber}
profileName={me.profileName}
title={me.title}
// See comment above about `sharedGroupNames`.
sharedGroupNames={[]}
size={80}
/>
</CallBackgroundBlur>

View File

@ -93,12 +93,17 @@ export const CallingParticipantsList = React.memo(
>
<div>
<Avatar
acceptedMessageRequest={
participant.acceptedMessageRequest
}
avatarPath={participant.avatarPath}
color={participant.color}
conversationType="direct"
i18n={i18n}
isMe={participant.isMe}
profileName={participant.profileName}
title={participant.title}
sharedGroupNames={participant.sharedGroupNames}
size={32}
/>
{participant.uuid === ourUuid ? (

View File

@ -7,7 +7,7 @@ import { boolean } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';
import { ColorType } from '../types/Colors';
import { ConversationTypeType } from '../state/ducks/conversations';
import { ConversationType } from '../state/ducks/conversations';
import { CallingPip, PropsType } from './CallingPip';
import {
ActiveCallType,
@ -16,13 +16,14 @@ import {
GroupCallConnectionState,
GroupCallJoinState,
} from '../types/Calling';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
import { fakeGetGroupCallVideoFrameSource } from '../test-both/helpers/fakeGetGroupCallVideoFrameSource';
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const conversation = {
const conversation: ConversationType = getDefaultConversation({
id: '3051234567',
avatarPath: undefined,
color: 'ultramarine' as ColorType,
@ -30,10 +31,7 @@ const conversation = {
name: 'Rick Sanchez',
phoneNumber: '3051234567',
profileName: 'Rick Sanchez',
markedUnread: false,
type: 'direct' as ConversationTypeType,
lastUpdated: Date.now(),
};
});
const getCommonActiveCallData = () => ({
conversation,
@ -73,7 +71,7 @@ story.add('Default', () => {
return <CallingPip {...props} />;
});
story.add('Contact (with avatar)', () => {
story.add('Contact (with avatar and no video)', () => {
const props = createProps({
activeCall: {
...defaultCall,
@ -81,6 +79,7 @@ story.add('Contact (with avatar)', () => {
...conversation,
avatarPath: 'https://www.fillmurray.com/64/64',
},
remoteParticipants: [{ hasRemoteVideo: false }],
},
});
return <CallingPip {...props} />;

View File

@ -32,11 +32,14 @@ const NoVideo = ({
i18n: LocalizerType;
}): JSX.Element => {
const {
acceptedMessageRequest,
avatarPath,
color,
isMe,
name,
phoneNumber,
profileName,
sharedGroupNames,
title,
} = activeCall.conversation;
@ -45,16 +48,19 @@ const NoVideo = ({
<CallBackgroundBlur avatarPath={avatarPath} color={color}>
<div className="module-calling-pip__video--avatar">
<Avatar
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color || 'ultramarine'}
noteToSelf={false}
conversationType="direct"
i18n={i18n}
isMe={isMe}
name={name}
phoneNumber={phoneNumber}
profileName={profileName}
title={title}
size={52}
sharedGroupNames={sharedGroupNames}
/>
</div>
</CallBackgroundBlur>

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -8,6 +8,7 @@ import { boolean, select } from '@storybook/addon-knobs';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
import { CompositionInput, Props } from './CompositionInput';
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
@ -105,20 +106,12 @@ story.add('Emojis', () => {
story.add('Mentions', () => {
const props = createProps({
sortedGroupMembers: [
{
id: '0',
type: 'direct',
lastUpdated: 0,
getDefaultConversation({
title: 'Kate Beaton',
markedUnread: false,
},
{
id: '0',
type: 'direct',
lastUpdated: 0,
}),
getDefaultConversation({
title: 'Parry Gripp',
markedUnread: false,
},
}),
],
draftText: 'send _ a message',
draftBodyRanges: [

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -26,6 +26,7 @@ storiesOf('Components/ContactListItem', module)
name="Someone 🔥 Somewhere"
phoneNumber="(202) 555-0011"
profileName="🔥Flames🔥"
sharedGroupNames={[]}
avatarPath={gifUrl}
onClick={onClick}
/>
@ -38,10 +39,12 @@ storiesOf('Components/ContactListItem', module)
type="direct"
acceptedMessageRequest
i18n={i18n}
isMe={false}
title="Someone 🔥 Somewhere"
name="Someone 🔥 Somewhere"
phoneNumber="(202) 555-0011"
profileName="🔥Flames🔥"
sharedGroupNames={[]}
about="👍 Free to chat"
avatarPath={gifUrl}
onClick={onClick}
@ -50,10 +53,12 @@ storiesOf('Components/ContactListItem', module)
type="direct"
acceptedMessageRequest
i18n={i18n}
isMe={false}
title="Another ❄️ Yes"
name="Another ❄️ Yes"
phoneNumber="(202) 555-0011"
profileName="❄Ice❄"
sharedGroupNames={[]}
about="🙏 Be kind"
avatarPath={gifUrl}
onClick={onClick}
@ -67,11 +72,13 @@ storiesOf('Components/ContactListItem', module)
type="direct"
acceptedMessageRequest
i18n={i18n}
isMe={false}
isAdmin
title="Someone 🔥 Somewhere"
name="Someone 🔥 Somewhere"
phoneNumber="(202) 555-0011"
profileName="🔥Flames🔥"
sharedGroupNames={[]}
about="👍 This is my really long status message that I have in order to test line breaking"
avatarPath={gifUrl}
onClick={onClick}
@ -83,8 +90,11 @@ storiesOf('Components/ContactListItem', module)
<ContactListItem
type="group"
i18n={i18n}
isMe={false}
isAdmin
title="Group!"
sharedGroupNames={[]}
acceptedMessageRequest
about="👍 Free to chat"
onClick={onClick}
/>
@ -96,9 +106,11 @@ storiesOf('Components/ContactListItem', module)
type="direct"
acceptedMessageRequest
i18n={i18n}
isMe={false}
isAdmin
title="(202) 555-0011"
phoneNumber="(202) 555-0011"
sharedGroupNames={[]}
about="👍 Free to chat"
avatarPath={gifUrl}
onClick={onClick}
@ -111,11 +123,13 @@ storiesOf('Components/ContactListItem', module)
type="direct"
acceptedMessageRequest
i18n={i18n}
isMe={false}
title="Someone 🔥 Somewhere"
name="Someone 🔥 Somewhere"
color="teal"
phoneNumber="(202) 555-0011"
profileName="🔥Flames🔥"
sharedGroupNames={[]}
about="👍 Free to chat"
onClick={onClick}
/>
@ -128,9 +142,11 @@ storiesOf('Components/ContactListItem', module)
acceptedMessageRequest
color="blue"
i18n={i18n}
isMe={false}
phoneNumber="(202) 555-0011"
title="🔥Flames🔥"
profileName="🔥Flames🔥"
sharedGroupNames={[]}
about="👍 Free to chat"
onClick={onClick}
/>
@ -142,7 +158,9 @@ storiesOf('Components/ContactListItem', module)
type="direct"
acceptedMessageRequest
i18n={i18n}
isMe={false}
phoneNumber="(202) 555-0011"
sharedGroupNames={[]}
title="(202) 555-0011"
onClick={onClick}
/>
@ -154,8 +172,10 @@ storiesOf('Components/ContactListItem', module)
type="direct"
acceptedMessageRequest
i18n={i18n}
isMe={false}
title="(202) 555-0011"
about="👍 Free to chat"
sharedGroupNames={[]}
phoneNumber="(202) 555-0011"
onClick={onClick}
/>
@ -167,7 +187,9 @@ storiesOf('Components/ContactListItem', module)
type="direct"
acceptedMessageRequest
i18n={i18n}
isMe={false}
title="Unknown contact"
sharedGroupNames={[]}
onClick={onClick}
/>
);

View File

@ -39,6 +39,7 @@ export class ContactListItem extends React.Component<Props> {
avatarPath,
color,
i18n,
isMe,
name,
phoneNumber,
profileName,
@ -55,6 +56,7 @@ export class ContactListItem extends React.Component<Props> {
color={color}
conversationType={type}
i18n={i18n}
isMe={isMe}
name={name}
phoneNumber={phoneNumber}
profileName={profileName}

View File

@ -34,6 +34,7 @@ export const ContactPill: FunctionComponent<PropsType> = ({
color,
firstName,
i18n,
isMe,
id,
name,
phoneNumber,
@ -54,6 +55,7 @@ export const ContactPill: FunctionComponent<PropsType> = ({
noteToSelf={false}
conversationType="direct"
i18n={i18n}
isMe={isMe}
name={name}
phoneNumber={phoneNumber}
profileName={profileName}

View File

@ -12,6 +12,7 @@ import enMessages from '../../_locales/en/messages.json';
import { ContactPills } from './ContactPills';
import { ContactPill, PropsType as ContactPillPropsType } from './ContactPill';
import { gifUrl } from '../storybook/Fixtures';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
@ -19,30 +20,32 @@ const story = storiesOf('Components/Contact Pills', module);
type ContactType = Omit<ContactPillPropsType, 'i18n' | 'onClickRemove'>;
const contacts: Array<ContactType> = times(50, index => ({
color: 'red',
id: `contact-${index}`,
isMe: false,
name: `Contact ${index}`,
phoneNumber: '(202) 555-0001',
profileName: `C${index}`,
title: `Contact ${index}`,
}));
const contacts: Array<ContactType> = times(50, index =>
getDefaultConversation({
color: 'red',
id: `contact-${index}`,
name: `Contact ${index}`,
phoneNumber: '(202) 555-0001',
profileName: `C${index}`,
title: `Contact ${index}`,
})
);
const contactPillProps = (
overrideProps?: ContactType
): ContactPillPropsType => ({
...(overrideProps || {
avatarPath: gifUrl,
color: 'red',
firstName: 'John',
id: 'abc123',
isMe: false,
name: 'John Bon Bon Jovi',
phoneNumber: '(202) 555-0001',
profileName: 'JohnB',
title: 'John Bon Bon Jovi',
}),
...(overrideProps ||
getDefaultConversation({
avatarPath: gifUrl,
color: 'red',
firstName: 'John',
id: 'abc123',
isMe: false,
name: 'John Bon Bon Jovi',
phoneNumber: '(202) 555-0001',
profileName: 'JohnB',
title: 'John Bon Bon Jovi',
})),
i18n,
onClickRemove: action('onClickRemove'),
});

View File

@ -24,32 +24,21 @@ const i18n = setupI18n('en', enMessages);
const story = storiesOf('Components/ConversationList', module);
const defaultConversations: Array<ConversationListItemPropsType> = [
{
getDefaultConversation({
id: 'fred-convo',
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Fred Willard',
type: 'direct',
},
{
}),
getDefaultConversation({
id: 'marc-convo',
isSelected: true,
lastUpdated: Date.now(),
markedUnread: false,
unreadCount: 12,
title: 'Marc Barraca',
type: 'direct',
},
{
}),
getDefaultConversation({
id: 'long-name-convo',
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title:
'Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de la Santísima Trinidad Ruiz y Picasso',
type: 'direct',
},
}),
getDefaultConversation(),
];
@ -247,6 +236,7 @@ story.add('Contact checkboxes: disabled', () => (
'lastUpdated',
new Date(overrideProps.lastUpdated || Date.now() - 5 * 60 * 1000)
),
sharedGroupNames: [],
});
const renderConversation = (

View File

@ -4,7 +4,6 @@
import React, { useRef, useEffect } from 'react';
import { SetRendererCanvasType } from '../state/ducks/calling';
import { ConversationType } from '../state/ducks/conversations';
import { ColorType } from '../types/Colors';
import { LocalizerType } from '../types/Util';
import { Avatar } from './Avatar';
@ -43,33 +42,43 @@ export const DirectCallRemoteParticipant: React.FC<PropsType> = ({
function renderAvatar(
i18n: LocalizerType,
{
acceptedMessageRequest,
avatarPath,
color,
isMe,
name,
phoneNumber,
profileName,
sharedGroupNames,
title,
}: {
avatarPath?: string;
color?: ColorType;
title: string;
name?: string;
phoneNumber?: string;
profileName?: string;
}
}: Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
>
): JSX.Element {
return (
<div className="module-ongoing-call__remote-video-disabled">
<Avatar
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color || 'ultramarine'}
noteToSelf={false}
conversationType="direct"
i18n={i18n}
isMe={isMe}
name={name}
phoneNumber={phoneNumber}
profileName={profileName}
title={title}
sharedGroupNames={sharedGroupNames}
size={112}
/>
</div>

View File

@ -54,13 +54,16 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
const { getFrameBuffer, getGroupCallVideoFrameSource, i18n } = props;
const {
acceptedMessageRequest,
avatarPath,
color,
demuxId,
hasRemoteAudio,
hasRemoteVideo,
isBlocked,
isMe,
profileName,
sharedGroupNames,
title,
videoAspectRatio,
} = props.remoteParticipant;
@ -285,13 +288,16 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
</>
) : (
<Avatar
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color || 'ultramarine'}
noteToSelf={false}
conversationType="direct"
i18n={i18n}
isMe={isMe}
profileName={profileName}
title={title}
sharedGroupNames={sharedGroupNames}
size={avatarSize}
/>
)}

View File

@ -99,8 +99,15 @@ GroupDialog.Contacts = ({ contacts, i18n }: Readonly<ContactsPropsType>) => (
{contacts.map(contact => (
<li key={contact.id} className="module-GroupDialog__contacts__contact">
<Avatar
{...contact}
acceptedMessageRequest={contact.acceptedMessageRequest}
avatarPath={contact.avatarPath}
color={contact.color}
conversationType={contact.type}
isMe={contact.isMe}
noteToSelf={contact.isMe}
title={contact.title}
unblurredAvatarPath={contact.unblurredAvatarPath}
sharedGroupNames={contact.sharedGroupNames}
size={AvatarSize.TWENTY_EIGHT}
i18n={i18n}
/>

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -8,37 +8,30 @@ import { boolean } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';
import { GroupV1MigrationDialog, PropsType } from './GroupV1MigrationDialog';
import { ConversationType } from '../state/ducks/conversations';
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
const contact1 = {
const contact1: ConversationType = getDefaultConversation({
title: 'Alice',
number: '+1 (300) 555-0000',
phoneNumber: '+1 (300) 555-0000',
id: 'guid-1',
markedUnread: false,
type: 'direct' as const,
lastUpdated: Date.now(),
};
});
const contact2 = {
const contact2: ConversationType = getDefaultConversation({
title: 'Bob',
number: '+1 (300) 555-0001',
phoneNumber: '+1 (300) 555-0001',
id: 'guid-2',
markedUnread: false,
type: 'direct' as const,
lastUpdated: Date.now(),
};
});
const contact3 = {
const contact3: ConversationType = getDefaultConversation({
title: 'Chet',
number: '+1 (300) 555-0002',
phoneNumber: '+1 (300) 555-0002',
id: 'guid-3',
markedUnread: false,
type: 'direct' as const,
lastUpdated: Date.now(),
};
});
function booleanOr(value: boolean | undefined, defaultValue: boolean): boolean {
return isBoolean(value) ? value : defaultValue;

View File

@ -4,7 +4,7 @@
import * as React from 'react';
import classNames from 'classnames';
import { LocalizerType } from '../types/Util';
import { Avatar } from './Avatar';
import { Avatar, AvatarBlur } from './Avatar';
import { Spinner } from './Spinner';
import { Button, ButtonVariant } from './Button';
@ -77,10 +77,14 @@ export const GroupV2JoinDialog = React.memo((props: PropsType) => {
/>
<div className="module-group-v2-join-dialog__avatar">
<Avatar
acceptedMessageRequest={false}
avatarPath={avatar ? avatar.url : undefined}
blur={AvatarBlur.NoBlur}
loading={avatar && !avatar.url}
conversationType="group"
title={title}
isMe={false}
sharedGroupNames={[]}
size={80}
i18n={i18n}
/>

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -10,6 +10,7 @@ import { IncomingCallBar } from './IncomingCallBar';
import { Colors, ColorType } from '../types/Colors';
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
@ -21,15 +22,15 @@ const defaultProps = {
isIncoming: true,
isVideoCall: true,
},
conversation: {
conversation: getDefaultConversation({
id: '3051234567',
avatarPath: undefined,
contactColor: 'ultramarine' as ColorType,
color: 'ultramarine' as ColorType,
name: 'Rick Sanchez',
phoneNumber: '3051234567',
profileName: 'Rick Sanchez',
title: 'Rick Sanchez',
},
}),
declineCall: action('decline-call'),
i18n,
};

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
@ -7,7 +7,7 @@ import { Tooltip } from './Tooltip';
import { Theme } from '../util/theme';
import { ContactName } from './conversation/ContactName';
import { LocalizerType } from '../types/Util';
import { ColorType } from '../types/Colors';
import { ConversationType } from '../state/ducks/conversations';
import { AcceptCallType, DeclineCallType } from '../state/ducks/calling';
export type PropsType = {
@ -17,15 +17,19 @@ export type PropsType = {
call: {
isVideoCall: boolean;
};
conversation: {
id: string;
avatarPath?: string;
color?: ColorType;
title: string;
name?: string;
phoneNumber?: string;
profileName?: string;
};
conversation: Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'id'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
>;
};
type CallButtonProps = {
@ -66,12 +70,15 @@ export const IncomingCallBar = ({
const { isVideoCall } = call;
const {
id: conversationId,
acceptedMessageRequest,
avatarPath,
color,
title,
isMe,
name,
phoneNumber,
profileName,
sharedGroupNames,
title,
} = conversation;
return (
@ -79,15 +86,18 @@ export const IncomingCallBar = ({
<div className="module-incoming-call__contact">
<div className="module-incoming-call__contact--avatar">
<Avatar
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color || 'ultramarine'}
noteToSelf={false}
conversationType="direct"
i18n={i18n}
isMe={isMe}
name={name}
phoneNumber={phoneNumber}
profileName={profileName}
title={title}
sharedGroupNames={sharedGroupNames}
size={52}
/>
</div>

View File

@ -9,83 +9,62 @@ import { storiesOf } from '@storybook/react';
import { LeftPane, LeftPaneMode, PropsType } from './LeftPane';
import { CaptchaDialog } from './CaptchaDialog';
import { PropsData as ConversationListItemPropsType } from './conversationList/ConversationListItem';
import { ConversationType } from '../state/ducks/conversations';
import { MessageSearchResult } from './conversationList/MessageSearchResult';
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
const story = storiesOf('Components/LeftPane', module);
const defaultConversations: Array<ConversationListItemPropsType> = [
{
const defaultConversations: Array<ConversationType> = [
getDefaultConversation({
id: 'fred-convo',
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Fred Willard',
type: 'direct',
},
{
}),
getDefaultConversation({
id: 'marc-convo',
isSelected: true,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Marc Barraca',
type: 'direct',
},
}),
];
const defaultGroups: Array<ConversationListItemPropsType> = [
{
const defaultGroups: Array<ConversationType> = [
getDefaultConversation({
id: 'biking-group',
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Mtn Biking Arizona 🚵☀️⛰',
type: 'group',
},
{
sharedGroupNames: [],
}),
getDefaultConversation({
id: 'dance-group',
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Are we dancers? 💃',
type: 'group',
},
sharedGroupNames: [],
}),
];
const defaultArchivedConversations: Array<ConversationListItemPropsType> = [
{
const defaultArchivedConversations: Array<ConversationType> = [
getDefaultConversation({
id: 'michelle-archive-convo',
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Michelle Mercure',
type: 'direct',
},
isArchived: true,
}),
];
const pinnedConversations: Array<ConversationListItemPropsType> = [
{
const pinnedConversations: Array<ConversationType> = [
getDefaultConversation({
id: 'philly-convo',
isPinned: true,
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Philip Glass',
type: 'direct',
},
{
}),
getDefaultConversation({
id: 'robbo-convo',
isPinned: true,
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Robert Moog',
type: 'direct',
},
}),
];
const defaultModeSpecificProps = {

View File

@ -368,6 +368,7 @@ export class MainHeader extends React.Component<PropsType, StateType> {
<Reference>
{({ ref }) => (
<Avatar
acceptedMessageRequest
avatarPath={avatarPath}
className="module-main-header__avatar"
color={color}
@ -378,6 +379,9 @@ export class MainHeader extends React.Component<PropsType, StateType> {
phoneNumber={phoneNumber}
profileName={profileName}
title={title}
// `sharedGroupNames` makes no sense for yourself, but `<Avatar>` needs it
// to determine blurring.
sharedGroupNames={[]}
size={28}
innerRef={ref}
onClick={this.showAvatarPopup}
@ -389,8 +393,10 @@ export class MainHeader extends React.Component<PropsType, StateType> {
<Popper placement="bottom-end">
{({ ref, style }) => (
<AvatarPopup
acceptedMessageRequest
innerRef={ref}
i18n={i18n}
isMe
style={{ ...style, zIndex: 1 }}
color={color}
conversationType="direct"
@ -400,6 +406,8 @@ export class MainHeader extends React.Component<PropsType, StateType> {
title={title}
avatarPath={avatarPath}
size={28}
// See the comment above about `sharedGroupNames`.
sharedGroupNames={[]}
onViewPreferences={() => {
showSettings();
this.hideAvatarPopup();

View File

@ -10,26 +10,13 @@ import { NewlyCreatedGroupInvitedContactsDialog } from './NewlyCreatedGroupInvit
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
import { ConversationType } from '../state/ducks/conversations';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
const conversations: Array<ConversationType> = [
{
id: 'fred-convo',
isSelected: false,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Fred Willard',
type: 'direct',
},
{
id: 'marc-convo',
isSelected: true,
lastUpdated: Date.now(),
markedUnread: false,
title: 'Marc Barraca',
type: 'direct',
},
getDefaultConversation({ title: 'Fred Willard' }),
getDefaultConversation({ title: 'Marc Barraca' }),
];
const story = storiesOf(

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -6,13 +6,13 @@ import { action } from '@storybook/addon-actions';
import { storiesOf } from '@storybook/react';
import { SafetyNumberChangeDialog } from './SafetyNumberChangeDialog';
import { ConversationType } from '../state/ducks/conversations';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const contactWithAllData = {
const contactWithAllData = getDefaultConversation({
id: 'abc',
avatarPath: undefined,
color: 'signal-blue',
@ -20,9 +20,9 @@ const contactWithAllData = {
title: 'Rick Sanchez',
name: 'Rick Sanchez',
phoneNumber: '(305) 123-4567',
} as ConversationType;
});
const contactWithJustProfile = {
const contactWithJustProfile = getDefaultConversation({
id: 'def',
avatarPath: undefined,
color: 'signal-blue',
@ -30,9 +30,9 @@ const contactWithJustProfile = {
profileName: '-*Smartest Dude*-',
name: undefined,
phoneNumber: '(305) 123-4567',
} as ConversationType;
});
const contactWithJustNumber = {
const contactWithJustNumber = getDefaultConversation({
id: 'xyz',
avatarPath: undefined,
color: 'signal-blue',
@ -40,9 +40,9 @@ const contactWithJustNumber = {
name: undefined,
title: '(305) 123-4567',
phoneNumber: '(305) 123-4567',
} as ConversationType;
});
const contactWithNothing = {
const contactWithNothing = getDefaultConversation({
id: 'some-guid',
avatarPath: undefined,
color: 'signal-blue',
@ -50,7 +50,7 @@ const contactWithNothing = {
name: undefined,
phoneNumber: undefined,
title: 'Unknown contact',
} as ConversationType;
});
storiesOf('Components/SafetyNumberChangeDialog', module)
.add('Single Contact Dialog', () => {

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -91,6 +91,7 @@ export const SafetyNumberChangeDialog = ({
color={contact.color}
conversationType="direct"
i18n={i18n}
isMe={contact.isMe}
name={contact.name}
phoneNumber={contact.phoneNumber}
profileName={contact.profileName}

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -7,6 +7,7 @@ import { action } from '@storybook/addon-actions';
import { boolean } from '@storybook/addon-knobs';
import { storiesOf } from '@storybook/react';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { ContactModal, PropsType } from './ContactModal';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
@ -16,16 +17,13 @@ const i18n = setupI18n('en', enMessages);
const story = storiesOf('Components/Conversation/ContactModal', module);
const defaultContact: ConversationType = {
const defaultContact: ConversationType = getDefaultConversation({
id: 'abcdef',
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
title: 'Pauline Oliveros',
type: 'direct',
phoneNumber: '(333) 444-5515',
about: '👍 Free to chat',
};
});
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
areWeAdmin: boolean('areWeAdmin', overrideProps.areWeAdmin || false),

View File

@ -111,6 +111,7 @@ export const ContactModal = ({
color={contact.color}
conversationType="direct"
i18n={i18n}
isMe={contact.isMe}
name={contact.name}
profileName={contact.profileName}
sharedGroupNames={contact.sharedGroupNames}

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { ComponentProps } from 'react';
@ -6,6 +6,7 @@ import React, { ComponentProps } from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
import {
@ -27,9 +28,10 @@ type ConversationHeaderStory = {
};
const commonProps = {
...getDefaultConversation(),
showBackButton: false,
outgoingCallButtonStyle: OutgoingCallButtonStyle.Both,
markedUnread: false,
i18n,

View File

@ -30,6 +30,7 @@ storiesOf('Components/Conversation/ConversationHero', module)
about={getAbout()}
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={getTitle()}
avatarPath={getAvatarPath()}
name={getName()}
@ -50,6 +51,7 @@ storiesOf('Components/Conversation/ConversationHero', module)
about={getAbout()}
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={getTitle()}
avatarPath={getAvatarPath()}
name={getName()}
@ -70,6 +72,7 @@ storiesOf('Components/Conversation/ConversationHero', module)
about={getAbout()}
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={getTitle()}
avatarPath={getAvatarPath()}
name={getName()}
@ -90,6 +93,7 @@ storiesOf('Components/Conversation/ConversationHero', module)
about={getAbout()}
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={getTitle()}
avatarPath={getAvatarPath()}
name={getName()}
@ -110,6 +114,7 @@ storiesOf('Components/Conversation/ConversationHero', module)
about={getAbout()}
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={text('title', 'Cayce Bollard (profile)')}
avatarPath={getAvatarPath()}
name={text('name', '')}
@ -130,6 +135,7 @@ storiesOf('Components/Conversation/ConversationHero', module)
about={getAbout()}
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={text('title', '+1 (646) 327-2700')}
avatarPath={getAvatarPath()}
name={text('name', '')}
@ -148,6 +154,7 @@ storiesOf('Components/Conversation/ConversationHero', module)
<div style={{ width: '480px' }}>
<ConversationHero
i18n={i18n}
isMe={false}
title={text('title', 'Unknown contact')}
acceptedMessageRequest
avatarPath={getAvatarPath()}
@ -167,6 +174,7 @@ storiesOf('Components/Conversation/ConversationHero', module)
<div style={{ width: '480px' }}>
<ConversationHero
i18n={i18n}
isMe={false}
title={text('title', 'Unknown contact')}
acceptedMessageRequest={false}
avatarPath={getAvatarPath()}
@ -187,10 +195,12 @@ storiesOf('Components/Conversation/ConversationHero', module)
<ConversationHero
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={text('title', 'NYC Rock Climbers')}
name={text('groupName', 'NYC Rock Climbers')}
conversationType="group"
membersCount={numberKnob('membersCount', 22)}
sharedGroupNames={[]}
unblurAvatar={action('unblurAvatar')}
updateSharedGroups={updateSharedGroups}
/>
@ -203,10 +213,12 @@ storiesOf('Components/Conversation/ConversationHero', module)
<ConversationHero
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={text('title', 'NYC Rock Climbers')}
name={text('groupName', 'NYC Rock Climbers')}
conversationType="group"
membersCount={1}
sharedGroupNames={[]}
unblurAvatar={action('unblurAvatar')}
updateSharedGroups={updateSharedGroups}
/>
@ -219,10 +231,12 @@ storiesOf('Components/Conversation/ConversationHero', module)
<ConversationHero
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={text('title', 'NYC Rock Climbers')}
name={text('groupName', 'NYC Rock Climbers')}
conversationType="group"
membersCount={0}
sharedGroupNames={[]}
unblurAvatar={action('unblurAvatar')}
updateSharedGroups={updateSharedGroups}
/>
@ -235,10 +249,12 @@ storiesOf('Components/Conversation/ConversationHero', module)
<ConversationHero
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={text('title', 'Unknown group')}
name={text('groupName', '')}
conversationType="group"
membersCount={0}
sharedGroupNames={[]}
unblurAvatar={action('unblurAvatar')}
updateSharedGroups={updateSharedGroups}
/>
@ -249,11 +265,13 @@ storiesOf('Components/Conversation/ConversationHero', module)
return (
<div style={{ width: '480px' }}>
<ConversationHero
acceptedMessageRequest
i18n={i18n}
isMe
title={getTitle()}
conversationType="direct"
phoneNumber={getPhoneNumber()}
sharedGroupNames={[]}
unblurAvatar={action('unblurAvatar')}
updateSharedGroups={updateSharedGroups}
/>

View File

@ -17,7 +17,7 @@ export type Props = {
about?: string;
acceptedMessageRequest?: boolean;
i18n: LocalizerType;
isMe?: boolean;
isMe: boolean;
membersCount?: number;
onHeightChange?: () => unknown;
phoneNumber?: string;
@ -179,18 +179,21 @@ export const ConversationHero = ({
{({ measureRef }) => (
<div className="module-conversation-hero" ref={measureRef}>
<Avatar
i18n={i18n}
blur={avatarBlur}
color={color}
noteToSelf={isMe}
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
blur={avatarBlur}
className="module-conversation-hero__avatar"
color={color}
conversationType={conversationType}
i18n={i18n}
isMe={isMe}
name={name}
noteToSelf={isMe}
onClick={avatarOnClick}
profileName={profileName}
title={title}
sharedGroupNames={sharedGroupNames}
size={112}
className="module-conversation-hero__avatar"
title={title}
/>
<h1 className="module-conversation-hero__profile-name">
{isMe ? (

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* eslint-disable-next-line max-classes-per-file */
@ -7,29 +7,24 @@ import { storiesOf } from '@storybook/react';
import { isBoolean } from 'lodash';
import { boolean } from '@storybook/addon-knobs';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
import { GroupV1Migration, PropsType } from './GroupV1Migration';
const i18n = setupI18n('en', enMessages);
const contact1 = {
const contact1 = getDefaultConversation({
title: 'Alice',
number: '+1 (300) 555-000',
phoneNumber: '+1 (300) 555-000',
id: 'guid-1',
markedUnread: false,
type: 'direct' as const,
lastUpdated: Date.now(),
};
});
const contact2 = {
const contact2 = getDefaultConversation({
title: 'Bob',
number: '+1 (300) 555-000',
phoneNumber: '+1 (300) 555-000',
id: 'guid-2',
markedUnread: false,
type: 'direct' as const,
lastUpdated: Date.now(),
};
});
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
areWeInvited: boolean(

View File

@ -5,7 +5,7 @@ import * as React from 'react';
import { isBoolean } from 'lodash';
import { action } from '@storybook/addon-actions';
import { boolean, number, text, select } from '@storybook/addon-knobs';
import { boolean, number, text } from '@storybook/addon-knobs';
import { storiesOf } from '@storybook/react';
import { SignalService } from '../../protobuf';
@ -25,6 +25,7 @@ import { computePeaks } from '../GlobalAudioContext';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
import { pngUrl } from '../../storybook/Fixtures';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
@ -67,18 +68,9 @@ const renderAudioAttachment: Props['renderAudioAttachment'] = props => (
<MessageAudioContainer {...props} />
);
const createAuthorProp = (
overrides: Partial<Props['author']> = {}
): Props['author'] => ({
id: 'some-id',
color: select('authorColor', Colors, Colors[0]),
...overrides,
title: text('authorTitle', overrides.title || ''),
});
const createProps = (overrideProps: Partial<Props> = {}): Props => ({
attachments: overrideProps.attachments,
author: overrideProps.author || createAuthorProp(),
author: overrideProps.author || getDefaultConversation(),
reducedMotion: boolean('reducedMotion', false),
bodyRanges: overrideProps.bodyRanges,
canReply: true,
@ -220,7 +212,7 @@ story.add('Pending', () => {
story.add('Collapsed Metadata', () => {
const props = createProps({
author: createAuthorProp({ title: 'Fred Willard' }),
author: getDefaultConversation({ title: 'Fred Willard' }),
collapseMetadata: true,
conversationType: 'group',
text: 'Hello there from a pal!',
@ -254,83 +246,83 @@ story.add('Reactions (wider message)', () => {
reactions: [
{
emoji: '👍',
from: {
from: getDefaultConversation({
isMe: true,
id: '+14155552672',
phoneNumber: '+14155552672',
name: 'Me',
title: 'Me',
},
}),
timestamp: Date.now() - 10,
},
{
emoji: '👍',
from: {
from: getDefaultConversation({
id: '+14155552672',
phoneNumber: '+14155552672',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now() - 10,
},
{
emoji: '👍',
from: {
from: getDefaultConversation({
id: '+14155552673',
phoneNumber: '+14155552673',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now() - 10,
},
{
emoji: '😂',
from: {
from: getDefaultConversation({
id: '+14155552674',
phoneNumber: '+14155552674',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now() - 10,
},
{
emoji: '😂',
from: {
from: getDefaultConversation({
id: '+14155552676',
phoneNumber: '+14155552676',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now() - 10,
},
{
emoji: '😡',
from: {
from: getDefaultConversation({
id: '+14155552677',
phoneNumber: '+14155552677',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now() - 10,
},
{
emoji: '👎',
from: {
from: getDefaultConversation({
id: '+14155552678',
phoneNumber: '+14155552678',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now() - 10,
},
{
emoji: '❤️',
from: {
from: getDefaultConversation({
id: '+14155552679',
phoneNumber: '+14155552679',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now() - 10,
},
],
@ -346,83 +338,83 @@ story.add('Reactions (short message)', () => {
reactions: [
{
emoji: '👍',
from: {
from: getDefaultConversation({
isMe: true,
id: '+14155552672',
phoneNumber: '+14155552672',
name: 'Me',
title: 'Me',
},
}),
timestamp: Date.now(),
},
{
emoji: '👍',
from: {
from: getDefaultConversation({
id: '+14155552672',
phoneNumber: '+14155552672',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
{
emoji: '👍',
from: {
from: getDefaultConversation({
id: '+14155552673',
phoneNumber: '+14155552673',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
{
emoji: '😂',
from: {
from: getDefaultConversation({
id: '+14155552674',
phoneNumber: '+14155552674',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
{
emoji: '😂',
from: {
from: getDefaultConversation({
id: '+14155552676',
phoneNumber: '+14155552676',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
{
emoji: '😡',
from: {
from: getDefaultConversation({
id: '+14155552677',
phoneNumber: '+14155552677',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
{
emoji: '👎',
from: {
from: getDefaultConversation({
id: '+14155552678',
phoneNumber: '+14155552678',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
{
emoji: '❤️',
from: {
from: getDefaultConversation({
id: '+14155552679',
phoneNumber: '+14155552679',
name: 'Amelia Briggs',
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
],
@ -433,7 +425,7 @@ story.add('Reactions (short message)', () => {
story.add('Avatar in Group', () => {
const props = createProps({
author: createAuthorProp({ avatarPath: pngUrl }),
author: getDefaultConversation({ avatarPath: pngUrl }),
conversationType: 'group',
status: 'sent',
text: 'Hello it is me, the saxophone.',
@ -1000,7 +992,7 @@ story.add('Colors', () => {
{Colors.map(color => (
<Message
{...createProps({
author: createAuthorProp({ color }),
author: getDefaultConversation({ color }),
text:
'Hello there from a pal! I am sending a long message so that it will wrap a bit, since I like that look.',
})}

View File

@ -9,6 +9,7 @@ import { storiesOf } from '@storybook/react';
import { PropsData as MessageDataPropsType } from './Message';
import { MessageDetail, Props } from './MessageDetail';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
@ -17,10 +18,10 @@ const i18n = setupI18n('en', enMessages);
const story = storiesOf('Components/Conversation/MessageDetail', module);
const defaultMessage: MessageDataPropsType = {
author: {
author: getDefaultConversation({
id: 'some-id',
title: 'Max',
},
}),
canReply: true,
canDeleteForEveryone: true,
canDownload: true,
@ -39,13 +40,15 @@ const defaultMessage: MessageDataPropsType = {
const createProps = (overrideProps: Partial<Props> = {}): Props => ({
contacts: overrideProps.contacts || [
{
color: 'green',
...getDefaultConversation({
color: 'green',
title: 'Just Max',
}),
isOutgoingKeyError: false,
isUnidentifiedDelivery: false,
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'delivered',
title: 'Just Max',
},
],
errors: overrideProps.errors || [],
@ -98,49 +101,59 @@ story.add('Message Statuses', () => {
const props = createProps({
contacts: [
{
color: 'green',
...getDefaultConversation({
color: 'green',
title: 'Max',
}),
isOutgoingKeyError: false,
isUnidentifiedDelivery: false,
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'sent',
title: 'Max',
},
{
color: 'blue',
...getDefaultConversation({
color: 'blue',
title: 'Sally',
}),
isOutgoingKeyError: false,
isUnidentifiedDelivery: false,
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'sending',
title: 'Sally',
},
{
color: 'brown',
...getDefaultConversation({
color: 'brown',
title: 'Terry',
}),
isOutgoingKeyError: false,
isUnidentifiedDelivery: false,
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'partial-sent',
title: 'Terry',
},
{
color: 'light_green',
...getDefaultConversation({
color: 'light_green',
title: 'Theo',
}),
isOutgoingKeyError: false,
isUnidentifiedDelivery: false,
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'delivered',
title: 'Theo',
},
{
color: 'blue_grey',
...getDefaultConversation({
color: 'blue_grey',
title: 'Nikki',
}),
isOutgoingKeyError: false,
isUnidentifiedDelivery: false,
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'read',
title: 'Nikki',
},
],
message: {
@ -191,16 +204,21 @@ story.add('All Errors', () => {
},
contacts: [
{
color: 'green',
...getDefaultConversation({
color: 'green',
title: 'Max',
}),
isOutgoingKeyError: true,
isUnidentifiedDelivery: false,
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'error',
title: 'Max',
},
{
color: 'blue',
...getDefaultConversation({
color: 'blue',
title: 'Sally',
}),
errors: [
{
name: 'Big Error',
@ -212,16 +230,17 @@ story.add('All Errors', () => {
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'error',
title: 'Sally',
},
{
color: 'brown',
...getDefaultConversation({
color: 'brown',
title: 'Terry',
}),
isOutgoingKeyError: true,
isUnidentifiedDelivery: true,
onSendAnyway: action('onSendAnyway'),
onShowSafetyNumber: action('onShowSafetyNumber'),
status: 'error',
title: 'Terry',
},
],
});

View File

@ -15,21 +15,25 @@ import {
PropsData as MessagePropsDataType,
} from './Message';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
import { ConversationType } from '../../state/ducks/conversations';
import { assert } from '../../util/assert';
export type Contact = {
export type Contact = Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
| 'unblurredAvatarPath'
> & {
status: MessageStatusType | null;
acceptedMessageRequest?: boolean;
title: string;
phoneNumber?: string;
name?: string;
profileName?: string;
avatarPath?: string;
color?: ColorType;
isOutgoingKeyError: boolean;
sharedGroupNames?: Array<string>;
isUnidentifiedDelivery: boolean;
unblurredAvatarPath?: string;
@ -95,6 +99,7 @@ export class MessageDetail extends React.Component<Props> {
acceptedMessageRequest,
avatarPath,
color,
isMe,
name,
phoneNumber,
profileName,
@ -110,6 +115,7 @@ export class MessageDetail extends React.Component<Props> {
color={color}
conversationType="direct"
i18n={i18n}
isMe={isMe}
name={name}
phoneNumber={phoneNumber}
profileName={profileName}

View File

@ -1,10 +1,11 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
import { ProfileChangeNotification } from './ProfileChangeNotification';
@ -16,14 +17,12 @@ storiesOf('Components/Conversation/ProfileChangeNotification', module)
return (
<ProfileChangeNotification
i18n={i18n}
changedContact={{
changedContact={getDefaultConversation({
id: 'some-guid',
type: 'direct',
title: 'Mr. Fire 🔥',
name: 'Mr. Fire 🔥',
lastUpdated: Date.now(),
markedUnread: false,
}}
})}
change={{
type: 'name',
oldName: 'Mr. Fire 🔥 Old',
@ -36,13 +35,11 @@ storiesOf('Components/Conversation/ProfileChangeNotification', module)
return (
<ProfileChangeNotification
i18n={i18n}
changedContact={{
changedContact={getDefaultConversation({
id: 'some-guid',
type: 'direct',
title: 'Mr. Fire 🔥',
lastUpdated: Date.now(),
markedUnread: false,
}}
})}
change={{
type: 'name',
oldName: 'Mr. Fire 🔥 Old',

View File

@ -21,16 +21,17 @@ import {
import { Props, Quote } from './Quote';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
const story = storiesOf('Components/Conversation/Quote', module);
const defaultMessageProps: MessagesProps = {
author: {
author: getDefaultConversation({
id: 'some-id',
title: 'Person X',
},
}),
canReply: true,
canDeleteForEveryone: true,
canDownload: true,

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -9,6 +9,7 @@ import { storiesOf } from '@storybook/react';
import { Props, ReactionViewer } from './ReactionViewer';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
@ -28,94 +29,94 @@ story.add('All Reactions', () => {
{
emoji: '❤️',
timestamp: 1,
from: {
from: getDefaultConversation({
id: '+14155552671',
phoneNumber: '+14155552671',
profileName: 'Ameila Briggs',
title: 'Amelia',
},
}),
},
{
emoji: '❤️',
timestamp: 2,
from: {
from: getDefaultConversation({
id: '+14155552672',
name: 'Adam Burrel',
title: 'Adam',
},
}),
},
{
emoji: '❤️',
timestamp: 3,
from: {
from: getDefaultConversation({
id: '+14155552673',
name: 'Rick Owens',
title: 'Rick',
},
}),
},
{
emoji: '❤️',
timestamp: 4,
from: {
from: getDefaultConversation({
id: '+14155552674',
name: 'Bojack Horseman',
title: 'Bojack',
},
}),
},
{
emoji: '👍',
timestamp: 9,
from: {
from: getDefaultConversation({
id: '+14155552678',
phoneNumber: '+14155552678',
profileName: 'Adam Burrel',
title: 'Adam',
},
}),
},
{
emoji: '👎',
timestamp: 10,
from: {
from: getDefaultConversation({
id: '+14155552673',
name: 'Rick Owens',
title: 'Rick',
},
}),
},
{
emoji: '😂',
timestamp: 11,
from: {
from: getDefaultConversation({
id: '+14155552674',
name: 'Bojack Horseman',
title: 'Bojack',
},
}),
},
{
emoji: '😮',
timestamp: 12,
from: {
from: getDefaultConversation({
id: '+14155552675',
name: 'Cayce Pollard',
title: 'Cayce',
},
}),
},
{
emoji: '😢',
timestamp: 13,
from: {
from: getDefaultConversation({
id: '+14155552676',
name: 'Foo McBarrington',
title: 'Foo',
},
}),
},
{
emoji: '😡',
timestamp: 14,
from: {
from: getDefaultConversation({
id: '+14155552676',
name: 'Foo McBarrington',
title: 'Foo',
},
}),
},
],
});
@ -128,22 +129,22 @@ story.add('Picked Reaction', () => {
reactions: [
{
emoji: '❤️',
from: {
from: getDefaultConversation({
id: '+14155552671',
name: 'Amelia Briggs',
isMe: true,
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
{
emoji: '👍',
from: {
from: getDefaultConversation({
id: '+14155552671',
phoneNumber: '+14155552671',
profileName: 'Joel Ferrari',
title: 'Joel',
},
}),
timestamp: Date.now(),
},
],
@ -157,22 +158,22 @@ story.add('Picked Missing Reaction', () => {
reactions: [
{
emoji: '❤️',
from: {
from: getDefaultConversation({
id: '+14155552671',
name: 'Amelia Briggs',
isMe: true,
title: 'Amelia',
},
}),
timestamp: Date.now(),
},
{
emoji: '👍',
from: {
from: getDefaultConversation({
id: '+14155552671',
phoneNumber: '+14155552671',
profileName: 'Joel Ferrari',
title: 'Joel',
},
}),
timestamp: Date.now(),
},
],
@ -196,11 +197,11 @@ const createReaction = (
timestamp = Date.now()
) => ({
emoji,
from: {
from: getDefaultConversation({
id: '+14155552671',
name,
title: name,
},
}),
timestamp,
});

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -8,22 +8,25 @@ import { ContactName } from './ContactName';
import { Avatar, Props as AvatarProps } from '../Avatar';
import { Emoji } from '../emoji/Emoji';
import { useRestoreFocus } from '../../util/hooks';
import { ColorType } from '../../types/Colors';
import { ConversationType } from '../../state/ducks/conversations';
import { emojiToData, EmojiData } from '../emoji/lib';
export type Reaction = {
emoji: string;
timestamp: number;
from: {
id: string;
color?: ColorType;
avatarPath?: string;
name?: string;
profileName?: string;
title: string;
isMe?: boolean;
phoneNumber?: string;
};
from: Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'id'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
>;
};
export type OwnProps = {
@ -212,9 +215,12 @@ export const ReactionViewer = React.forwardRef<HTMLDivElement, Props>(
>
<div className="module-reaction-viewer__body__row__avatar">
<Avatar
acceptedMessageRequest={from.acceptedMessageRequest}
avatarPath={from.avatarPath}
conversationType="direct"
sharedGroupNames={from.sharedGroupNames}
size={32}
isMe={from.isMe}
color={from.color}
name={from.name}
profileName={from.profileName}

View File

@ -318,7 +318,9 @@ const getPhoneNumber = () => text('phoneNumber', '+1 (808) 555-1234');
const renderHeroRow = () => (
<ConversationHero
about={getAbout()}
acceptedMessageRequest
i18n={i18n}
isMe={false}
title={getTitle()}
avatarPath={getAvatarPath()}
name={getName()}
@ -333,11 +335,14 @@ const renderHeroRow = () => (
const renderLoadingRow = () => <TimelineLoadingRow state="loading" />;
const renderTypingBubble = () => (
<TypingBubble
acceptedMessageRequest
color="red"
conversationType="direct"
phoneNumber="+18005552222"
i18n={i18n}
isMe={false}
title="title"
sharedGroupNames={[]}
/>
);
@ -456,16 +461,14 @@ story.add('Typing Indicator', () => {
story.add('With invited contacts for a newly-created group', () => {
const props = createProps({
invitedContactsForNewlyCreatedGroup: [
{
getDefaultConversation({
id: 'abc123',
title: 'John Bon Bon Jovi',
type: 'direct',
},
{
}),
getDefaultConversation({
id: 'def456',
title: 'Bon John Bon Jovi',
type: 'direct',
},
}),
],
});

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -15,6 +15,8 @@ const i18n = setupI18n('en', enMessages);
const story = storiesOf('Components/Conversation/TypingBubble', module);
const createProps = (overrideProps: Partial<Props> = {}): Props => ({
acceptedMessageRequest: true,
isMe: false,
i18n,
color: select(
'color',
@ -29,6 +31,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
{ group: 'group', direct: 'direct' },
overrideProps.conversationType || 'direct'
),
sharedGroupNames: [],
});
story.add('Direct', () => {

View File

@ -1,4 +1,4 @@
// Copyright 2018-2020 Signal Messenger, LLC
// Copyright 2018-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
@ -8,15 +8,20 @@ import { TypingAnimation } from './TypingAnimation';
import { Avatar } from '../Avatar';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
import { ConversationType } from '../../state/ducks/conversations';
export type Props = {
avatarPath?: string;
color: ColorType;
name?: string;
phoneNumber?: string;
profileName?: string;
title: string;
export type Props = Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
> & {
conversationType: 'group' | 'direct';
i18n: LocalizerType;
};
@ -24,14 +29,17 @@ export type Props = {
export class TypingBubble extends React.PureComponent<Props> {
public renderAvatar(): JSX.Element | null {
const {
acceptedMessageRequest,
avatarPath,
color,
conversationType,
i18n,
isMe,
name,
phoneNumber,
profileName,
sharedGroupNames,
title,
conversationType,
i18n,
} = this.props;
if (conversationType !== 'group') {
@ -42,14 +50,17 @@ export class TypingBubble extends React.PureComponent<Props> {
<div className="module-message__author-avatar-container">
<div className="module-message__author-avatar">
<Avatar
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color}
conversationType="direct"
i18n={i18n}
isMe={isMe}
name={name}
phoneNumber={phoneNumber}
profileName={profileName}
title={title}
sharedGroupNames={sharedGroupNames}
size={28}
/>
</div>

View File

@ -1,10 +1,10 @@
// Copyright 2019-2020 Signal Messenger, LLC
// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import classNames from 'classnames';
import { Avatar } from '../Avatar';
import { Avatar, AvatarBlur } from '../Avatar';
import { Spinner } from '../Spinner';
import { LocalizerType } from '../../types/Util';
@ -45,11 +45,15 @@ export function renderAvatar({
return (
<Avatar
acceptedMessageRequest={false}
avatarPath={avatarPath}
blur={AvatarBlur.NoBlur}
color="grey"
conversationType="direct"
i18n={i18n}
isMe
title={title}
sharedGroupNames={[]}
size={size}
/>
);

View File

@ -156,10 +156,12 @@ export const ChooseGroupMembersModal: FunctionComponent<PropsType> = ({
color={contact.color}
firstName={contact.firstName}
i18n={i18n}
isMe={contact.isMe}
id={contact.id}
name={contact.name}
phoneNumber={contact.phoneNumber}
profileName={contact.profileName}
sharedGroupNames={contact.sharedGroupNames}
title={contact.title}
onClickRemove={() => {
removeSelectedContact(contact.id);

View File

@ -20,13 +20,13 @@ const story = storiesOf(
module
);
const conversation: ConversationType = {
const conversation: ConversationType = getDefaultConversation({
id: '',
lastUpdated: 0,
markedUnread: false,
title: 'Some Conversation',
type: 'group',
};
sharedGroupNames: [],
});
const createProps = (hasGroupLink = false): Props => ({
addMembers: async () => {

View File

@ -7,6 +7,7 @@ import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { number, text } from '@storybook/addon-knobs';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { setup as setupI18n } from '../../../../js/modules/i18n';
import enMessages from '../../../../_locales/en/messages.json';
import { ConversationType } from '../../../state/ducks/conversations';
@ -20,14 +21,14 @@ const story = storiesOf(
module
);
const createConversation = (): ConversationType => ({
id: '',
markedUnread: false,
type: 'group',
lastUpdated: 0,
title: text('conversation title', 'Some Conversation'),
memberships: new Array(number('conversation members length', 0)),
});
const createConversation = (): ConversationType =>
getDefaultConversation({
id: '',
type: 'group',
lastUpdated: 0,
title: text('conversation title', 'Some Conversation'),
memberships: new Array(number('conversation members length', 0)),
});
const createProps = (overrideProps: Partial<Props> = {}): Props => ({
conversation: createConversation(),

View File

@ -32,6 +32,7 @@ export const ConversationDetailsHeader: React.ComponentType<Props> = ({
i18n={i18n}
size={80}
{...conversation}
sharedGroupNames={[]}
/>
<div>
<div className={bem('title')}>{conversation.title}</div>

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -35,20 +35,20 @@ function getConversation(
groupLink?: string,
accessControlAddFromInviteLink?: number
): ConversationType {
return {
return getDefaultConversation({
id: '',
lastUpdated: 0,
markedUnread: false,
memberships: Array(32).fill({ member: getDefaultConversation({}) }),
pendingMemberships: Array(16).fill({ member: getDefaultConversation({}) }),
title: 'Some Conversation',
type: 'group',
sharedGroupNames: [],
groupLink,
accessControlAddFromInviteLink:
accessControlAddFromInviteLink !== undefined
? accessControlAddFromInviteLink
: AccessEnum.UNSATISFIABLE,
};
});
}
const createProps = (

View File

@ -1,4 +1,4 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -19,15 +19,15 @@ const story = storiesOf(
module
);
const conversation: ConversationType = {
const conversation: ConversationType = getDefaultConversation({
id: '',
lastUpdated: 0,
markedUnread: false,
memberships: Array(32).fill({ member: getDefaultConversation({}) }),
pendingMemberships: Array(16).fill({ member: getDefaultConversation({}) }),
title: 'Some Conversation',
type: 'group',
};
sharedGroupNames: [],
});
class AccessEnum {
static ANY = 0;

View File

@ -27,13 +27,16 @@ const sortedGroupMembers = Array.from(Array(32)).map((_, i) =>
);
const conversation: ConversationType = {
acceptedMessageRequest: true,
areWeAdmin: true,
id: '',
lastUpdated: 0,
markedUnread: false,
isMe: false,
sortedGroupMembers,
title: 'Some Conversation',
type: 'group',
sharedGroupNames: [],
};
const createProps = (): PropsType => ({

View File

@ -124,9 +124,10 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color}
noteToSelf={isAvatarNoteToSelf}
conversationType={conversationType}
noteToSelf={isAvatarNoteToSelf}
i18n={i18n}
isMe={isMe}
name={name}
phoneNumber={phoneNumber}
profileName={profileName}

View File

@ -18,7 +18,7 @@ import { ContactName } from '../conversation/ContactName';
import { TypingAnimation } from '../conversation/TypingAnimation';
import { LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
import { ConversationType } from '../../state/ducks/conversations';
const MESSAGE_STATUS_ICON_CLASS_NAME = `${MESSAGE_TEXT_CLASS_NAME}__status-icon`;
@ -34,37 +34,31 @@ export const MessageStatuses = [
export type MessageStatusType = typeof MessageStatuses[number];
export type PropsData = {
id: string;
phoneNumber?: string;
color?: ColorType;
profileName?: string;
title: string;
name?: string;
type: 'group' | 'direct';
avatarPath?: string;
isMe?: boolean;
muteExpiresAt?: number;
sharedGroupNames?: Array<string>;
unblurredAvatarPath?: string;
lastUpdated?: number;
unreadCount?: number;
markedUnread?: boolean;
isSelected?: boolean;
acceptedMessageRequest?: boolean;
draftPreview?: string;
shouldShowDraft?: boolean;
typingContact?: unknown;
lastMessage?: {
status: MessageStatusType;
text: string;
deletedForEveryone?: boolean;
};
isPinned?: boolean;
};
export type PropsData = Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'draftPreview'
| 'id'
| 'isMe'
| 'isPinned'
| 'isSelected'
| 'lastMessage'
| 'lastUpdated'
| 'markedUnread'
| 'muteExpiresAt'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'shouldShowDraft'
| 'title'
| 'type'
| 'typingContact'
| 'unblurredAvatarPath'
| 'unreadCount'
>;
type PropsHousekeeping = {
i18n: LocalizerType;

View File

@ -18,12 +18,15 @@ export const CreateNewGroupButton: FunctionComponent<PropsType> = React.memo(
return (
<BaseConversationListItem
acceptedMessageRequest={false}
color="grey"
conversationType="group"
headerName={title}
i18n={i18n}
isMe={false}
isSelected={false}
onClick={onClick}
sharedGroupNames={[]}
style={style}
title={title}
/>

View File

@ -9,6 +9,7 @@ import { boolean, text, withKnobs } from '@storybook/addon-knobs';
import { setup as setupI18n } from '../../../js/modules/i18n';
import enMessages from '../../../_locales/en/messages.json';
import { MessageSearchResult, PropsType } from './MessageSearchResult';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
const i18n = setupI18n('en', enMessages);
const story = storiesOf('Components/MessageSearchResult', module);
@ -17,22 +18,23 @@ const story = storiesOf('Components/MessageSearchResult', module);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
story.addDecorator((withKnobs as any)({ escapeHTML: false }));
const someone = {
const someone = getDefaultConversation({
title: 'Some Person',
name: 'Some Person',
phoneNumber: '(202) 555-0011',
};
});
const me = {
const me = getDefaultConversation({
title: 'Me',
name: 'Me',
isMe: true,
};
});
const group = {
const group = getDefaultConversation({
title: 'Group Chat',
name: 'Group Chat',
};
type: 'group',
});
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
i18n,

View File

@ -32,14 +32,17 @@ export const StartNewConversation: FunctionComponent<Props> = React.memo(
return (
<BaseConversationListItem
acceptedMessageRequest={false}
color="grey"
conversationType="direct"
headerName={phoneNumber}
i18n={i18n}
isMe={false}
isSelected={false}
messageText={messageText}
onClick={onClick}
phoneNumber={phoneNumber}
sharedGroupNames={[]}
style={style}
title={phoneNumber}
/>

View File

@ -169,14 +169,17 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
{this.selectedContacts.map(contact => (
<ContactPill
key={contact.id}
acceptedMessageRequest={contact.acceptedMessageRequest}
avatarPath={contact.avatarPath}
color={contact.color}
firstName={contact.firstName}
i18n={i18n}
id={contact.id}
isMe={contact.isMe}
name={contact.name}
phoneNumber={contact.phoneNumber}
profileName={contact.profileName}
sharedGroupNames={contact.sharedGroupNames}
title={contact.title}
onClickRemove={removeSelectedContact}
/>

View File

@ -18,10 +18,7 @@ import {
GroupV2InfoType,
SendOptionsType,
} from '../textsecure/SendMessage';
import {
ConversationType,
ConversationTypeType,
} from '../state/ducks/conversations';
import { ConversationType } from '../state/ducks/conversations';
import { ColorType } from '../types/Colors';
import { MessageModel } from './messages';
import { isMuted } from '../util/isMuted';
@ -1386,7 +1383,6 @@ export class ConversationModel extends window.Backbone
profileSharing: this.get('profileSharing'),
publicParams: this.get('publicParams'),
secretParams: this.get('secretParams'),
sharedGroupNames: this.get('sharedGroupNames'),
shouldShowDraft,
sortedGroupMembers,
timestamp,
@ -1394,8 +1390,16 @@ export class ConversationModel extends window.Backbone
searchableTitle: this.isMe()
? window.i18n('noteToSelf')
: this.getTitle(),
type: (this.isPrivate() ? 'direct' : 'group') as ConversationTypeType,
unreadCount: this.get('unreadCount')! || 0,
...(this.isPrivate()
? {
type: 'direct' as const,
sharedGroupNames: this.get('sharedGroupNames') || [],
}
: {
type: 'group' as const,
sharedGroupNames: [],
}),
};
if (typingContact) {

View File

@ -63,7 +63,16 @@ type PropsForMessageDetail = Pick<
type PropsForMessage = Omit<PropsData, 'interactionMode'>;
type FormattedContact = Partial<ConversationType> &
Pick<ConversationType, 'title' | 'id' | 'type'>;
Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'id'
| 'isMe'
| 'sharedGroupNames'
| 'title'
| 'type'
| 'unblurredAvatarPath'
>;
type PropsForUnsupportedMessage = {
canProcessNow: boolean;
@ -155,10 +164,13 @@ const { getTextWithMentions, GoogleChrome } = window.Signal.Util;
const { addStickerPackReference, getMessageBySender } = window.Signal.Data;
const { bytesFromString } = window.Signal.Crypto;
const PLACEHOLDER_CONTACT: Pick<ConversationType, 'title' | 'type' | 'id'> = {
const PLACEHOLDER_CONTACT: FormattedContact = {
acceptedMessageRequest: false,
id: 'placeholder-contact',
type: 'direct',
isMe: false,
sharedGroupNames: [],
title: window.i18n('unknownContact'),
type: 'direct',
};
const THREE_HOURS = 3 * 60 * 60 * 1000;
@ -1003,10 +1015,13 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
});
return {
acceptedMessageRequest: false,
id: 'phone-only',
type: 'direct',
title: phoneNumber,
isMe: false,
phoneNumber,
sharedGroupNames: [],
title: phoneNumber,
type: 'direct',
};
}

View File

@ -272,11 +272,15 @@ export class MentionCompletion {
)}
>
<Avatar
acceptedMessageRequest={member.acceptedMessageRequest}
avatarPath={member.avatarPath}
conversationType="direct"
i18n={this.options.i18n}
isMe={member.isMe}
sharedGroupNames={member.sharedGroupNames}
size={28}
title={member.title}
unblurredAvatarPath={member.unblurredAvatarPath}
/>
<div className="module-composition-input__suggestions__title">
{member.title}

View File

@ -106,7 +106,7 @@ export type ConversationType = {
}>;
muteExpiresAt?: number;
type: ConversationTypeType;
isMe?: boolean;
isMe: boolean;
lastUpdated?: number;
// This is used by the CompositionInput for @mentions
sortedGroupMembers?: Array<ConversationType>;
@ -129,12 +129,12 @@ export type ConversationType = {
draftBodyRanges?: Array<BodyRangeType>;
draftPreview?: string;
sharedGroupNames?: Array<string>;
sharedGroupNames: Array<string>;
groupVersion?: 1 | 2;
groupId?: string;
groupLink?: string;
messageRequestsEnabled?: boolean;
acceptedMessageRequest?: boolean;
acceptedMessageRequest: boolean;
secretParams?: string;
publicParams?: string;
};

View File

@ -45,9 +45,12 @@ export const getPlaceholderContact = (): ConversationType => {
}
placeholderContact = {
acceptedMessageRequest: false,
id: 'placeholder-contact',
type: 'direct',
title: window.i18n('unknownContact'),
isMe: false,
sharedGroupNames: [],
};
return placeholderContact;
};

View File

@ -321,12 +321,15 @@ export function getDefaultConversation(
const lastName = getLastName();
return {
id: generateUuid(),
isGroupV2Capable: true,
lastUpdated: Date.now(),
markedUnread: Boolean(overrideProps.markedUnread),
acceptedMessageRequest: true,
e164: '+1300555000',
firstName,
id: generateUuid(),
isGroupV2Capable: true,
isMe: false,
lastUpdated: Date.now(),
markedUnread: Boolean(overrideProps.markedUnread),
sharedGroupNames: [],
title: `${firstName} ${lastName}`,
type: 'direct' as const,
uuid: generateUuid(),

View File

@ -42,19 +42,19 @@ import { noopAction } from '../../../state/ducks/noop';
import { StateType, reducer as rootReducer } from '../../../state/reducer';
import { setup as setupI18n } from '../../../../js/modules/i18n';
import enMessages from '../../../../_locales/en/messages.json';
import { getDefaultConversation } from '../../helpers/getDefaultConversation';
describe('both/state/selectors/conversations', () => {
const getEmptyRootState = (): StateType => {
return rootReducer(undefined, noopAction());
};
function getDefaultConversation(id: string): ConversationType {
return {
function makeConversation(id: string): ConversationType {
return getDefaultConversation({
id,
type: 'direct',
searchableTitle: `${id} title`,
title: `${id} title`,
};
});
}
const i18n = setupI18n('en', enMessages);
@ -64,7 +64,7 @@ describe('both/state/selectors/conversations', () => {
...getEmptyRootState(),
conversations: {
...getEmptyState(),
conversationLookup: { abc123: getDefaultConversation('abc123') },
conversationLookup: { abc123: makeConversation('abc123') },
},
};
@ -104,8 +104,8 @@ describe('both/state/selectors/conversations', () => {
it('returns conversation by e164 first', () => {
const id = 'id';
const conversation = getDefaultConversation(id);
const wrongConversation = getDefaultConversation('wrong');
const conversation = makeConversation(id);
const wrongConversation = makeConversation('wrong');
const state = {
...getEmptyRootState(),
@ -135,8 +135,8 @@ describe('both/state/selectors/conversations', () => {
it('returns conversation by uuid', () => {
const id = 'id';
const conversation = getDefaultConversation(id);
const wrongConversation = getDefaultConversation('wrong');
const conversation = makeConversation(id);
const wrongConversation = makeConversation('wrong');
const state = {
...getEmptyRootState(),
@ -163,8 +163,8 @@ describe('both/state/selectors/conversations', () => {
it('returns conversation by groupId', () => {
const id = 'id';
const conversation = getDefaultConversation(id);
const wrongConversation = getDefaultConversation('wrong');
const conversation = makeConversation(id);
const wrongConversation = makeConversation('wrong');
const state = {
...getEmptyRootState(),
@ -188,7 +188,7 @@ describe('both/state/selectors/conversations', () => {
it('returns conversation by conversationId', () => {
const id = 'id';
const conversation = getDefaultConversation(id);
const conversation = makeConversation(id);
const state = {
...getEmptyRootState(),
@ -212,7 +212,7 @@ describe('both/state/selectors/conversations', () => {
it('does proper caching of result', () => {
const id = 'id';
const conversation = getDefaultConversation(id);
const conversation = makeConversation(id);
const state = {
...getEmptyRootState(),
@ -248,7 +248,7 @@ describe('both/state/selectors/conversations', () => {
conversations: {
...getEmptyState(),
conversationLookup: {
[id]: getDefaultConversation('third'),
[id]: makeConversation('third'),
},
},
};
@ -273,8 +273,8 @@ describe('both/state/selectors/conversations', () => {
conversations: {
...getEmptyState(),
conversationLookup: {
abc: getDefaultConversation('abc'),
def: getDefaultConversation('def'),
abc: makeConversation('abc'),
def: makeConversation('def'),
},
invitedConversationIdsForNewlyCreatedGroup: ['def', 'abc'],
},
@ -487,7 +487,7 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'our-conversation-id': {
...getDefaultConversation('our-conversation-id'),
...makeConversation('our-conversation-id'),
isMe: true,
profileName: 'My own name',
},
@ -505,44 +505,44 @@ describe('both/state/selectors/conversations', () => {
const result = getRootState();
Object.assign(result.conversations.conversationLookup, {
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
type: 'direct',
profileName: 'A',
title: 'A',
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
type: 'group',
isGroupV1AndDisabled: true,
name: '2',
title: 'Should Be Dropped (GV1)',
},
'convo-3': {
...getDefaultConversation('convo-3'),
...makeConversation('convo-3'),
type: 'group',
name: 'B',
title: 'B',
},
'convo-4': {
...getDefaultConversation('convo-4'),
...makeConversation('convo-4'),
isBlocked: true,
name: '4',
title: 'Should Be Dropped (blocked)',
},
'convo-5': {
...getDefaultConversation('convo-5'),
...makeConversation('convo-5'),
discoveredUnregisteredAt: new Date(1999, 3, 20).getTime(),
name: 'C',
title: 'C',
},
'convo-6': {
...getDefaultConversation('convo-6'),
...makeConversation('convo-6'),
profileSharing: true,
name: 'Should Be Droped (no title)',
title: null,
},
'convo-7': {
...getDefaultConversation('convo-7'),
...makeConversation('convo-7'),
discoveredUnregisteredAt: Date.now(),
name: '7',
title: 'Should Be Dropped (unregistered)',
@ -574,7 +574,7 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'our-conversation-id': {
...getDefaultConversation('our-conversation-id'),
...makeConversation('our-conversation-id'),
isMe: true,
},
},
@ -594,17 +594,18 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'convo-0': {
...getDefaultConversation('convo-0'),
...makeConversation('convo-0'),
isMe: true,
profileSharing: false,
},
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
type: 'group' as const,
name: 'Friends!',
sharedGroupNames: [],
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
name: 'Alice',
},
},
@ -623,17 +624,17 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'convo-0': {
...getDefaultConversation('convo-0'),
...makeConversation('convo-0'),
name: 'Ex',
isBlocked: true,
},
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
name: 'Bob',
discoveredUnregisteredAt: Date.now(),
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
name: 'Charlie',
},
},
@ -656,7 +657,7 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'our-conversation-id': {
...getDefaultConversation('our-conversation-id'),
...makeConversation('our-conversation-id'),
isMe: true,
},
},
@ -676,17 +677,18 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'convo-0': {
...getDefaultConversation('convo-0'),
...makeConversation('convo-0'),
isMe: true,
name: 'Me!',
},
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
type: 'group' as const,
name: 'Friends!',
sharedGroupNames: [],
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
name: 'Alice',
},
},
@ -705,17 +707,17 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'convo-0': {
...getDefaultConversation('convo-0'),
...makeConversation('convo-0'),
name: 'Ex',
isBlocked: true,
},
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
name: 'Bob',
discoveredUnregisteredAt: Date.now(),
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
name: 'Charlie',
},
},
@ -738,7 +740,7 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'our-conversation-id': {
...getDefaultConversation('our-conversation-id'),
...makeConversation('our-conversation-id'),
isMe: true,
},
},
@ -758,18 +760,20 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'convo-0': {
...getDefaultConversation('convo-0'),
...makeConversation('convo-0'),
isMe: true,
name: 'Me!',
},
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
type: 'group' as const,
name: 'Friends!',
sharedGroupNames: [],
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
type: 'group' as const,
sharedGroupNames: [],
},
},
},
@ -787,19 +791,22 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'convo-0': {
...getDefaultConversation('convo-0'),
...makeConversation('convo-0'),
type: 'group' as const,
name: 'Family!',
isBlocked: true,
sharedGroupNames: [],
},
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
type: 'group' as const,
name: 'Friends!',
sharedGroupNames: [],
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
type: 'group' as const,
sharedGroupNames: [],
},
},
},
@ -821,7 +828,7 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'our-conversation-id': {
...getDefaultConversation('our-conversation-id'),
...makeConversation('our-conversation-id'),
name: 'Me, Myself, and I',
title: 'Me, Myself, and I',
searchableTitle: 'Note to Self',
@ -845,38 +852,38 @@ describe('both/state/selectors/conversations', () => {
const result = getRootState(searchTerm);
Object.assign(result.conversations.conversationLookup, {
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
name: 'In System Contacts',
title: 'A. Sorted First',
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
title: 'Should Be Dropped (no name, no profile sharing)',
},
'convo-3': {
...getDefaultConversation('convo-3'),
...makeConversation('convo-3'),
type: 'group',
title: 'Should Be Dropped (group)',
},
'convo-4': {
...getDefaultConversation('convo-4'),
...makeConversation('convo-4'),
isBlocked: true,
title: 'Should Be Dropped (blocked)',
},
'convo-5': {
...getDefaultConversation('convo-5'),
...makeConversation('convo-5'),
discoveredUnregisteredAt: new Date(1999, 3, 20).getTime(),
name: 'In System Contacts (and unregistered too long ago)',
title: 'B. Sorted Second',
},
'convo-6': {
...getDefaultConversation('convo-6'),
...makeConversation('convo-6'),
profileSharing: true,
profileName: 'C. Has Profile Sharing',
title: 'C. Has Profile Sharing',
},
'convo-7': {
...getDefaultConversation('convo-7'),
...makeConversation('convo-7'),
discoveredUnregisteredAt: Date.now(),
title: 'Should Be Dropped (unregistered)',
},
@ -939,47 +946,52 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'our-conversation-id': {
...getDefaultConversation('our-conversation-id'),
...makeConversation('our-conversation-id'),
isMe: true,
},
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
name: 'In System Contacts',
title: 'Should be dropped (contact)',
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
title: 'Should be dropped (contact)',
},
'convo-3': {
...getDefaultConversation('convo-3'),
...makeConversation('convo-3'),
type: 'group',
name: 'Hello World',
title: 'Hello World',
sharedGroupNames: [],
},
'convo-4': {
...getDefaultConversation('convo-4'),
...makeConversation('convo-4'),
type: 'group',
isBlocked: true,
title: 'Should be dropped (blocked)',
sharedGroupNames: [],
},
'convo-5': {
...getDefaultConversation('convo-5'),
...makeConversation('convo-5'),
type: 'group',
title: 'Unknown Group',
sharedGroupNames: [],
},
'convo-6': {
...getDefaultConversation('convo-6'),
...makeConversation('convo-6'),
type: 'group',
name: 'Signal',
title: 'Signal',
sharedGroupNames: [],
},
'convo-7': {
...getDefaultConversation('convo-7'),
...makeConversation('convo-7'),
profileSharing: false,
type: 'group',
name: 'Signal Fake',
title: 'Signal Fake',
sharedGroupNames: [],
},
},
composer: {
@ -1021,37 +1033,38 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'our-conversation-id': {
...getDefaultConversation('our-conversation-id'),
...makeConversation('our-conversation-id'),
isMe: true,
},
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
name: 'In System Contacts',
title: 'A. Sorted First',
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
title: 'Should be dropped (has no name)',
},
'convo-3': {
...getDefaultConversation('convo-3'),
...makeConversation('convo-3'),
type: 'group',
title: 'Should Be Dropped (group)',
sharedGroupNames: [],
},
'convo-4': {
...getDefaultConversation('convo-4'),
...makeConversation('convo-4'),
isBlocked: true,
name: 'My Name',
title: 'Should Be Dropped (blocked)',
},
'convo-5': {
...getDefaultConversation('convo-5'),
...makeConversation('convo-5'),
discoveredUnregisteredAt: new Date(1999, 3, 20).getTime(),
name: 'In System Contacts (and unregistered too long ago)',
title: 'C. Sorted Third',
},
'convo-6': {
...getDefaultConversation('convo-6'),
...makeConversation('convo-6'),
discoveredUnregisteredAt: Date.now(),
name: 'My Name',
title: 'Should Be Dropped (unregistered)',
@ -1133,7 +1146,7 @@ describe('both/state/selectors/conversations', () => {
});
it('returns the marked contact', () => {
const conversation = getDefaultConversation('abc123');
const conversation = makeConversation('abc123');
assert.deepEqual(
getCantAddContactForModal({
@ -1179,7 +1192,7 @@ describe('both/state/selectors/conversations', () => {
describe('#_getLeftPaneLists', () => {
it('sorts conversations based on timestamp then by intl-friendly title', () => {
const data: ConversationLookupType = {
id1: {
id1: getDefaultConversation({
id: 'id1',
e164: '+18005551111',
activeAt: Date.now(),
@ -1203,8 +1216,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
id2: {
}),
id2: getDefaultConversation({
id: 'id2',
e164: '+18005551111',
activeAt: Date.now(),
@ -1228,8 +1241,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
id3: {
}),
id3: getDefaultConversation({
id: 'id3',
e164: '+18005551111',
activeAt: Date.now(),
@ -1253,8 +1266,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
id4: {
}),
id4: getDefaultConversation({
id: 'id4',
e164: '+18005551111',
activeAt: Date.now(),
@ -1278,8 +1291,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
id5: {
}),
id5: getDefaultConversation({
id: 'id5',
e164: '+18005551111',
activeAt: Date.now(),
@ -1303,7 +1316,7 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
}),
};
const comparator = _getConversationComparator();
const {
@ -1327,7 +1340,7 @@ describe('both/state/selectors/conversations', () => {
describe('given pinned conversations', () => {
it('sorts pinned conversations based on order in storage', () => {
const data: ConversationLookupType = {
pin2: {
pin2: getDefaultConversation({
id: 'pin2',
e164: '+18005551111',
activeAt: Date.now(),
@ -1352,8 +1365,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
pin3: {
}),
pin3: getDefaultConversation({
id: 'pin3',
e164: '+18005551111',
activeAt: Date.now(),
@ -1378,8 +1391,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
pin1: {
}),
pin1: getDefaultConversation({
id: 'pin1',
e164: '+18005551111',
activeAt: Date.now(),
@ -1404,7 +1417,7 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
}),
};
const pinnedConversationIds = ['pin1', 'pin2', 'pin3'];
@ -1431,7 +1444,7 @@ describe('both/state/selectors/conversations', () => {
it('includes archived and pinned conversations with no active_at', () => {
const data: ConversationLookupType = {
pin2: {
pin2: getDefaultConversation({
id: 'pin2',
e164: '+18005551111',
name: 'Pin Two',
@ -1455,8 +1468,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
pin3: {
}),
pin3: getDefaultConversation({
id: 'pin3',
e164: '+18005551111',
name: 'Pin Three',
@ -1480,8 +1493,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
pin1: {
}),
pin1: getDefaultConversation({
id: 'pin1',
e164: '+18005551111',
name: 'Pin One',
@ -1505,8 +1518,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
pin4: {
}),
pin4: getDefaultConversation({
id: 'pin1',
e164: '+18005551111',
name: 'Pin Four',
@ -1531,8 +1544,8 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
pin5: {
}),
pin5: getDefaultConversation({
id: 'pin1',
e164: '+18005551111',
name: 'Pin Five',
@ -1556,7 +1569,7 @@ describe('both/state/selectors/conversations', () => {
},
acceptedMessageRequest: true,
},
}),
};
const pinnedConversationIds = ['pin1', 'pin2', 'pin3'];
@ -1713,11 +1726,11 @@ describe('both/state/selectors/conversations', () => {
...getEmptyState(),
conversationLookup: {
'convo-1': {
...getDefaultConversation('convo-1'),
...makeConversation('convo-1'),
title: 'Person One',
},
'convo-2': {
...getDefaultConversation('convo-2'),
...makeConversation('convo-2'),
title: 'Person Two',
},
},
@ -1749,9 +1762,9 @@ describe('both/state/selectors/conversations', () => {
conversations: {
...getEmptyState(),
conversationLookup: {
abc: { ...getDefaultConversation('abc'), title: 'Janet' },
def: { ...getDefaultConversation('def'), title: 'Janet' },
geh: { ...getDefaultConversation('geh'), title: 'Rick' },
abc: { ...makeConversation('abc'), title: 'Janet' },
def: { ...makeConversation('def'), title: 'Janet' },
geh: { ...makeConversation('geh'), title: 'Rick' },
},
},
};
@ -1778,7 +1791,7 @@ describe('both/state/selectors/conversations', () => {
conversations: {
...getEmptyState(),
conversationLookup: {
abc123: getDefaultConversation('abc123'),
abc123: makeConversation('abc123'),
},
},
};
@ -1791,7 +1804,7 @@ describe('both/state/selectors/conversations', () => {
conversations: {
...getEmptyState(),
conversationLookup: {
abc123: getDefaultConversation('abc123'),
abc123: makeConversation('abc123'),
},
selectedConversationId: 'abc123',
},
@ -1807,28 +1820,26 @@ describe('both/state/selectors/conversations', () => {
conversations: {
...getEmptyState(),
conversationLookup: {
abc123: getDefaultConversation('abc123'),
abc123: makeConversation('abc123'),
},
},
};
assert.isUndefined(getSelectedConversation(state));
});
it('returns the selected conversation ID', () => {
it('returns the selected conversation', () => {
const conversation = makeConversation('abc123');
const state = {
...getEmptyRootState(),
conversations: {
...getEmptyState(),
conversationLookup: {
abc123: getDefaultConversation('abc123'),
abc123: conversation,
},
selectedConversationId: 'abc123',
},
};
assert.deepEqual(
getSelectedConversation(state),
getDefaultConversation('abc123')
);
assert.strictEqual(getSelectedConversation(state), conversation);
});
});
});

View File

@ -19,6 +19,7 @@ import {
getSearchResults,
} from '../../../state/selectors/search';
import { makeLookup } from '../../../util/makeLookup';
import { getDefaultConversation } from '../../helpers/getDefaultConversation';
import { StateType, reducer as rootReducer } from '../../../state/reducer';
@ -50,14 +51,6 @@ describe('both/state/selectors/search', () => {
};
}
function getDefaultConversation(id: string): ConversationType {
return {
id,
type: 'direct',
title: `${id} title`,
};
}
describe('#getMessageSearchResultSelector', () => {
it('returns undefined if message not found in lookup', () => {
const state = getEmptyRootState();
@ -97,8 +90,8 @@ describe('both/state/selectors/search', () => {
const fromId = 'from-id';
const toId = 'to-id';
const from = getDefaultConversation(fromId);
const to = getDefaultConversation(toId);
const from = getDefaultConversation({ id: fromId });
const to = getDefaultConversation({ id: toId });
const state = {
...getEmptyRootState(),
@ -151,8 +144,8 @@ describe('both/state/selectors/search', () => {
const toId = fromId;
const myId = 'my-id';
const from = getDefaultConversation(fromId);
const meAsRecipient = getDefaultConversation(myId);
const from = getDefaultConversation({ id: fromId });
const meAsRecipient = getDefaultConversation({ id: myId });
const state = {
...getEmptyRootState(),
@ -195,8 +188,8 @@ describe('both/state/selectors/search', () => {
const fromId = 'from-id';
const toId = 'to-id';
const from = getDefaultConversation(fromId);
const to = getDefaultConversation(toId);
const from = getDefaultConversation({ id: fromId });
const to = getDefaultConversation({ id: toId });
const state = {
...getEmptyRootState(),
@ -302,13 +295,13 @@ describe('both/state/selectors/search', () => {
it('returns loaded search results', () => {
const conversations: Array<ConversationType> = [
getDefaultConversation('1'),
getDefaultConversation('2'),
getDefaultConversation({ id: '1' }),
getDefaultConversation({ id: '2' }),
];
const contacts: Array<ConversationType> = [
getDefaultConversation('3'),
getDefaultConversation('4'),
getDefaultConversation('5'),
getDefaultConversation({ id: '3' }),
getDefaultConversation({ id: '4' }),
getDefaultConversation({ id: '5' }),
];
const messages: Array<MessageSearchResultType> = [
getDefaultSearchMessage('a'),

View File

@ -84,13 +84,6 @@ describe('shouldBlurAvatar', () => {
});
it('returns true if the stars align (i.e., not everything above)', () => {
assert.isTrue(
shouldBlurAvatar({
avatarPath: '/path/to/avatar.jpg',
acceptedMessageRequest: false,
isMe: false,
})
);
assert.isTrue(
shouldBlurAvatar({
avatarPath: '/path/to/avatar.jpg',

View File

@ -13,8 +13,9 @@ import {
} from '../../../quill/mentions/completion';
import { ConversationType } from '../../../state/ducks/conversations';
import { MemberRepository } from '../../../quill/memberRepository';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
const me: ConversationType = {
const me: ConversationType = getDefaultConversation({
id: '666777',
uuid: 'pqrstuv',
title: 'Fred Savage',
@ -24,10 +25,11 @@ const me: ConversationType = {
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
};
isMe: true,
});
const members: Array<ConversationType> = [
{
getDefaultConversation({
id: '555444',
uuid: 'abcdefg',
title: 'Mahershala Ali',
@ -37,8 +39,8 @@ const members: Array<ConversationType> = [
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
},
{
}),
getDefaultConversation({
id: '333222',
uuid: 'hijklmno',
title: 'Shia LaBeouf',
@ -48,7 +50,7 @@ const members: Array<ConversationType> = [
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
},
}),
me,
];

View File

@ -25,6 +25,7 @@ import {
} from '../../../state/ducks/conversations';
import { CallMode } from '../../../types/Calling';
import * as groups from '../../../groups';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
const {
cantAddContactToGroup,
@ -72,31 +73,7 @@ describe('both/state/ducks/conversations', () => {
describe('helpers', () => {
describe('getConversationCallMode', () => {
const fakeConversation: ConversationType = {
id: 'id1',
e164: '+18005551111',
activeAt: Date.now(),
name: 'No timestamp',
timestamp: 0,
inboxPosition: 0,
phoneNumber: 'notused',
isArchived: false,
markedUnread: false,
type: 'direct',
isMe: false,
lastUpdated: Date.now(),
title: 'No timestamp',
unreadCount: 1,
isSelected: false,
typingContact: {
name: 'Someone There',
color: 'blue',
phoneNumber: '+18005551111',
},
acceptedMessageRequest: true,
};
const fakeConversation: ConversationType = getDefaultConversation();
it("returns CallMode.None if you've left the conversation", () => {
assert.strictEqual(
@ -144,6 +121,7 @@ describe('both/state/ducks/conversations', () => {
...fakeConversation,
type: 'group',
groupVersion: 1,
sharedGroupNames: [],
}),
CallMode.None
);
@ -152,6 +130,7 @@ describe('both/state/ducks/conversations', () => {
getConversationCallMode({
...fakeConversation,
type: 'group',
sharedGroupNames: [],
}),
CallMode.None
);
@ -170,6 +149,7 @@ describe('both/state/ducks/conversations', () => {
...fakeConversation,
type: 'group',
groupVersion: 2,
sharedGroupNames: [],
}),
CallMode.Group
);
@ -177,14 +157,6 @@ describe('both/state/ducks/conversations', () => {
});
describe('updateConversationLookups', () => {
function getDefaultConversation(id: string): ConversationType {
return {
id,
type: 'direct',
title: `${id} title`,
};
}
it('does not change lookups if no conversations provided', () => {
const state = getEmptyState();
const result = updateConversationLookups(undefined, undefined, state);
@ -204,24 +176,26 @@ describe('both/state/ducks/conversations', () => {
});
it('adds and removes e164-only contact', () => {
const removed = {
...getDefaultConversation('id-removed'),
const removed = getDefaultConversation({
id: 'id-removed',
e164: 'e164-removed',
};
uuid: undefined,
});
const state = {
...getEmptyState(),
conversationsByE164: {
[removed.e164]: removed,
'e164-removed': removed,
},
};
const added = {
...getDefaultConversation('id-added'),
const added = getDefaultConversation({
id: 'id-added',
e164: 'e164-added',
};
uuid: undefined,
});
const expected = {
[added.e164]: added,
'e164-added': added,
};
const actual = updateConversationLookups(added, removed, state);
@ -238,24 +212,26 @@ describe('both/state/ducks/conversations', () => {
});
it('adds and removes uuid-only contact', () => {
const removed = {
...getDefaultConversation('id-removed'),
const removed = getDefaultConversation({
id: 'id-removed',
uuid: 'uuid-removed',
};
e164: undefined,
});
const state = {
...getEmptyState(),
conversationsByuuid: {
[removed.uuid]: removed,
'uuid-removed': removed,
},
};
const added = {
...getDefaultConversation('id-added'),
const added = getDefaultConversation({
id: 'id-added',
uuid: 'uuid-added',
};
e164: undefined,
});
const expected = {
[added.uuid]: added,
'uuid-added': added,
};
const actual = updateConversationLookups(added, removed, state);
@ -272,24 +248,28 @@ describe('both/state/ducks/conversations', () => {
});
it('adds and removes groupId-only contact', () => {
const removed = {
...getDefaultConversation('id-removed'),
const removed = getDefaultConversation({
id: 'id-removed',
groupId: 'groupId-removed',
};
e164: undefined,
uuid: undefined,
});
const state = {
...getEmptyState(),
conversationsBygroupId: {
[removed.groupId]: removed,
'groupId-removed': removed,
},
};
const added = {
...getDefaultConversation('id-added'),
const added = getDefaultConversation({
id: 'id-added',
groupId: 'groupId-added',
};
e164: undefined,
uuid: undefined,
});
const expected = {
[added.groupId]: added,
'groupId-added': added,
};
const actual = updateConversationLookups(added, removed, state);
@ -420,14 +400,13 @@ describe('both/state/ducks/conversations', () => {
});
it('shows the inbox if the conversation is not archived', () => {
const conversation = getDefaultConversation({
id: 'fake-conversation-id',
});
const state = {
...getEmptyState(),
conversationLookup: {
'fake-conversation-id': {
id: 'fake-conversation-id',
type: 'direct' as const,
title: 'Foo Bar',
},
[conversation.id]: conversation,
},
};
const result = reducer(state, action);
@ -437,15 +416,14 @@ describe('both/state/ducks/conversations', () => {
});
it('shows the archive if the conversation is archived', () => {
const conversation = getDefaultConversation({
id: 'fake-conversation-id',
isArchived: true,
});
const state = {
...getEmptyState(),
conversationLookup: {
'fake-conversation-id': {
id: 'fake-conversation-id',
type: 'group' as const,
title: 'Baz Qux',
isArchived: true,
},
[conversation.id]: conversation,
},
};
const result = reducer(state, action);

View File

@ -6,16 +6,11 @@ import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { LeftPaneArchiveHelper } from '../../../components/leftPane/LeftPaneArchiveHelper';
describe('LeftPaneArchiveHelper', () => {
const fakeConversation = () => ({
id: uuid(),
title: uuid(),
type: 'direct' as const,
});
describe('getBackAction', () => {
it('returns the "show inbox" action', () => {
const showInbox = sinon.fake();
@ -33,7 +28,10 @@ describe('LeftPaneArchiveHelper', () => {
);
assert.strictEqual(
new LeftPaneArchiveHelper({
archivedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
}).getRowCount(),
2
);
@ -43,7 +41,10 @@ describe('LeftPaneArchiveHelper', () => {
describe('getRowIndexToScrollTo', () => {
it('returns undefined if no conversation is selected', () => {
const helper = new LeftPaneArchiveHelper({
archivedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
});
assert.isUndefined(helper.getRowIndexToScrollTo(undefined));
@ -51,14 +52,20 @@ describe('LeftPaneArchiveHelper', () => {
it('returns undefined if the selected conversation is not pinned or non-pinned', () => {
const helper = new LeftPaneArchiveHelper({
archivedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
});
assert.isUndefined(helper.getRowIndexToScrollTo(uuid()));
});
it("returns the archived conversation's index", () => {
const archivedConversations = [fakeConversation(), fakeConversation()];
const archivedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneArchiveHelper({ archivedConversations });
assert.strictEqual(
@ -74,7 +81,10 @@ describe('LeftPaneArchiveHelper', () => {
describe('getRow', () => {
it('returns each conversation as a row', () => {
const archivedConversations = [fakeConversation(), fakeConversation()];
const archivedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneArchiveHelper({ archivedConversations });
assert.deepEqual(helper.getRow(0), {
@ -90,7 +100,10 @@ describe('LeftPaneArchiveHelper', () => {
describe('getConversationAndMessageAtIndex', () => {
it('returns the conversation at the given index when it exists', () => {
const archivedConversations = [fakeConversation(), fakeConversation()];
const archivedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneArchiveHelper({ archivedConversations });
assert.strictEqual(
@ -104,7 +117,10 @@ describe('LeftPaneArchiveHelper', () => {
});
it('when requesting an index out of bounds, returns the last conversation', () => {
const archivedConversations = [fakeConversation(), fakeConversation()];
const archivedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneArchiveHelper({ archivedConversations });
assert.strictEqual(
@ -135,7 +151,10 @@ describe('LeftPaneArchiveHelper', () => {
describe('getConversationAndMessageInDirection', () => {
it('returns the next conversation when searching downward', () => {
const archivedConversations = [fakeConversation(), fakeConversation()];
const archivedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneArchiveHelper({ archivedConversations });
assert.deepEqual(
@ -154,17 +173,23 @@ describe('LeftPaneArchiveHelper', () => {
describe('shouldRecomputeRowHeights', () => {
it('always returns false because row heights are constant', () => {
const helper = new LeftPaneArchiveHelper({
archivedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
});
assert.isFalse(
helper.shouldRecomputeRowHeights({
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
})
);
assert.isFalse(
helper.shouldRecomputeRowHeights({
archivedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
})
);
});

View File

@ -4,10 +4,10 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { times } from 'lodash';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
import * as remoteConfig from '../../../RemoteConfig';
import { ContactCheckboxDisabledReason } from '../../../components/conversationList/ContactCheckbox';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { LeftPaneChooseGroupMembersHelper } from '../../../components/leftPane/LeftPaneChooseGroupMembersHelper';
@ -21,13 +21,6 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
selectedContacts: [],
};
const fakeContact = () => ({
id: uuid(),
isGroupV2Capable: true,
title: uuid(),
type: 'direct' as const,
});
let sinonSandbox: sinon.SinonSandbox;
beforeEach(() => {
@ -64,7 +57,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
...defaults,
candidateContacts: [],
searchTerm: '',
selectedContacts: [fakeContact()],
selectedContacts: [getDefaultConversation()],
}).getRowCount(),
0
);
@ -73,7 +66,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
...defaults,
candidateContacts: [],
searchTerm: 'foo bar',
selectedContacts: [fakeContact()],
selectedContacts: [getDefaultConversation()],
}).getRowCount(),
0
);
@ -83,9 +76,12 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
assert.strictEqual(
new LeftPaneChooseGroupMembersHelper({
...defaults,
candidateContacts: [fakeContact(), fakeContact()],
candidateContacts: [
getDefaultConversation(),
getDefaultConversation(),
],
searchTerm: '',
selectedContacts: [fakeContact()],
selectedContacts: [getDefaultConversation()],
}).getRowCount(),
4
);
@ -99,7 +95,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
...defaults,
candidateContacts: [],
searchTerm: '',
selectedContacts: [fakeContact()],
selectedContacts: [getDefaultConversation()],
}).getRow(0)
);
assert.isUndefined(
@ -107,7 +103,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
...defaults,
candidateContacts: [],
searchTerm: '',
selectedContacts: [fakeContact()],
selectedContacts: [getDefaultConversation()],
}).getRow(99)
);
assert.isUndefined(
@ -115,13 +111,16 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
...defaults,
candidateContacts: [],
searchTerm: 'foo bar',
selectedContacts: [fakeContact()],
selectedContacts: [getDefaultConversation()],
}).getRow(0)
);
});
it('returns a header, then the contacts, then a blank space if there are contacts', () => {
const candidateContacts = [fakeContact(), fakeContact()];
const candidateContacts = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneChooseGroupMembersHelper({
...defaults,
candidateContacts,
@ -149,7 +148,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
});
it("disables non-selected contact checkboxes if you've selected the maximum number of contacts", () => {
const candidateContacts = times(50, () => fakeContact());
const candidateContacts = times(50, () => getDefaultConversation());
const helper = new LeftPaneChooseGroupMembersHelper({
...defaults,
candidateContacts,
@ -173,9 +172,9 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
it("disables contacts that aren't GV2-capable, unless they are already selected somehow", () => {
const candidateContacts = [
{ ...fakeContact(), isGroupV2Capable: false },
{ ...fakeContact(), isGroupV2Capable: undefined },
{ ...fakeContact(), isGroupV2Capable: false },
{ ...getDefaultConversation(), isGroupV2Capable: false },
{ ...getDefaultConversation(), isGroupV2Capable: undefined },
{ ...getDefaultConversation(), isGroupV2Capable: false },
];
const helper = new LeftPaneChooseGroupMembersHelper({

View File

@ -3,20 +3,14 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
import * as remoteConfig from '../../../RemoteConfig';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { LeftPaneComposeHelper } from '../../../components/leftPane/LeftPaneComposeHelper';
describe('LeftPaneComposeHelper', () => {
const fakeConvo = () => ({
id: uuid(),
title: uuid(),
type: 'direct' as const,
});
let sinonSandbox: sinon.SinonSandbox;
let remoteConfigStub: sinon.SinonStub;
@ -65,7 +59,7 @@ describe('LeftPaneComposeHelper', () => {
it('returns the number of contacts + 2 (for the "new group" button and header) if not searching', () => {
assert.strictEqual(
new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: '',
@ -77,8 +71,8 @@ describe('LeftPaneComposeHelper', () => {
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()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [getDefaultConversation(), getDefaultConversation()],
regionCode: 'US',
searchTerm: '',
}).getRowCount(),
@ -98,7 +92,7 @@ describe('LeftPaneComposeHelper', () => {
);
assert.strictEqual(
new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -107,8 +101,8 @@ describe('LeftPaneComposeHelper', () => {
);
assert.strictEqual(
new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeGroups: [fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [getDefaultConversation()],
regionCode: 'US',
searchTerm: 'foo bar',
}).getRowCount(),
@ -131,7 +125,7 @@ describe('LeftPaneComposeHelper', () => {
it('returns the number of contacts + 2 (for the "Start new conversation" button and header) if searching for a phone number', () => {
assert.strictEqual(
new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: '+16505551234',
@ -157,7 +151,10 @@ describe('LeftPaneComposeHelper', () => {
});
it('returns a "new group" button, a header, and contacts if not searching', () => {
const composeContacts = [fakeConvo(), fakeConvo()];
const composeContacts = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneComposeHelper({
composeContacts,
composeGroups: [],
@ -183,8 +180,14 @@ 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 composeContacts = [
getDefaultConversation(),
getDefaultConversation(),
];
const composeGroups = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneComposeHelper({
composeContacts,
composeGroups,
@ -266,7 +269,10 @@ describe('LeftPaneComposeHelper', () => {
});
it('returns one row per contact if searching', () => {
const composeContacts = [fakeConvo(), fakeConvo()];
const composeContacts = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneComposeHelper({
composeContacts,
composeGroups: [],
@ -300,7 +306,10 @@ describe('LeftPaneComposeHelper', () => {
});
it('returns a "start new conversation" row, a header, and contacts if searching for a phone number', () => {
const composeContacts = [fakeConvo(), fakeConvo()];
const composeContacts = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneComposeHelper({
composeContacts,
composeGroups: [],
@ -330,7 +339,7 @@ describe('LeftPaneComposeHelper', () => {
describe('getConversationAndMessageAtIndex', () => {
it('returns undefined because keyboard shortcuts are not supported', () => {
const helper = new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -343,7 +352,7 @@ describe('LeftPaneComposeHelper', () => {
describe('getConversationAndMessageInDirection', () => {
it('returns undefined because keyboard shortcuts are not supported', () => {
const helper = new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -362,7 +371,7 @@ describe('LeftPaneComposeHelper', () => {
describe('shouldRecomputeRowHeights', () => {
it('returns false if going from "no header" to "no header"', () => {
const helper = new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -370,7 +379,7 @@ describe('LeftPaneComposeHelper', () => {
assert.isFalse(
helper.shouldRecomputeRowHeights({
composeContacts: [fakeConvo()],
composeContacts: [getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -378,7 +387,11 @@ describe('LeftPaneComposeHelper', () => {
);
assert.isFalse(
helper.shouldRecomputeRowHeights({
composeContacts: [fakeConvo(), fakeConvo(), fakeConvo()],
composeContacts: [
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
composeGroups: [],
regionCode: 'US',
searchTerm: 'bing bong',
@ -388,7 +401,7 @@ describe('LeftPaneComposeHelper', () => {
it('returns false if going from "has header" to "has header"', () => {
const helper = new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: '',
@ -396,7 +409,7 @@ describe('LeftPaneComposeHelper', () => {
assert.isFalse(
helper.shouldRecomputeRowHeights({
composeContacts: [fakeConvo()],
composeContacts: [getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: '',
@ -404,7 +417,7 @@ describe('LeftPaneComposeHelper', () => {
);
assert.isFalse(
helper.shouldRecomputeRowHeights({
composeContacts: [fakeConvo()],
composeContacts: [getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: '+16505559876',
@ -414,7 +427,7 @@ describe('LeftPaneComposeHelper', () => {
it('returns true if going from "no header" to "has header"', () => {
const helper = new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -422,7 +435,7 @@ describe('LeftPaneComposeHelper', () => {
assert.isTrue(
helper.shouldRecomputeRowHeights({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: '',
@ -430,7 +443,7 @@ describe('LeftPaneComposeHelper', () => {
);
assert.isTrue(
helper.shouldRecomputeRowHeights({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: '+16505551234',
@ -440,7 +453,7 @@ describe('LeftPaneComposeHelper', () => {
it('returns true if going from "has header" to "no header"', () => {
const helper = new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: '',
@ -448,7 +461,7 @@ describe('LeftPaneComposeHelper', () => {
assert.isTrue(
helper.shouldRecomputeRowHeights({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -458,7 +471,7 @@ describe('LeftPaneComposeHelper', () => {
it('should be true if going from contact to group or vice versa', () => {
const helperContacts = new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -467,7 +480,7 @@ describe('LeftPaneComposeHelper', () => {
assert.isTrue(
helperContacts.shouldRecomputeRowHeights({
composeContacts: [],
composeGroups: [fakeConvo(), fakeConvo()],
composeGroups: [getDefaultConversation(), getDefaultConversation()],
regionCode: 'US',
searchTerm: 'foo bar',
})
@ -475,14 +488,14 @@ describe('LeftPaneComposeHelper', () => {
const helperGroups = new LeftPaneComposeHelper({
composeContacts: [],
composeGroups: [fakeConvo(), fakeConvo()],
composeGroups: [getDefaultConversation(), getDefaultConversation()],
regionCode: 'US',
searchTerm: 'foo bar',
});
assert.isTrue(
helperGroups.shouldRecomputeRowHeights({
composeContacts: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [],
regionCode: 'US',
searchTerm: 'foo bar',
@ -492,16 +505,16 @@ describe('LeftPaneComposeHelper', () => {
it('should be true if the headers are in different row indices as before', () => {
const helperContacts = new LeftPaneComposeHelper({
composeContacts: [fakeConvo(), fakeConvo()],
composeGroups: [fakeConvo()],
composeContacts: [getDefaultConversation(), getDefaultConversation()],
composeGroups: [getDefaultConversation()],
regionCode: 'US',
searchTerm: 'soup',
});
assert.isTrue(
helperContacts.shouldRecomputeRowHeights({
composeContacts: [fakeConvo()],
composeGroups: [fakeConvo(), fakeConvo()],
composeContacts: [getDefaultConversation()],
composeGroups: [getDefaultConversation(), getDefaultConversation()],
regionCode: 'US',
searchTerm: 'sandwich',
})

View File

@ -3,19 +3,13 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { LeftPaneInboxHelper } from '../../../components/leftPane/LeftPaneInboxHelper';
describe('LeftPaneInboxHelper', () => {
const fakeConversation = () => ({
id: uuid(),
title: uuid(),
type: 'direct' as const,
});
describe('getBackAction', () => {
it("returns undefined; you can't go back from the main inbox", () => {
const helper = new LeftPaneInboxHelper({
@ -49,7 +43,7 @@ describe('LeftPaneInboxHelper', () => {
const helper = new LeftPaneInboxHelper({
conversations: [],
pinnedConversations: [],
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
});
assert.strictEqual(helper.getRowCount(), 1);
@ -58,9 +52,9 @@ describe('LeftPaneInboxHelper', () => {
it("returns the number of non-pinned conversations if that's all there is", () => {
const helper = new LeftPaneInboxHelper({
conversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [],
archivedConversations: [],
@ -73,9 +67,9 @@ describe('LeftPaneInboxHelper', () => {
const helper = new LeftPaneInboxHelper({
conversations: [],
pinnedConversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [],
});
@ -86,11 +80,11 @@ describe('LeftPaneInboxHelper', () => {
it('adds 2 rows for each header if there are pinned and non-pinned conversations,', () => {
const helper = new LeftPaneInboxHelper({
conversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [fakeConversation()],
pinnedConversations: [getDefaultConversation()],
archivedConversations: [],
});
@ -100,12 +94,12 @@ describe('LeftPaneInboxHelper', () => {
it('adds 1 row for the archive button if there are any archived conversations', () => {
const helper = new LeftPaneInboxHelper({
conversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [],
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
});
assert.strictEqual(helper.getRowCount(), 4);
@ -115,8 +109,8 @@ describe('LeftPaneInboxHelper', () => {
describe('getRowIndexToScrollTo', () => {
it('returns undefined if no conversation is selected', () => {
const helper = new LeftPaneInboxHelper({
conversations: [fakeConversation(), fakeConversation()],
pinnedConversations: [fakeConversation()],
conversations: [getDefaultConversation(), getDefaultConversation()],
pinnedConversations: [getDefaultConversation()],
archivedConversations: [],
});
@ -124,10 +118,10 @@ describe('LeftPaneInboxHelper', () => {
});
it('returns undefined if the selected conversation is not pinned or non-pinned', () => {
const archivedConversations = [fakeConversation()];
const archivedConversations = [getDefaultConversation()];
const helper = new LeftPaneInboxHelper({
conversations: [fakeConversation(), fakeConversation()],
pinnedConversations: [fakeConversation()],
conversations: [getDefaultConversation(), getDefaultConversation()],
pinnedConversations: [getDefaultConversation()],
archivedConversations,
});
@ -137,7 +131,10 @@ describe('LeftPaneInboxHelper', () => {
});
it("returns the pinned conversation's index if there are only pinned conversations", () => {
const pinnedConversations = [fakeConversation(), fakeConversation()];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations: [],
pinnedConversations,
@ -155,7 +152,10 @@ describe('LeftPaneInboxHelper', () => {
});
it("returns the conversation's index if there are only non-pinned conversations", () => {
const conversations = [fakeConversation(), fakeConversation()];
const conversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations,
pinnedConversations: [],
@ -167,9 +167,12 @@ describe('LeftPaneInboxHelper', () => {
});
it("returns the pinned conversation's index + 1 (for the header) if there are both pinned and non-pinned conversations", () => {
const pinnedConversations = [fakeConversation(), fakeConversation()];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations: [fakeConversation()],
conversations: [getDefaultConversation()],
pinnedConversations,
archivedConversations: [],
});
@ -185,13 +188,16 @@ describe('LeftPaneInboxHelper', () => {
});
it("returns the non-pinned conversation's index + pinnedConversations.length + 2 (for the headers) if there are both pinned and non-pinned conversations", () => {
const conversations = [fakeConversation(), fakeConversation()];
const conversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations,
pinnedConversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [],
});
@ -206,7 +212,10 @@ describe('LeftPaneInboxHelper', () => {
const helper = new LeftPaneInboxHelper({
conversations: [],
pinnedConversations: [],
archivedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
});
assert.deepEqual(helper.getRow(0), {
@ -217,7 +226,10 @@ describe('LeftPaneInboxHelper', () => {
});
it("returns pinned conversations if that's all there are", () => {
const pinnedConversations = [fakeConversation(), fakeConversation()];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations: [],
@ -237,12 +249,15 @@ describe('LeftPaneInboxHelper', () => {
});
it('returns pinned conversations and an archive button if there are no non-pinned conversations', () => {
const pinnedConversations = [fakeConversation(), fakeConversation()];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations: [],
pinnedConversations,
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
});
assert.deepEqual(helper.getRow(0), {
@ -261,7 +276,10 @@ describe('LeftPaneInboxHelper', () => {
});
it("returns non-pinned conversations if that's all there are", () => {
const conversations = [fakeConversation(), fakeConversation()];
const conversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations,
@ -281,12 +299,15 @@ describe('LeftPaneInboxHelper', () => {
});
it('returns non-pinned conversations and an archive button if there are no pinned conversations', () => {
const conversations = [fakeConversation(), fakeConversation()];
const conversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations,
pinnedConversations: [],
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
});
assert.deepEqual(helper.getRow(0), {
@ -306,11 +327,14 @@ describe('LeftPaneInboxHelper', () => {
it('returns headers if there are both pinned and non-pinned conversations', () => {
const conversations = [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const pinnedConversations = [fakeConversation(), fakeConversation()];
const helper = new LeftPaneInboxHelper({
conversations,
@ -351,16 +375,19 @@ describe('LeftPaneInboxHelper', () => {
it('returns headers if there are both pinned and non-pinned conversations, and an archive button', () => {
const conversations = [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const pinnedConversations = [fakeConversation(), fakeConversation()];
const helper = new LeftPaneInboxHelper({
conversations,
pinnedConversations,
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
});
assert.deepEqual(helper.getRow(0), {
@ -402,11 +429,14 @@ describe('LeftPaneInboxHelper', () => {
describe('getConversationAndMessageAtIndex', () => {
it('returns pinned converastions, then non-pinned conversations', () => {
const conversations = [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const pinnedConversations = [fakeConversation(), fakeConversation()];
const helper = new LeftPaneInboxHelper({
conversations,
@ -437,7 +467,10 @@ describe('LeftPaneInboxHelper', () => {
});
it("when requesting an index out of bounds, returns the last pinned conversation when that's all there is", () => {
const pinnedConversations = [fakeConversation(), fakeConversation()];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations: [],
@ -462,7 +495,10 @@ describe('LeftPaneInboxHelper', () => {
});
it("when requesting an index out of bounds, returns the last non-pinned conversation when that's all there is", () => {
const conversations = [fakeConversation(), fakeConversation()];
const conversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations,
@ -487,8 +523,14 @@ describe('LeftPaneInboxHelper', () => {
});
it('when requesting an index out of bounds, returns the last non-pinned conversation when there are both pinned and non-pinned conversations', () => {
const conversations = [fakeConversation(), fakeConversation()];
const pinnedConversations = [fakeConversation(), fakeConversation()];
const conversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneInboxHelper({
conversations,
@ -516,7 +558,7 @@ describe('LeftPaneInboxHelper', () => {
const helper = new LeftPaneInboxHelper({
conversations: [],
pinnedConversations: [],
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
});
assert.isUndefined(helper.getConversationAndMessageAtIndex(0));
@ -527,8 +569,11 @@ describe('LeftPaneInboxHelper', () => {
describe('getConversationAndMessageInDirection', () => {
it('returns the next conversation when searching downward', () => {
const pinnedConversations = [fakeConversation(), fakeConversation()];
const conversations = [fakeConversation()];
const pinnedConversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const conversations = [getDefaultConversation()];
const helper = new LeftPaneInboxHelper({
conversations,
pinnedConversations,
@ -552,23 +597,32 @@ describe('LeftPaneInboxHelper', () => {
it("returns false if the number of conversations in each section doesn't change", () => {
const helper = new LeftPaneInboxHelper({
conversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [fakeConversation()],
pinnedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [getDefaultConversation()],
});
assert.isFalse(
helper.shouldRecomputeRowHeights({
conversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [fakeConversation(), fakeConversation()],
})
);
});
@ -576,22 +630,28 @@ describe('LeftPaneInboxHelper', () => {
it('returns false if the only thing changed is whether conversations are archived', () => {
const helper = new LeftPaneInboxHelper({
conversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [fakeConversation()],
pinnedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [getDefaultConversation()],
});
assert.isFalse(
helper.shouldRecomputeRowHeights({
conversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [],
})
);
@ -600,53 +660,65 @@ describe('LeftPaneInboxHelper', () => {
it('returns false if the only thing changed is the number of non-pinned conversations', () => {
const helper = new LeftPaneInboxHelper({
conversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
pinnedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [fakeConversation()],
pinnedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [getDefaultConversation()],
});
assert.isFalse(
helper.shouldRecomputeRowHeights({
conversations: [fakeConversation()],
pinnedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [fakeConversation(), fakeConversation()],
conversations: [getDefaultConversation()],
pinnedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
})
);
});
it('returns true if the number of pinned conversations changes', () => {
const helper = new LeftPaneInboxHelper({
conversations: [fakeConversation()],
pinnedConversations: [fakeConversation(), fakeConversation()],
archivedConversations: [fakeConversation()],
conversations: [getDefaultConversation()],
pinnedConversations: [
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [getDefaultConversation()],
});
assert.isTrue(
helper.shouldRecomputeRowHeights({
conversations: [fakeConversation()],
conversations: [getDefaultConversation()],
pinnedConversations: [
fakeConversation(),
fakeConversation(),
fakeConversation(),
getDefaultConversation(),
getDefaultConversation(),
getDefaultConversation(),
],
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
})
);
assert.isTrue(
helper.shouldRecomputeRowHeights({
conversations: [fakeConversation()],
pinnedConversations: [fakeConversation()],
archivedConversations: [fakeConversation()],
conversations: [getDefaultConversation()],
pinnedConversations: [getDefaultConversation()],
archivedConversations: [getDefaultConversation()],
})
);
assert.isTrue(
helper.shouldRecomputeRowHeights({
conversations: [fakeConversation()],
conversations: [getDefaultConversation()],
pinnedConversations: [],
archivedConversations: [fakeConversation()],
archivedConversations: [getDefaultConversation()],
})
);
});

View File

@ -5,16 +5,11 @@ import { assert } from 'chai';
import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { LeftPaneSearchHelper } from '../../../components/leftPane/LeftPaneSearchHelper';
describe('LeftPaneSearchHelper', () => {
const fakeConversation = () => ({
id: uuid(),
title: uuid(),
type: 'direct' as const,
});
const fakeMessage = () => ({
id: uuid(),
conversationId: uuid(),
@ -54,7 +49,7 @@ describe('LeftPaneSearchHelper', () => {
new LeftPaneSearchHelper({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: true },
messageResults: { isLoading: true },
@ -88,7 +83,7 @@ describe('LeftPaneSearchHelper', () => {
const helper = new LeftPaneSearchHelper({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [fakeMessage()] },
@ -111,7 +106,7 @@ describe('LeftPaneSearchHelper', () => {
new LeftPaneSearchHelper({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: true },
messageResults: { isLoading: true },
@ -139,8 +134,11 @@ describe('LeftPaneSearchHelper', () => {
});
it('returns header + results when all sections have loaded with results', () => {
const conversations = [fakeConversation(), fakeConversation()];
const contacts = [fakeConversation()];
const conversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const contacts = [getDefaultConversation()];
const messages = [fakeMessage(), fakeMessage()];
const helper = new LeftPaneSearchHelper({
@ -188,7 +186,7 @@ describe('LeftPaneSearchHelper', () => {
});
it('omits conversations when there are no conversation results', () => {
const contacts = [fakeConversation()];
const contacts = [getDefaultConversation()];
const messages = [fakeMessage(), fakeMessage()];
const helper = new LeftPaneSearchHelper({
@ -224,7 +222,10 @@ describe('LeftPaneSearchHelper', () => {
});
it('omits contacts when there are no contact results', () => {
const conversations = [fakeConversation(), fakeConversation()];
const conversations = [
getDefaultConversation(),
getDefaultConversation(),
];
const messages = [fakeMessage(), fakeMessage()];
const helper = new LeftPaneSearchHelper({
@ -265,8 +266,8 @@ describe('LeftPaneSearchHelper', () => {
});
it('omits messages when there are no message results', () => {
const conversations = [fakeConversation(), fakeConversation()];
const contacts = [fakeConversation()];
const conversations = [getDefaultConversation(), getDefaultConversation()];
const contacts = [getDefaultConversation()];
const helper = new LeftPaneSearchHelper({
conversationResults: {
@ -313,7 +314,7 @@ describe('LeftPaneSearchHelper', () => {
new LeftPaneSearchHelper({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: true },
messageResults: { isLoading: true },
@ -336,7 +337,7 @@ describe('LeftPaneSearchHelper', () => {
const helper = new LeftPaneSearchHelper({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: false, results: [] },
messageResults: {
@ -354,7 +355,7 @@ describe('LeftPaneSearchHelper', () => {
const helper = new LeftPaneSearchHelper({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: false, results: [] },
messageResults: {
@ -368,7 +369,7 @@ describe('LeftPaneSearchHelper', () => {
helper.shouldRecomputeRowHeights({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: false, results: [] },
messageResults: {
@ -392,7 +393,7 @@ describe('LeftPaneSearchHelper', () => {
helper.shouldRecomputeRowHeights({
conversationResults: {
isLoading: false,
results: [fakeConversation()],
results: [getDefaultConversation()],
},
contactResults: { isLoading: true },
messageResults: { isLoading: true },
@ -413,7 +414,7 @@ describe('LeftPaneSearchHelper', () => {
helper.shouldRecomputeRowHeights({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [fakeMessage()] },
@ -426,7 +427,7 @@ describe('LeftPaneSearchHelper', () => {
const helper = new LeftPaneSearchHelper({
conversationResults: {
isLoading: false,
results: [fakeConversation(), fakeConversation()],
results: [getDefaultConversation(), getDefaultConversation()],
},
contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [] },
@ -437,7 +438,7 @@ describe('LeftPaneSearchHelper', () => {
helper.shouldRecomputeRowHeights({
conversationResults: {
isLoading: false,
results: [fakeConversation()],
results: [getDefaultConversation()],
},
contactResults: { isLoading: true },
messageResults: { isLoading: true },

View File

@ -3,18 +3,12 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { LeftPaneSetGroupMetadataHelper } from '../../../components/leftPane/LeftPaneSetGroupMetadataHelper';
describe('LeftPaneSetGroupMetadataHelper', () => {
const fakeContact = () => ({
id: uuid(),
title: uuid(),
type: 'direct' as const,
});
describe('getBackAction', () => {
it('returns the "show composer" action if a request is not active', () => {
const showChooseGroupMembers = sinon.fake();
@ -68,7 +62,10 @@ describe('LeftPaneSetGroupMetadataHelper', () => {
groupName: '',
hasError: false,
isCreating: false,
selectedContacts: [fakeContact(), fakeContact()],
selectedContacts: [
getDefaultConversation(),
getDefaultConversation(),
],
}).getRowCount(),
4
);
@ -89,7 +86,10 @@ describe('LeftPaneSetGroupMetadataHelper', () => {
});
it('returns a header, then the contacts, then a blank space if there are contacts', () => {
const selectedContacts = [fakeContact(), fakeContact()];
const selectedContacts = [
getDefaultConversation(),
getDefaultConversation(),
];
const helper = new LeftPaneSetGroupMetadataHelper({
groupAvatar: undefined,
groupName: '',

View File

@ -2,21 +2,17 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { v4 as uuid } from 'uuid';
import {
FindDirection,
ToFindType,
} from '../../../components/leftPane/LeftPaneHelper';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { getConversationInDirection } from '../../../components/leftPane/getConversationInDirection';
describe('getConversationInDirection', () => {
const fakeConversation = (markedUnread = false) => ({
id: uuid(),
title: uuid(),
type: 'direct' as const,
markedUnread,
});
const fakeConversation = (markedUnread = false) =>
getDefaultConversation({ markedUnread });
const fakeConversations = [
fakeConversation(),

View File

@ -1,12 +1,13 @@
// Copyright 2020 Signal Messenger, LLC
// Copyright 2020-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { ConversationType } from '../../state/ducks/conversations';
import { MemberRepository } from '../../quill/memberRepository';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
const memberMahershala: ConversationType = {
const memberMahershala: ConversationType = getDefaultConversation({
id: '555444',
uuid: 'abcdefg',
title: 'Pal',
@ -17,9 +18,9 @@ const memberMahershala: ConversationType = {
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
};
});
const memberShia: ConversationType = {
const memberShia: ConversationType = getDefaultConversation({
id: '333222',
uuid: 'hijklmno',
title: 'Buddy',
@ -30,11 +31,11 @@ const memberShia: ConversationType = {
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
};
});
const members: Array<ConversationType> = [memberMahershala, memberShia];
const singleMember: ConversationType = {
const singleMember: ConversationType = getDefaultConversation({
id: '666777',
uuid: 'pqrstuv',
title: 'The Guy',
@ -45,7 +46,7 @@ const singleMember: ConversationType = {
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
};
});
describe('MemberRepository', () => {
describe('#updateMembers', () => {

View File

@ -8,6 +8,7 @@ import Delta from 'quill-delta';
import { matchMention } from '../../../quill/mentions/matchers';
import { MemberRepository } from '../../../quill/memberRepository';
import { ConversationType } from '../../../state/ducks/conversations';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
class FakeTokenList<T> extends Array<T> {
constructor(elements: Array<T>) {
@ -37,7 +38,7 @@ const createMockMentionBlotElement = (
dataset: Record<string, string>
): HTMLElement => createMockElement('mention-blot', dataset);
const memberMahershala: ConversationType = {
const memberMahershala: ConversationType = getDefaultConversation({
id: '555444',
uuid: 'abcdefg',
title: 'Mahershala Ali',
@ -47,9 +48,9 @@ const memberMahershala: ConversationType = {
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
};
});
const memberShia: ConversationType = {
const memberShia: ConversationType = getDefaultConversation({
id: '333222',
uuid: 'hijklmno',
title: 'Shia LaBeouf',
@ -59,7 +60,7 @@ const memberShia: ConversationType = {
lastUpdated: Date.now(),
markedUnread: false,
areWeAdmin: false,
};
});
const members: Array<ConversationType> = [memberMahershala, memberShia];

View File

@ -7,7 +7,7 @@ export const shouldBlurAvatar = ({
acceptedMessageRequest,
avatarPath,
isMe,
sharedGroupNames = [],
sharedGroupNames,
unblurredAvatarPath,
}: Readonly<
Pick<