Skip to content

Commit

Permalink
Add badges to avatars in group dialogs
Browse files Browse the repository at this point in the history
  • Loading branch information
EvanHahn-Signal authored Nov 20, 2021
1 parent 7bb37dc commit e490d91
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 39 deletions.
14 changes: 12 additions & 2 deletions ts/components/GroupDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import type { ReactChild, ReactNode } from 'react';
import React from 'react';

import type { LocalizerType } from '../types/Util';
import type { LocalizerType, ThemeType } from '../types/Util';
import type { ConversationType } from '../state/ducks/conversations';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import { ModalHost } from './ModalHost';
import { Button, ButtonVariant } from './Button';
import { Avatar, AvatarSize } from './Avatar';
Expand Down Expand Up @@ -92,20 +93,29 @@ GroupDialog.Paragraph = ({

type ContactsPropsType = {
contacts: Array<ConversationType>;
getPreferredBadge: PreferredBadgeSelectorType;
i18n: LocalizerType;
theme: ThemeType;
};

GroupDialog.Contacts = ({ contacts, i18n }: Readonly<ContactsPropsType>) => (
GroupDialog.Contacts = ({
contacts,
getPreferredBadge,
i18n,
theme,
}: Readonly<ContactsPropsType>) => (
<ul className="module-GroupDialog__contacts">
{contacts.map(contact => (
<li key={contact.id} className="module-GroupDialog__contacts__contact">
<Avatar
acceptedMessageRequest={contact.acceptedMessageRequest}
avatarPath={contact.avatarPath}
badge={getPreferredBadge(contact.badges)}
color={contact.color}
conversationType={contact.type}
isMe={contact.isMe}
noteToSelf={contact.isMe}
theme={theme}
title={contact.title}
unblurredAvatarPath={contact.unblurredAvatarPath}
sharedGroupNames={contact.sharedGroupNames}
Expand Down
3 changes: 3 additions & 0 deletions ts/components/GroupV1MigrationDialog.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { ConversationType } from '../state/ducks/conversations';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
import { ThemeType } from '../types/Util';

const i18n = setupI18n('en', enMessages);

Expand Down Expand Up @@ -44,6 +45,7 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
booleanOr(overrideProps.areWeInvited, false)
),
droppedMembers: overrideProps.droppedMembers || [contact3, contact1],
getPreferredBadge: () => undefined,
hasMigrated: boolean(
'hasMigrated',
booleanOr(overrideProps.hasMigrated, false)
Expand All @@ -52,6 +54,7 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
invitedMembers: overrideProps.invitedMembers || [contact2],
migrate: action('migrate'),
onClose: action('onClose'),
theme: ThemeType.light,
});

const stories = storiesOf('Components/GroupV1MigrationDialog', module);
Expand Down
54 changes: 40 additions & 14 deletions ts/components/GroupV1MigrationDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright 2019-2020 Signal Messenger, LLC
// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only

import * as React from 'react';
import type { LocalizerType } from '../types/Util';
import type { LocalizerType, ThemeType } from '../types/Util';
import type { ConversationType } from '../state/ducks/conversations';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import { GroupDialog } from './GroupDialog';
import { sortByTitle } from '../util/sortByTitle';

Expand All @@ -19,7 +20,9 @@ export type DataPropsType = {
};

export type HousekeepingPropsType = {
readonly getPreferredBadge: PreferredBadgeSelectorType;
readonly i18n: LocalizerType;
readonly theme: ThemeType;
};

export type PropsType = DataPropsType & HousekeepingPropsType;
Expand All @@ -29,11 +32,13 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
const {
areWeInvited,
droppedMembers,
getPreferredBadge,
hasMigrated,
i18n,
invitedMembers,
migrate,
onClose,
theme,
} = props;

const title = hasMigrated
Expand Down Expand Up @@ -84,23 +89,39 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
</GroupDialog.Paragraph>
) : (
<>
{renderMembers(
invitedMembers,
'GroupV1--Migration--info--invited',
i18n
)}
{renderMembers(droppedMembers, droppedMembersKey, i18n)}
{renderMembers({
getPreferredBadge,
i18n,
members: invitedMembers,
prefix: 'GroupV1--Migration--info--invited',
theme,
})}
{renderMembers({
getPreferredBadge,
i18n,
members: droppedMembers,
prefix: droppedMembersKey,
theme,
})}
</>
)}
</GroupDialog>
);
});

function renderMembers(
members: Array<ConversationType>,
prefix: string,
i18n: LocalizerType
): React.ReactNode {
function renderMembers({
getPreferredBadge,
i18n,
members,
prefix,
theme,
}: Readonly<{
getPreferredBadge: PreferredBadgeSelectorType;
i18n: LocalizerType;
members: Array<ConversationType>;
prefix: string;
theme: ThemeType;
}>): React.ReactNode {
if (!members.length) {
return null;
}
Expand All @@ -111,7 +132,12 @@ function renderMembers(
return (
<>
<GroupDialog.Paragraph>{i18n(key)}</GroupDialog.Paragraph>
<GroupDialog.Contacts contacts={sortByTitle(members)} i18n={i18n} />
<GroupDialog.Contacts
contacts={sortByTitle(members)}
getPreferredBadge={getPreferredBadge}
i18n={i18n}
theme={theme}
/>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
import type { ConversationType } from '../state/ducks/conversations';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
import { ThemeType } from '../types/Util';

const i18n = setupI18n('en', enMessages);

Expand All @@ -27,15 +28,19 @@ const story = storiesOf(
story.add('One contact', () => (
<NewlyCreatedGroupInvitedContactsDialog
contacts={[conversations[0]]}
getPreferredBadge={() => undefined}
i18n={i18n}
onClose={action('onClose')}
theme={ThemeType.light}
/>
));

story.add('Two contacts', () => (
<NewlyCreatedGroupInvitedContactsDialog
contacts={conversations}
getPreferredBadge={() => undefined}
i18n={i18n}
onClose={action('onClose')}
theme={ThemeType.light}
/>
));
14 changes: 11 additions & 3 deletions ts/components/NewlyCreatedGroupInvitedContactsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@
import type { FunctionComponent, ReactNode } from 'react';
import React from 'react';

import type { LocalizerType } from '../types/Util';
import type { LocalizerType, ThemeType } from '../types/Util';
import type { ConversationType } from '../state/ducks/conversations';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import { Intl } from './Intl';
import { ContactName } from './conversation/ContactName';
import { GroupDialog } from './GroupDialog';
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';

type PropsType = {
contacts: Array<ConversationType>;
getPreferredBadge: PreferredBadgeSelectorType;
i18n: LocalizerType;
onClose: () => void;
theme: ThemeType;
};

export const NewlyCreatedGroupInvitedContactsDialog: FunctionComponent<PropsType> =
({ contacts, i18n, onClose }) => {
({ contacts, getPreferredBadge, i18n, onClose, theme }) => {
let title: string;
let body: ReactNode;
if (contacts.length === 1) {
Expand Down Expand Up @@ -57,7 +60,12 @@ export const NewlyCreatedGroupInvitedContactsDialog: FunctionComponent<PropsType
'NewlyCreatedGroupInvitedContactsDialog--body--info-paragraph'
)}
</GroupDialog.Paragraph>
<GroupDialog.Contacts contacts={contacts} i18n={i18n} />
<GroupDialog.Contacts
contacts={contacts}
getPreferredBadge={getPreferredBadge}
i18n={i18n}
theme={theme}
/>
</>
);
}
Expand Down
3 changes: 3 additions & 0 deletions ts/components/conversation/GroupV1Migration.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { setupI18n } from '../../util/setupI18n';
import enMessages from '../../../_locales/en/messages.json';
import type { PropsType } from './GroupV1Migration';
import { GroupV1Migration } from './GroupV1Migration';
import { ThemeType } from '../../types/Util';

const i18n = setupI18n('en', enMessages);

Expand All @@ -33,8 +34,10 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
isBoolean(overrideProps.areWeInvited) ? overrideProps.areWeInvited : false
),
droppedMembers: overrideProps.droppedMembers || [contact1],
getPreferredBadge: () => undefined,
i18n,
invitedMembers: overrideProps.invitedMembers || [contact2],
theme: ThemeType.light,
});

const stories = storiesOf('Components/Conversation/GroupV1Migration', module);
Expand Down
16 changes: 14 additions & 2 deletions ts/components/conversation/GroupV1Migration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import * as React from 'react';

import { Button, ButtonSize, ButtonVariant } from '../Button';
import { SystemMessage } from './SystemMessage';
import type { LocalizerType } from '../../types/Util';
import type { LocalizerType, ThemeType } from '../../types/Util';
import type { ConversationType } from '../../state/ducks/conversations';
import type { PreferredBadgeSelectorType } from '../../state/selectors/badges';
import { Intl } from '../Intl';
import { ContactName } from './ContactName';
import { GroupV1MigrationDialog } from '../GroupV1MigrationDialog';
Expand All @@ -19,13 +20,22 @@ export type PropsDataType = {
};

export type PropsHousekeepingType = {
getPreferredBadge: PreferredBadgeSelectorType;
i18n: LocalizerType;
theme: ThemeType;
};

export type PropsType = PropsDataType & PropsHousekeepingType;

export function GroupV1Migration(props: PropsType): React.ReactElement {
const { areWeInvited, droppedMembers, i18n, invitedMembers } = props;
const {
areWeInvited,
droppedMembers,
getPreferredBadge,
i18n,
invitedMembers,
theme,
} = props;
const [showingDialog, setShowingDialog] = React.useState(false);

const showDialog = React.useCallback(() => {
Expand Down Expand Up @@ -77,11 +87,13 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
<GroupV1MigrationDialog
areWeInvited={areWeInvited}
droppedMembers={droppedMembers}
getPreferredBadge={getPreferredBadge}
hasMigrated
i18n={i18n}
invitedMembers={invitedMembers}
migrate={() => log.warn('GroupV1Migration: Modal called migrate()')}
onClose={dismissDialog}
theme={theme}
/>
) : null}
</>
Expand Down
Loading

0 comments on commit e490d91

Please sign in to comment.