Display user badges

This commit is contained in:
Evan Hahn 2021-11-02 18:01:13 -05:00 committed by GitHub
parent 927c22ef73
commit f647c4e053
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
95 changed files with 2891 additions and 424 deletions

View file

@ -3,17 +3,21 @@
import React, { useEffect, useState } from 'react';
import { missingCaseError } from '../../util/missingCaseError';
import { About } from './About';
import { Avatar } from '../Avatar';
import { AvatarLightbox } from '../AvatarLightbox';
import type { ConversationType } from '../../state/ducks/conversations';
import { Modal } from '../Modal';
import type { LocalizerType } from '../../types/Util';
import { BadgeDialog } from '../BadgeDialog';
import type { BadgeType } from '../../badges/types';
import { SharedGroupNames } from '../SharedGroupNames';
import { ConfirmationDialog } from '../ConfirmationDialog';
export type PropsDataType = {
areWeAdmin: boolean;
badges: ReadonlyArray<BadgeType>;
contact?: ConversationType;
conversationId?: string;
readonly i18n: LocalizerType;
@ -38,8 +42,15 @@ type PropsActionType = {
export type PropsType = PropsDataType & PropsActionType;
enum ContactModalView {
Default,
ShowingAvatar,
ShowingBadges,
}
export const ContactModal = ({
areWeAdmin,
badges,
contact,
conversationId,
hideContactModal,
@ -56,7 +67,7 @@ export const ContactModal = ({
throw new Error('Contact modal opened without a matching contact');
}
const [showingAvatar, setShowingAvatar] = useState(false);
const [view, setView] = useState(ContactModalView.Default);
const [confirmToggleAdmin, setConfirmToggleAdmin] = useState(false);
useEffect(() => {
@ -66,135 +77,158 @@ export const ContactModal = ({
}
}, [conversationId, updateConversationModelSharedGroups]);
if (showingAvatar) {
return (
<AvatarLightbox
avatarColor={contact.color}
avatarPath={contact.avatarPath}
conversationTitle={contact.title}
i18n={i18n}
onClose={() => setShowingAvatar(false)}
/>
);
}
switch (view) {
case ContactModalView.Default: {
const preferredBadge: undefined | BadgeType = badges[0];
return (
<Modal
moduleClassName="ContactModal__modal"
hasXButton
i18n={i18n}
onClose={hideContactModal}
>
<div className="ContactModal">
<Avatar
acceptedMessageRequest={contact.acceptedMessageRequest}
avatarPath={contact.avatarPath}
color={contact.color}
conversationType="direct"
return (
<Modal
moduleClassName="ContactModal__modal"
hasXButton
i18n={i18n}
isMe={contact.isMe}
name={contact.name}
profileName={contact.profileName}
sharedGroupNames={contact.sharedGroupNames}
size={96}
title={contact.title}
unblurredAvatarPath={contact.unblurredAvatarPath}
onClick={() => setShowingAvatar(true)}
/>
<div className="ContactModal__name">{contact.title}</div>
<div className="module-about__container">
<About text={contact.about} />
</div>
{contact.phoneNumber && (
<div className="ContactModal__info">{contact.phoneNumber}</div>
)}
{!contact.isMe && (
<div className="ContactModal__info">
<SharedGroupNames
onClose={hideContactModal}
>
<div className="ContactModal">
<Avatar
acceptedMessageRequest={contact.acceptedMessageRequest}
avatarPath={contact.avatarPath}
badge={preferredBadge}
color={contact.color}
conversationType="direct"
i18n={i18n}
sharedGroupNames={contact.sharedGroupNames || []}
/>
</div>
)}
<div className="ContactModal__button-container">
<button
type="button"
className="ContactModal__button ContactModal__send-message"
onClick={() => {
hideContactModal();
openConversationInternal({ conversationId: contact.id });
}}
>
<div className="ContactModal__bubble-icon">
<div className="ContactModal__send-message__bubble-icon" />
</div>
<span>{i18n('ContactModal--message')}</span>
</button>
{!contact.isMe && (
<button
type="button"
className="ContactModal__button ContactModal__safety-number"
isMe={contact.isMe}
name={contact.name}
profileName={contact.profileName}
sharedGroupNames={contact.sharedGroupNames}
size={96}
title={contact.title}
unblurredAvatarPath={contact.unblurredAvatarPath}
onClick={() => {
hideContactModal();
toggleSafetyNumberModal(contact.id);
setView(
preferredBadge
? ContactModalView.ShowingBadges
: ContactModalView.ShowingAvatar
);
}}
>
<div className="ContactModal__bubble-icon">
<div className="ContactModal__safety-number__bubble-icon" />
/>
<div className="ContactModal__name">{contact.title}</div>
<div className="module-about__container">
<About text={contact.about} />
</div>
{contact.phoneNumber && (
<div className="ContactModal__info">{contact.phoneNumber}</div>
)}
{!contact.isMe && (
<div className="ContactModal__info">
<SharedGroupNames
i18n={i18n}
sharedGroupNames={contact.sharedGroupNames || []}
/>
</div>
<span>{i18n('showSafetyNumber')}</span>
</button>
)}
{!contact.isMe && areWeAdmin && isMember && conversationId && (
<>
)}
<div className="ContactModal__button-container">
<button
type="button"
className="ContactModal__button ContactModal__make-admin"
onClick={() => setConfirmToggleAdmin(true)}
className="ContactModal__button ContactModal__send-message"
onClick={() => {
hideContactModal();
openConversationInternal({ conversationId: contact.id });
}}
>
<div className="ContactModal__bubble-icon">
<div className="ContactModal__make-admin__bubble-icon" />
<div className="ContactModal__send-message__bubble-icon" />
</div>
{isAdmin ? (
<span>{i18n('ContactModal--rm-admin')}</span>
) : (
<span>{i18n('ContactModal--make-admin')}</span>
)}
<span>{i18n('ContactModal--message')}</span>
</button>
<button
type="button"
className="ContactModal__button ContactModal__remove-from-group"
onClick={() =>
removeMemberFromGroup(conversationId, contact.id)
}
{!contact.isMe && (
<button
type="button"
className="ContactModal__button ContactModal__safety-number"
onClick={() => {
hideContactModal();
toggleSafetyNumberModal(contact.id);
}}
>
<div className="ContactModal__bubble-icon">
<div className="ContactModal__safety-number__bubble-icon" />
</div>
<span>{i18n('showSafetyNumber')}</span>
</button>
)}
{!contact.isMe && areWeAdmin && isMember && conversationId && (
<>
<button
type="button"
className="ContactModal__button ContactModal__make-admin"
onClick={() => setConfirmToggleAdmin(true)}
>
<div className="ContactModal__bubble-icon">
<div className="ContactModal__make-admin__bubble-icon" />
</div>
{isAdmin ? (
<span>{i18n('ContactModal--rm-admin')}</span>
) : (
<span>{i18n('ContactModal--make-admin')}</span>
)}
</button>
<button
type="button"
className="ContactModal__button ContactModal__remove-from-group"
onClick={() =>
removeMemberFromGroup(conversationId, contact.id)
}
>
<div className="ContactModal__bubble-icon">
<div className="ContactModal__remove-from-group__bubble-icon" />
</div>
<span>{i18n('ContactModal--remove-from-group')}</span>
</button>
</>
)}
</div>
{confirmToggleAdmin && conversationId && (
<ConfirmationDialog
actions={[
{
action: () => toggleAdmin(conversationId, contact.id),
text: isAdmin
? i18n('ContactModal--rm-admin')
: i18n('ContactModal--make-admin'),
},
]}
i18n={i18n}
onClose={() => setConfirmToggleAdmin(false)}
>
<div className="ContactModal__bubble-icon">
<div className="ContactModal__remove-from-group__bubble-icon" />
</div>
<span>{i18n('ContactModal--remove-from-group')}</span>
</button>
</>
)}
</div>
{confirmToggleAdmin && conversationId && (
<ConfirmationDialog
actions={[
{
action: () => toggleAdmin(conversationId, contact.id),
text: isAdmin
? i18n('ContactModal--rm-admin')
: i18n('ContactModal--make-admin'),
},
]}
i18n={i18n}
onClose={() => setConfirmToggleAdmin(false)}
>
{isAdmin
? i18n('ContactModal--rm-admin-info', [contact.title])
: i18n('ContactModal--make-admin-info', [contact.title])}
</ConfirmationDialog>
)}
</div>
</Modal>
);
{isAdmin
? i18n('ContactModal--rm-admin-info', [contact.title])
: i18n('ContactModal--make-admin-info', [contact.title])}
</ConfirmationDialog>
)}
</div>
</Modal>
);
}
case ContactModalView.ShowingAvatar:
return (
<AvatarLightbox
avatarColor={contact.color}
avatarPath={contact.avatarPath}
conversationTitle={contact.title}
i18n={i18n}
onClose={() => setView(ContactModalView.Default)}
/>
);
case ContactModalView.ShowingBadges:
return (
<BadgeDialog
badges={badges}
firstName={contact.firstName}
i18n={i18n}
onClose={() => setView(ContactModalView.Default)}
title={contact.title}
/>
);
default:
throw missingCaseError(view);
}
};