Gift unique: Support link menu (#5530)
This commit is contained in:
parent
10009ce9ba
commit
495bd7e5d9
@ -1585,3 +1585,4 @@
|
|||||||
"ViewButtonStickerset" = "VIEW STICKERS";
|
"ViewButtonStickerset" = "VIEW STICKERS";
|
||||||
"ViewButtonGiftUnique" = "VIEW COLLECTIBLE";
|
"ViewButtonGiftUnique" = "VIEW COLLECTIBLE";
|
||||||
"AuthContinueOnThisLanguage" = "Continue in English";
|
"AuthContinueOnThisLanguage" = "Continue in English";
|
||||||
|
"Share" = "Share";
|
||||||
|
|||||||
@ -25,6 +25,7 @@ type OwnProps = {
|
|||||||
tableData?: TableData;
|
tableData?: TableData;
|
||||||
headerAvatarPeer?: ApiPeer | CustomPeer;
|
headerAvatarPeer?: ApiPeer | CustomPeer;
|
||||||
header?: TeactNode;
|
header?: TeactNode;
|
||||||
|
modalHeader?: TeactNode;
|
||||||
footer?: TeactNode;
|
footer?: TeactNode;
|
||||||
buttonText?: string;
|
buttonText?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -39,6 +40,7 @@ const TableInfoModal = ({
|
|||||||
tableData,
|
tableData,
|
||||||
headerAvatarPeer,
|
headerAvatarPeer,
|
||||||
header,
|
header,
|
||||||
|
modalHeader,
|
||||||
footer,
|
footer,
|
||||||
buttonText,
|
buttonText,
|
||||||
className,
|
className,
|
||||||
@ -59,6 +61,7 @@ const TableInfoModal = ({
|
|||||||
hasAbsoluteCloseButton={!title}
|
hasAbsoluteCloseButton={!title}
|
||||||
absoluteCloseButtonColor={hasBackdrop ? 'translucent-white' : undefined}
|
absoluteCloseButtonColor={hasBackdrop ? 'translucent-white' : undefined}
|
||||||
isSlim
|
isSlim
|
||||||
|
header={modalHeader}
|
||||||
title={title}
|
title={title}
|
||||||
className={className}
|
className={className}
|
||||||
contentClassName={styles.content}
|
contentClassName={styles.content}
|
||||||
|
|||||||
@ -61,6 +61,18 @@
|
|||||||
margin-inline-start: 0 !important;
|
margin-inline-start: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modalHeader {
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.375rem;
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.modalCloseButton {
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.ownerAddress {
|
.ownerAddress {
|
||||||
font-family: var(--font-family-monospace);
|
font-family: var(--font-family-monospace);
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { TeactNode } from '../../../../lib/teact/teact';
|
import type { FC, TeactNode } from '../../../../lib/teact/teact';
|
||||||
import React, { memo, useMemo } from '../../../../lib/teact/teact';
|
import React, { memo, useMemo } from '../../../../lib/teact/teact';
|
||||||
import { getActions, getGlobal, withGlobal } from '../../../../global';
|
import { getActions, getGlobal, withGlobal } from '../../../../global';
|
||||||
|
|
||||||
@ -7,6 +7,7 @@ import type {
|
|||||||
} from '../../../../api/types';
|
} from '../../../../api/types';
|
||||||
import type { TabState } from '../../../../global/types';
|
import type { TabState } from '../../../../global/types';
|
||||||
|
|
||||||
|
import { TME_LINK_PREFIX } from '../../../../config';
|
||||||
import { getHasAdminRight, getPeerTitle } from '../../../../global/helpers';
|
import { getHasAdminRight, getPeerTitle } from '../../../../global/helpers';
|
||||||
import { isApiPeerChat } from '../../../../global/helpers/peers';
|
import { isApiPeerChat } from '../../../../global/helpers/peers';
|
||||||
import { selectPeer } from '../../../../global/selectors';
|
import { selectPeer } from '../../../../global/selectors';
|
||||||
@ -32,7 +33,9 @@ import BadgeButton from '../../../common/BadgeButton';
|
|||||||
import Icon from '../../../common/icons/Icon';
|
import Icon from '../../../common/icons/Icon';
|
||||||
import Button from '../../../ui/Button';
|
import Button from '../../../ui/Button';
|
||||||
import ConfirmDialog from '../../../ui/ConfirmDialog';
|
import ConfirmDialog from '../../../ui/ConfirmDialog';
|
||||||
|
import DropdownMenu from '../../../ui/DropdownMenu';
|
||||||
import Link from '../../../ui/Link';
|
import Link from '../../../ui/Link';
|
||||||
|
import MenuItem from '../../../ui/MenuItem';
|
||||||
import TableInfoModal, { type TableData } from '../../common/TableInfoModal';
|
import TableInfoModal, { type TableData } from '../../common/TableInfoModal';
|
||||||
import UniqueGiftHeader from '../UniqueGiftHeader';
|
import UniqueGiftHeader from '../UniqueGiftHeader';
|
||||||
|
|
||||||
@ -68,6 +71,7 @@ const GiftInfoModal = ({
|
|||||||
focusMessage,
|
focusMessage,
|
||||||
openGiftUpgradeModal,
|
openGiftUpgradeModal,
|
||||||
showNotification,
|
showNotification,
|
||||||
|
openChatWithDraft,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
const [isConvertConfirmOpen, openConvertConfirm, closeConvertConfirm] = useFlag();
|
const [isConvertConfirmOpen, openConvertConfirm, closeConvertConfirm] = useFlag();
|
||||||
@ -103,6 +107,26 @@ const GiftInfoModal = ({
|
|||||||
closeGiftInfoModal();
|
closeGiftInfoModal();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const starGiftUniqueLink = useMemo(() => {
|
||||||
|
const slug = gift?.type === 'starGiftUnique' ? gift.slug : undefined;
|
||||||
|
if (!slug) return undefined;
|
||||||
|
return `${TME_LINK_PREFIX}nft/${slug}`;
|
||||||
|
}, [gift]);
|
||||||
|
|
||||||
|
const handleCopyLink = useLastCallback(() => {
|
||||||
|
if (!starGiftUniqueLink) return;
|
||||||
|
copyTextToClipboard(starGiftUniqueLink);
|
||||||
|
showNotification({
|
||||||
|
message: lang('LinkCopied'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleLinkShare = useLastCallback(() => {
|
||||||
|
if (!starGiftUniqueLink) return;
|
||||||
|
openChatWithDraft({ text: { text: starGiftUniqueLink } });
|
||||||
|
handleClose();
|
||||||
|
});
|
||||||
|
|
||||||
const handleFocusUpgraded = useLastCallback(() => {
|
const handleFocusUpgraded = useLastCallback(() => {
|
||||||
if (!savedGift?.upgradeMsgId || !renderingTargetPeer) return;
|
if (!savedGift?.upgradeMsgId || !renderingTargetPeer) return;
|
||||||
const { upgradeMsgId } = savedGift;
|
const { upgradeMsgId } = savedGift;
|
||||||
@ -132,6 +156,21 @@ const GiftInfoModal = ({
|
|||||||
return gift && getGiftAttributes(gift);
|
return gift && getGiftAttributes(gift);
|
||||||
}, [gift]);
|
}, [gift]);
|
||||||
|
|
||||||
|
const SettingsMenuButton: FC<{ onTrigger: () => void; isMenuOpen?: boolean }> = useMemo(() => {
|
||||||
|
return ({ onTrigger, isMenuOpen }) => (
|
||||||
|
<Button
|
||||||
|
round
|
||||||
|
size="smaller"
|
||||||
|
color="translucent-white"
|
||||||
|
className={isMenuOpen ? 'active' : ''}
|
||||||
|
onClick={onTrigger}
|
||||||
|
ariaLabel={lang('AriaMoreButton')}
|
||||||
|
>
|
||||||
|
<Icon name="more" />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}, [lang]);
|
||||||
|
|
||||||
const renderFooterButton = useLastCallback(() => {
|
const renderFooterButton = useLastCallback(() => {
|
||||||
if (canFocusUpgrade) {
|
if (canFocusUpgrade) {
|
||||||
return (
|
return (
|
||||||
@ -234,6 +273,45 @@ const GiftInfoModal = ({
|
|||||||
|
|
||||||
const isUniqueGift = gift.type === 'starGiftUnique';
|
const isUniqueGift = gift.type === 'starGiftUnique';
|
||||||
|
|
||||||
|
const contextMenu = (
|
||||||
|
<DropdownMenu
|
||||||
|
className="with-menu-transitions"
|
||||||
|
trigger={SettingsMenuButton}
|
||||||
|
positionX="right"
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
icon="link-badge"
|
||||||
|
onClick={handleCopyLink}
|
||||||
|
>
|
||||||
|
{lang('CopyLink')}
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="forward"
|
||||||
|
onClick={handleLinkShare}
|
||||||
|
>
|
||||||
|
{lang('Share')}
|
||||||
|
</MenuItem>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
|
||||||
|
const uniqueGiftModalHeader = (
|
||||||
|
<div
|
||||||
|
className={styles.modalHeader}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
className={styles.modalCloseButton}
|
||||||
|
round
|
||||||
|
color="translucent-white"
|
||||||
|
size="smaller"
|
||||||
|
ariaLabel={lang('Close')}
|
||||||
|
onClick={handleClose}
|
||||||
|
>
|
||||||
|
<Icon name="close" />
|
||||||
|
</Button>
|
||||||
|
{contextMenu}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const uniqueGiftHeader = isUniqueGift && (
|
const uniqueGiftHeader = isUniqueGift && (
|
||||||
<div className={buildClassName(styles.header, styles.uniqueGift)}>
|
<div className={buildClassName(styles.header, styles.uniqueGift)}>
|
||||||
<UniqueGiftHeader
|
<UniqueGiftHeader
|
||||||
@ -501,19 +579,21 @@ const GiftInfoModal = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
modalHeader: isUniqueGift ? uniqueGiftModalHeader : undefined,
|
||||||
header: isUniqueGift ? uniqueGiftHeader : regularHeader,
|
header: isUniqueGift ? uniqueGiftHeader : regularHeader,
|
||||||
tableData,
|
tableData,
|
||||||
footer,
|
footer,
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
typeGift, savedGift, renderingTargetPeer, giftSticker, lang, canUpdate, canConvertDifference, isSender, oldLang,
|
typeGift, savedGift, renderingTargetPeer, giftSticker, lang, canUpdate, canConvertDifference, isSender, oldLang,
|
||||||
gift, giftAttributes, renderFooterButton, isTargetChat,
|
gift, giftAttributes, renderFooterButton, isTargetChat, SettingsMenuButton,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TableInfoModal
|
<TableInfoModal
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
|
modalHeader={modalData?.modalHeader}
|
||||||
header={modalData?.header}
|
header={modalData?.header}
|
||||||
hasBackdrop={gift?.type === 'starGiftUnique'}
|
hasBackdrop={gift?.type === 'starGiftUnique'}
|
||||||
tableData={modalData?.tableData}
|
tableData={modalData?.tableData}
|
||||||
|
|||||||
1
src/types/language.d.ts
vendored
1
src/types/language.d.ts
vendored
@ -1295,6 +1295,7 @@ export interface LangPair {
|
|||||||
'ViewButtonStickerset': undefined;
|
'ViewButtonStickerset': undefined;
|
||||||
'ViewButtonGiftUnique': undefined;
|
'ViewButtonGiftUnique': undefined;
|
||||||
'AuthContinueOnThisLanguage': undefined;
|
'AuthContinueOnThisLanguage': undefined;
|
||||||
|
'Share': undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user