TelegramPWA/src/components/modals/collectible/CollectibleInfoModal.tsx
2024-06-18 16:30:47 +02:00

157 lines
4.7 KiB
TypeScript

import type { FC } from '../../../lib/teact/teact';
import React, {
memo,
useMemo,
} from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global';
import type { ApiCountryCode } from '../../../api/types';
import type { TabState } from '../../../global/types';
import { copyTextToClipboard } from '../../../util/clipboard';
import { formatDateAtTime } from '../../../util/dates/dateFormat';
import { formatCurrencyAsString } from '../../../util/formatCurrency';
import { formatPhoneNumberWithCode } from '../../../util/phoneNumber';
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
import formatUsername from '../../common/helpers/formatUsername';
import renderText from '../../common/helpers/renderText';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import AnimatedIconWithPreview from '../../common/AnimatedIconWithPreview';
import Icon from '../../common/icons/Icon';
import PickerSelectedItem from '../../common/PickerSelectedItem';
import Button from '../../ui/Button';
import Modal from '../../ui/Modal';
import styles from './CollectibleInfoModal.module.scss';
export type OwnProps = {
modal: TabState['collectibleInfoModal'];
};
type StateProps = {
phoneCodeList: ApiCountryCode[];
};
const TOP_ICON_SIZE = 60;
const CollectibleInfoModal: FC<OwnProps & StateProps> = ({
modal,
phoneCodeList,
}) => {
const {
closeCollectibleInfoModal,
openChat,
openUrl,
showNotification,
} = getActions();
const lang = useOldLang();
const isUsername = modal?.type === 'username';
const handleClose = useLastCallback(() => {
closeCollectibleInfoModal();
});
const handleOpenChat = useLastCallback(() => {
openChat({ id: modal!.peerId });
handleClose();
});
const handleOpenUrl = useLastCallback(() => {
openUrl({
url: modal!.url,
shouldSkipModal: true,
});
handleClose();
});
const handleCopy = useLastCallback(() => {
const text = isUsername ? formatUsername(modal!.collectible)
: formatPhoneNumberWithCode(phoneCodeList, modal!.collectible);
copyTextToClipboard(text);
showNotification({
message: lang(isUsername ? 'UsernameCopied' : 'PhoneCopied'),
});
handleClose();
});
const title = useMemo(() => {
if (!modal) return undefined;
const key = isUsername ? 'FragmentUsernameTitle' : 'FragmentPhoneTitle';
const formattedCollectible = isUsername
? formatUsername(modal.collectible)
: formatPhoneNumberWithCode(phoneCodeList, modal.collectible);
return lang(key, formattedCollectible);
}, [modal, isUsername, phoneCodeList, lang]);
const description = useMemo(() => {
if (!modal) return undefined;
const key = isUsername ? 'FragmentUsernameMessage' : 'FragmentPhoneMessage';
const date = formatDateAtTime(lang, modal.purchaseDate * 1000);
const currency = formatCurrencyAsString(modal.amount, modal.currency, lang.code);
const cryptoCurrency = formatCurrencyAsString(modal.cryptoAmount, modal.cryptoCurrency, lang.code);
const paid = `${cryptoCurrency} (${currency})`;
return lang(key, [date, paid]);
}, [modal, isUsername, lang]);
return (
<Modal
isOpen={Boolean(modal)}
isSlim
contentClassName={styles.content}
onClose={closeCollectibleInfoModal}
>
<Button
round
color="translucent"
size="smaller"
className={styles.closeButton}
ariaLabel={lang('Close')}
onClick={handleClose}
>
<Icon name="close" />
</Button>
<div className={styles.icon}>
<AnimatedIconWithPreview
tgsUrl={isUsername ? LOCAL_TGS_URLS.Mention : LOCAL_TGS_URLS.Fragment}
size={TOP_ICON_SIZE}
/>
</div>
<h3 className={styles.title}>
{title && renderText(title, ['simple_markdown'])}
</h3>
<PickerSelectedItem
fluid
className={styles.chip}
peerId={modal?.peerId}
forceShowSelf
onClick={handleOpenChat}
/>
<p className={styles.description}>
{description && renderText(description, ['simple_markdown'])}
</p>
<div className="dialog-buttons dialog-buttons-centered">
<Button className="confirm-dialog-button" onClick={handleOpenUrl}>
{lang('FragmentUsernameOpen')}
</Button>
<Button isText className="confirm-dialog-button" onClick={handleCopy}>
{lang(isUsername ? 'FragmentUsernameCopy' : 'FragmentPhoneCopy')}
</Button>
</div>
</Modal>
);
};
export default memo(withGlobal<OwnProps>(
(global): StateProps => {
const { countryList } = global;
return {
phoneCodeList: countryList.phoneCodes,
};
},
)(CollectibleInfoModal));