Unique Gift: Show TON link (#5647)

Co-authored-by: Alexander Zinchuk <alx.zinchuk@gmail.com>
This commit is contained in:
zubiden 2025-03-01 17:59:26 +01:00 committed by Alexander Zinchuk
parent e8b4a4c00d
commit f93f678ee5
8 changed files with 49 additions and 18 deletions

View File

@ -86,6 +86,7 @@ export interface GramJsAppConfig extends LimitsConfig {
stargifts_message_length_max?: number; stargifts_message_length_max?: number;
stargifts_convert_period_max?: number; stargifts_convert_period_max?: number;
starref_start_param_prefixes?: string[]; starref_start_param_prefixes?: string[];
ton_blockchain_explorer_url?: string;
} }
function buildEmojiSounds(appConfig: GramJsAppConfig) { function buildEmojiSounds(appConfig: GramJsAppConfig) {
@ -172,5 +173,6 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp
starGiftMaxMessageLength: appConfig.stargifts_message_length_max, starGiftMaxMessageLength: appConfig.stargifts_message_length_max,
starGiftMaxConvertPeriod: appConfig.stargifts_convert_period_max, starGiftMaxConvertPeriod: appConfig.stargifts_convert_period_max,
starRefStartPrefixes: appConfig.starref_start_param_prefixes, starRefStartPrefixes: appConfig.starref_start_param_prefixes,
tonExplorerUrl: appConfig.ton_blockchain_explorer_url,
}; };
} }

View File

@ -17,6 +17,7 @@ export function buildApiStarGift(starGift: GramJs.TypeStarGift): ApiStarGift {
if (starGift instanceof GramJs.StarGiftUnique) { if (starGift instanceof GramJs.StarGiftUnique) {
const { const {
id, num, ownerId, ownerName, title, attributes, availabilityIssued, availabilityTotal, slug, ownerAddress, id, num, ownerId, ownerName, title, attributes, availabilityIssued, availabilityTotal, slug, ownerAddress,
giftAddress,
} = starGift; } = starGift;
return { return {
@ -31,6 +32,7 @@ export function buildApiStarGift(starGift: GramJs.TypeStarGift): ApiStarGift {
totalCount: availabilityTotal, totalCount: availabilityTotal,
issuedCount: availabilityIssued, issuedCount: availabilityIssued,
slug, slug,
giftAddress,
}; };
} }

View File

@ -241,6 +241,7 @@ export interface ApiAppConfig {
starGiftMaxMessageLength?: number; starGiftMaxMessageLength?: number;
starGiftMaxConvertPeriod?: number; starGiftMaxConvertPeriod?: number;
starRefStartPrefixes?: string[]; starRefStartPrefixes?: string[];
tonExplorerUrl?: string;
} }
export interface ApiConfig { export interface ApiConfig {

View File

@ -218,6 +218,7 @@ export interface ApiStarGiftUnique {
totalCount: number; totalCount: number;
attributes: ApiStarGiftAttribute[]; attributes: ApiStarGiftAttribute[];
slug: string; slug: string;
giftAddress?: string;
} }
export type ApiStarGift = ApiStarGiftRegular | ApiStarGiftUnique; export type ApiStarGift = ApiStarGiftRegular | ApiStarGiftUnique;

View File

@ -1405,6 +1405,8 @@
"GiftInfoChannelHidden" = "This gift is hidden from visitors of your channel. {link}"; "GiftInfoChannelHidden" = "This gift is hidden from visitors of your channel. {link}";
"GiftInfoSavedHide" = "Hide >"; "GiftInfoSavedHide" = "Hide >";
"GiftInfoSavedShow" = "Show >"; "GiftInfoSavedShow" = "Show >";
"GiftInfoTonText" = "This gift is on the TON Blockchain. {link}";
"GiftInfoTonLinkText" = "View >";
"GiftInfoAvailability" = "Availability"; "GiftInfoAvailability" = "Availability";
"GiftInfoAvailabilityValue_one" = "{count} of {total} left"; "GiftInfoAvailabilityValue_one" = "{count} of {total} left";
"GiftInfoAvailabilityValue_other" = "{count} of {total} left"; "GiftInfoAvailabilityValue_other" = "{count} of {total} left";
@ -1569,7 +1571,8 @@
"ActionUnsupportedDescription" = "Please use one of our apps to complete this action."; "ActionUnsupportedDescription" = "Please use one of our apps to complete this action.";
"LocationPermissionText" = "**{name}** requests access to set your **location**. You will be able to revoke this access in the profile page of **{name}**."; "LocationPermissionText" = "**{name}** requests access to set your **location**. You will be able to revoke this access in the profile page of **{name}**.";
"UnlockMoreSimilarBots" = "Show More Apps"; "UnlockMoreSimilarBots" = "Show More Apps";
"MoreSimilarBotsText" = "Subscribe to **Telegram Premium** to unlock up to {count} similar apps."; "MoreSimilarBotsDescription_one" = "Subscribe to **Telegram Premium** to unlock up to {count} similar bot.";
"MoreSimilarBotsDescription_other" = "Subscribe to **Telegram Premium** to unlock up to {count} similar bots.";
"GiftWasNotFound" = "Gift was not found"; "GiftWasNotFound" = "Gift was not found";
"ViewButtonRequestJoin" = "REQUEST TO JOIN"; "ViewButtonRequestJoin" = "REQUEST TO JOIN";
"ViewButtonMessage" = "VIEW MESSAGE"; "ViewButtonMessage" = "VIEW MESSAGE";

View File

@ -33,6 +33,7 @@ import AnimatedIconFromSticker from '../../../common/AnimatedIconFromSticker';
import Avatar from '../../../common/Avatar'; import Avatar from '../../../common/Avatar';
import BadgeButton from '../../../common/BadgeButton'; import BadgeButton from '../../../common/BadgeButton';
import Icon from '../../../common/icons/Icon'; import Icon from '../../../common/icons/Icon';
import SafeLink from '../../../common/SafeLink';
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 DropdownMenu from '../../../ui/DropdownMenu';
@ -55,6 +56,7 @@ type StateProps = {
hasAdminRights?: boolean; hasAdminRights?: boolean;
currentUserEmojiStatus?: ApiEmojiStatusType; currentUserEmojiStatus?: ApiEmojiStatusType;
collectibleEmojiStatuses?: ApiEmojiStatusType[]; collectibleEmojiStatuses?: ApiEmojiStatusType[];
tonExplorerUrl?: string;
}; };
const STICKER_SIZE = 120; const STICKER_SIZE = 120;
@ -68,6 +70,7 @@ const GiftInfoModal = ({
hasAdminRights, hasAdminRights,
currentUserEmojiStatus, currentUserEmojiStatus,
collectibleEmojiStatuses, collectibleEmojiStatuses,
tonExplorerUrl,
}: OwnProps & StateProps) => { }: OwnProps & StateProps) => {
const { const {
closeGiftInfoModal, closeGiftInfoModal,
@ -599,21 +602,34 @@ const GiftInfoModal = ({
} }
} }
const tonLink = tonExplorerUrl && isGiftUnique && gift.giftAddress && (
`${tonExplorerUrl}${gift.giftAddress}`
);
const footer = ( const footer = (
<div className={styles.footer}> <div className={styles.footer}>
{canUpdate && ( {(canUpdate || tonLink) && (
<div className={styles.footerDescription}> <div className={styles.footerDescription}>
<div> {tonLink && (
{lang(`GiftInfo${isTargetChat ? 'Channel' : ''}${isUnsaved ? 'Hidden' : 'Saved'}`, { <div>
link: ( {lang('GiftInfoTonText', {
<Link isPrimary onClick={handleTriggerVisibility}> link: <SafeLink url={tonLink} text={lang('GiftInfoTonLinkText')} />,
{lang(`GiftInfoSaved${isUnsaved ? 'Show' : 'Hide'}`)} }, { withNodes: true })}
</Link> </div>
), )}
}, { {canUpdate && (
withNodes: true, <div>
})} {lang(`GiftInfo${isTargetChat ? 'Channel' : ''}${isUnsaved ? 'Hidden' : 'Saved'}`, {
</div> link: (
<Link isPrimary onClick={handleTriggerVisibility}>
{lang(`GiftInfoSaved${isUnsaved ? 'Show' : 'Hide'}`)}
</Link>
),
}, {
withNodes: true,
})}
</div>
)}
{isVisibleForMe && ( {isVisibleForMe && (
<div> <div>
{lang('GiftInfoSenderHidden')} {lang('GiftInfoSenderHidden')}
@ -633,7 +649,7 @@ const GiftInfoModal = ({
}; };
}, [ }, [
typeGift, savedGift, renderingTargetPeer, giftSticker, lang, typeGift, savedGift, renderingTargetPeer, giftSticker, lang,
canUpdate, canConvertDifference, isSender, oldLang, canUpdate, canConvertDifference, isSender, oldLang, tonExplorerUrl,
gift, giftAttributes, renderFooterButton, isTargetChat, gift, giftAttributes, renderFooterButton, isTargetChat,
SettingsMenuButton, isOpen, isGiftUnique, canWear, canTakeOff, SettingsMenuButton, isOpen, isGiftUnique, canWear, canTakeOff,
]); ]);
@ -703,6 +719,7 @@ export default memo(withGlobal<OwnProps>(
targetPeer, targetPeer,
currentUserId: global.currentUserId, currentUserId: global.currentUserId,
starGiftMaxConvertPeriod: global.appConfig?.starGiftMaxConvertPeriod, starGiftMaxConvertPeriod: global.appConfig?.starGiftMaxConvertPeriod,
tonExplorerUrl: global.appConfig?.tonExplorerUrl,
hasAdminRights, hasAdminRights,
currentUserEmojiStatus, currentUserEmojiStatus,
collectibleEmojiStatuses, collectibleEmojiStatuses,

View File

@ -807,9 +807,10 @@ const Profile: FC<OwnProps & StateProps> = ({
<Icon name="unlock-badge" /> <Icon name="unlock-badge" />
</Button> </Button>
<div className="more-similar"> <div className="more-similar">
{renderText(lang('MoreSimilarBotsText', { count: limitSimilarPeers }, { {renderText(lang('MoreSimilarBotsDescription', { count: limitSimilarPeers }, {
withNodes: true, withNodes: true,
withMarkdown: true, withMarkdown: true,
pluralValue: limitSimilarPeers,
}))} }))}
</div> </div>
</> </>

View File

@ -1178,6 +1178,7 @@ export interface LangPair {
'GiftInfoConvertDescription2': undefined; 'GiftInfoConvertDescription2': undefined;
'GiftInfoSavedHide': undefined; 'GiftInfoSavedHide': undefined;
'GiftInfoSavedShow': undefined; 'GiftInfoSavedShow': undefined;
'GiftInfoTonLinkText': undefined;
'GiftInfoAvailability': undefined; 'GiftInfoAvailability': undefined;
'GiftInfoFirstSale': undefined; 'GiftInfoFirstSale': undefined;
'GiftInfoLastSale': undefined; 'GiftInfoLastSale': undefined;
@ -1768,6 +1769,9 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'GiftInfoChannelHidden': { 'GiftInfoChannelHidden': {
'link': V; 'link': V;
}; };
'GiftInfoTonText': {
'link': V;
};
'GiftInfoIssued': { 'GiftInfoIssued': {
'issued': V; 'issued': V;
'total': V; 'total': V;
@ -1892,9 +1896,6 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'LocationPermissionText': { 'LocationPermissionText': {
'name': V; 'name': V;
}; };
'MoreSimilarBotsText': {
'count': V;
};
'ActionPinnedText': { 'ActionPinnedText': {
'from': V; 'from': V;
'text': V; 'text': V;
@ -2424,6 +2425,9 @@ export interface LangPairPluralWithVariables<V extends unknown = LangVariable> {
'FolderLinkNotificationUpdatedSubtitle': { 'FolderLinkNotificationUpdatedSubtitle': {
'count': V; 'count': V;
}; };
'MoreSimilarBotsDescription': {
'count': V;
};
'ActionGameScore': { 'ActionGameScore': {
'from': V; 'from': V;
'count': V; 'count': V;