140 lines
4.7 KiB
TypeScript
140 lines
4.7 KiB
TypeScript
// Copyright 2024 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import React, { useCallback, useEffect, useMemo } from 'react';
|
|
import { Modal } from './Modal';
|
|
import type { LocalizerType } from '../types/I18N';
|
|
import { Avatar, AvatarSize } from './Avatar';
|
|
import type { PendingUserActionPayloadType } from '../state/ducks/calling';
|
|
import type { ConversationType } from '../state/ducks/conversations';
|
|
import { InContactsIcon } from './InContactsIcon';
|
|
import { isInSystemContacts } from '../util/isInSystemContacts';
|
|
import { ThemeType } from '../types/Util';
|
|
import { Theme } from '../util/theme';
|
|
import { UserText } from './UserText';
|
|
import { SharedGroupNames } from './SharedGroupNames';
|
|
|
|
export type CallLinkPendingParticipantModalProps = {
|
|
readonly i18n: LocalizerType;
|
|
readonly conversation: ConversationType;
|
|
readonly approveUser: (payload: PendingUserActionPayloadType) => void;
|
|
readonly denyUser: (payload: PendingUserActionPayloadType) => void;
|
|
readonly onClose: () => void;
|
|
readonly toggleAboutContactModal: (conversationId: string) => void;
|
|
readonly updateSharedGroups: (conversationId: string) => void;
|
|
};
|
|
|
|
export function CallLinkPendingParticipantModal({
|
|
i18n,
|
|
conversation,
|
|
approveUser,
|
|
denyUser,
|
|
onClose,
|
|
toggleAboutContactModal,
|
|
updateSharedGroups,
|
|
}: CallLinkPendingParticipantModalProps): JSX.Element {
|
|
useEffect(() => {
|
|
// Kick off the expensive hydration of the current sharedGroupNames
|
|
updateSharedGroups(conversation.id);
|
|
}, [conversation.id, updateSharedGroups]);
|
|
|
|
const serviceId = useMemo(() => {
|
|
return conversation.serviceId;
|
|
}, [conversation]);
|
|
|
|
const handleApprove = useCallback(() => {
|
|
approveUser({ serviceId });
|
|
onClose();
|
|
}, [approveUser, onClose, serviceId]);
|
|
|
|
const handleDeny = useCallback(() => {
|
|
denyUser({ serviceId });
|
|
onClose();
|
|
}, [denyUser, onClose, serviceId]);
|
|
|
|
return (
|
|
<Modal
|
|
modalName="CallLinkPendingParticipantModal"
|
|
moduleClassName="CallLinkPendingParticipantModal"
|
|
hasXButton
|
|
i18n={i18n}
|
|
onClose={onClose}
|
|
theme={Theme.Dark}
|
|
>
|
|
<Avatar
|
|
acceptedMessageRequest={conversation.acceptedMessageRequest}
|
|
avatarUrl={conversation.avatarUrl}
|
|
badge={undefined}
|
|
color={conversation.color}
|
|
conversationType="direct"
|
|
i18n={i18n}
|
|
isMe={conversation.isMe}
|
|
profileName={conversation.profileName}
|
|
sharedGroupNames={conversation.sharedGroupNames}
|
|
size={AvatarSize.EIGHTY}
|
|
title={conversation.title}
|
|
theme={ThemeType.dark}
|
|
unblurredAvatarUrl={conversation.unblurredAvatarUrl}
|
|
/>
|
|
|
|
<button
|
|
type="button"
|
|
onClick={ev => {
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
toggleAboutContactModal(conversation.id);
|
|
}}
|
|
className="CallLinkPendingParticipantModal__NameButton"
|
|
>
|
|
<div className="CallLinkPendingParticipantModal__Title">
|
|
<UserText text={conversation.title} />
|
|
{isInSystemContacts(conversation) && (
|
|
<span>
|
|
{' '}
|
|
<InContactsIcon
|
|
className="module-in-contacts-icon__icon CallLinkPendingParticipantModal__InContactsIcon"
|
|
i18n={i18n}
|
|
/>
|
|
</span>
|
|
)}
|
|
<span className="CallLinkPendingParticipantModal__AboutIcon" />
|
|
</div>
|
|
</button>
|
|
|
|
<div className="CallLinkPendingParticipantModal__SharedGroupInfo">
|
|
{conversation.sharedGroupNames?.length ? (
|
|
<SharedGroupNames
|
|
i18n={i18n}
|
|
sharedGroupNames={conversation.sharedGroupNames || []}
|
|
/>
|
|
) : (
|
|
i18n('icu:no-groups-in-common-warning')
|
|
)}
|
|
</div>
|
|
|
|
<div className="CallLinkPendingParticipantModal__Hr" />
|
|
|
|
<button
|
|
type="button"
|
|
className="CallLinkPendingParticipantModal__ActionButton"
|
|
onClick={handleApprove}
|
|
>
|
|
<div className="CallLinkPendingParticipantModal__ButtonIcon">
|
|
<div className="CallLinkPendingParticipantModal__ButtonIconContent CallLinkPendingParticipantModal__ButtonIconContent--approve" />
|
|
</div>
|
|
{i18n('icu:CallLinkPendingParticipantModal__ApproveButtonLabel')}
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
className="CallLinkPendingParticipantModal__ActionButton"
|
|
onClick={handleDeny}
|
|
>
|
|
<div className="CallLinkPendingParticipantModal__ButtonIcon">
|
|
<div className="CallLinkPendingParticipantModal__ButtonIconContent CallLinkPendingParticipantModal__ButtonIconContent--deny" />
|
|
</div>
|
|
{i18n('icu:CallLinkPendingParticipantModal__DenyButtonLabel')}
|
|
</button>
|
|
</Modal>
|
|
);
|
|
}
|