Gifts: Support unique links for gifts (#5450)
This commit is contained in:
parent
93cb31c980
commit
86cb0f5ee6
141
src/api/gramjs/apiBuilders/gifts.ts
Normal file
141
src/api/gramjs/apiBuilders/gifts.ts
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
import { Api as GramJs } from '../../../lib/gramjs';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
ApiStarGift,
|
||||||
|
ApiStarGiftAttribute,
|
||||||
|
ApiUserStarGift,
|
||||||
|
} from '../../types';
|
||||||
|
|
||||||
|
import { numberToHexColor } from '../../../util/colors';
|
||||||
|
import { addDocumentToLocalDb } from '../helpers';
|
||||||
|
import { buildApiFormattedText } from './common';
|
||||||
|
import { buildApiPeerId } from './peers';
|
||||||
|
import { buildStickerFromDocument } from './symbols';
|
||||||
|
|
||||||
|
export function buildApiStarGift(starGift: GramJs.TypeStarGift): ApiStarGift {
|
||||||
|
if (starGift instanceof GramJs.StarGiftUnique) {
|
||||||
|
const {
|
||||||
|
id, num, ownerId, ownerName, title, attributes, availabilityIssued, availabilityTotal,
|
||||||
|
} = starGift;
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'starGiftUnique',
|
||||||
|
id: id.toString(),
|
||||||
|
number: num,
|
||||||
|
ownerId: ownerId && buildApiPeerId(ownerId, 'user'),
|
||||||
|
ownerName,
|
||||||
|
attributes: attributes.map(buildApiStarGiftAttribute).filter(Boolean),
|
||||||
|
title,
|
||||||
|
totalCount: availabilityTotal,
|
||||||
|
issuedCount: availabilityIssued,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
id, limited, stars, availabilityRemains, availabilityTotal, convertStars, firstSaleDate, lastSaleDate, soldOut,
|
||||||
|
birthday, upgradeStars,
|
||||||
|
} = starGift;
|
||||||
|
|
||||||
|
addDocumentToLocalDb(starGift.sticker);
|
||||||
|
|
||||||
|
const sticker = buildStickerFromDocument(starGift.sticker)!;
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'starGift',
|
||||||
|
id: id.toString(),
|
||||||
|
isLimited: limited,
|
||||||
|
sticker,
|
||||||
|
stars: stars.toJSNumber(),
|
||||||
|
availabilityRemains,
|
||||||
|
availabilityTotal,
|
||||||
|
starsToConvert: convertStars.toJSNumber(),
|
||||||
|
firstSaleDate,
|
||||||
|
lastSaleDate,
|
||||||
|
isSoldOut: soldOut,
|
||||||
|
isBirthday: birthday,
|
||||||
|
upgradeStars: upgradeStars?.toJSNumber(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildApiStarGiftAttribute(attribute: GramJs.TypeStarGiftAttribute): ApiStarGiftAttribute | undefined {
|
||||||
|
if (attribute instanceof GramJs.StarGiftAttributeModel) {
|
||||||
|
const sticker = buildStickerFromDocument(attribute.document);
|
||||||
|
if (!sticker) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
addDocumentToLocalDb(attribute.document);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'model',
|
||||||
|
name: attribute.name,
|
||||||
|
rarityPercent: attribute.rarityPermille / 10,
|
||||||
|
sticker,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attribute instanceof GramJs.StarGiftAttributePattern) {
|
||||||
|
const sticker = buildStickerFromDocument(attribute.document);
|
||||||
|
if (!sticker) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
addDocumentToLocalDb(attribute.document);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'pattern',
|
||||||
|
name: attribute.name,
|
||||||
|
rarityPercent: attribute.rarityPermille / 10,
|
||||||
|
sticker,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attribute instanceof GramJs.StarGiftAttributeBackdrop) {
|
||||||
|
const {
|
||||||
|
name, rarityPermille, centerColor, edgeColor, patternColor, textColor,
|
||||||
|
} = attribute;
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'backdrop',
|
||||||
|
name,
|
||||||
|
rarityPercent: rarityPermille / 10,
|
||||||
|
centerColor: numberToHexColor(centerColor),
|
||||||
|
edgeColor: numberToHexColor(edgeColor),
|
||||||
|
patternColor: numberToHexColor(patternColor),
|
||||||
|
textColor: numberToHexColor(textColor),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attribute instanceof GramJs.StarGiftAttributeOriginalDetails) {
|
||||||
|
const {
|
||||||
|
date, recipientId, message, senderId,
|
||||||
|
} = attribute;
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'originalDetails',
|
||||||
|
date,
|
||||||
|
recipientId: recipientId && buildApiPeerId(recipientId, 'user'),
|
||||||
|
message: message && buildApiFormattedText(message),
|
||||||
|
senderId: senderId && buildApiPeerId(senderId, 'user'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildApiUserStarGift(userStarGift: GramJs.UserStarGift): ApiUserStarGift {
|
||||||
|
const {
|
||||||
|
gift, date, convertStars, fromId, message, msgId, nameHidden, unsaved,
|
||||||
|
} = userStarGift;
|
||||||
|
|
||||||
|
return {
|
||||||
|
gift: buildApiStarGift(gift),
|
||||||
|
date,
|
||||||
|
starsToConvert: convertStars?.toJSNumber(),
|
||||||
|
fromId: fromId && buildApiPeerId(fromId, 'user'),
|
||||||
|
message: message && buildApiFormattedText(message),
|
||||||
|
messageId: msgId,
|
||||||
|
isNameHidden: nameHidden,
|
||||||
|
isUnsaved: unsaved,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ import type {
|
|||||||
ApiPaidMedia,
|
ApiPaidMedia,
|
||||||
ApiPhoto,
|
ApiPhoto,
|
||||||
ApiPoll,
|
ApiPoll,
|
||||||
|
ApiStarGiftUnique,
|
||||||
ApiSticker,
|
ApiSticker,
|
||||||
ApiVideo,
|
ApiVideo,
|
||||||
ApiVoice,
|
ApiVoice,
|
||||||
@ -42,6 +43,7 @@ import {
|
|||||||
buildApiThumbnailFromPath,
|
buildApiThumbnailFromPath,
|
||||||
buildApiThumbnailFromStripped,
|
buildApiThumbnailFromStripped,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
import { buildApiStarGift } from './gifts';
|
||||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
||||||
import { buildStickerFromDocument, processStickerResult } from './symbols';
|
import { buildStickerFromDocument, processStickerResult } from './symbols';
|
||||||
|
|
||||||
@ -753,9 +755,12 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
|
|||||||
audio = buildAudioFromDocument(document);
|
audio = buildAudioFromDocument(document);
|
||||||
}
|
}
|
||||||
let story: ApiWebPageStoryData | undefined;
|
let story: ApiWebPageStoryData | undefined;
|
||||||
|
let gift: ApiStarGiftUnique | undefined;
|
||||||
let stickers: ApiWebPageStickerData | undefined;
|
let stickers: ApiWebPageStickerData | undefined;
|
||||||
const attributeStory = attributes
|
const attributeStory = attributes
|
||||||
?.find((a): a is GramJs.WebPageAttributeStory => a instanceof GramJs.WebPageAttributeStory);
|
?.find((a): a is GramJs.WebPageAttributeStory => a instanceof GramJs.WebPageAttributeStory);
|
||||||
|
const attributeGift = attributes
|
||||||
|
?.find((a): a is GramJs.WebPageAttributeUniqueStarGift => a instanceof GramJs.WebPageAttributeUniqueStarGift);
|
||||||
if (attributeStory) {
|
if (attributeStory) {
|
||||||
const peerId = getApiChatIdFromMtpPeer(attributeStory.peer);
|
const peerId = getApiChatIdFromMtpPeer(attributeStory.peer);
|
||||||
story = {
|
story = {
|
||||||
@ -767,6 +772,10 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
|
|||||||
addStoryToLocalDb(attributeStory.story, peerId);
|
addStoryToLocalDb(attributeStory.story, peerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (attributeGift) {
|
||||||
|
const starGift = buildApiStarGift(attributeGift.gift);
|
||||||
|
gift = starGift.type === 'starGiftUnique' ? starGift : undefined;
|
||||||
|
}
|
||||||
const attributeStickers = attributes?.find((a): a is GramJs.WebPageAttributeStickerSet => (
|
const attributeStickers = attributes?.find((a): a is GramJs.WebPageAttributeStickerSet => (
|
||||||
a instanceof GramJs.WebPageAttributeStickerSet
|
a instanceof GramJs.WebPageAttributeStickerSet
|
||||||
));
|
));
|
||||||
@ -798,6 +807,7 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
|
|||||||
video,
|
video,
|
||||||
audio,
|
audio,
|
||||||
story,
|
story,
|
||||||
|
gift,
|
||||||
stickers,
|
stickers,
|
||||||
mediaSize,
|
mediaSize,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -63,8 +63,8 @@ import {
|
|||||||
buildApiFormattedText,
|
buildApiFormattedText,
|
||||||
buildApiPhoto,
|
buildApiPhoto,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
import { buildApiStarGift } from './gifts';
|
||||||
import { buildMessageContent, buildMessageMediaContent, buildMessageTextContent } from './messageContent';
|
import { buildMessageContent, buildMessageMediaContent, buildMessageTextContent } from './messageContent';
|
||||||
import { buildApiStarGift } from './payments';
|
|
||||||
import { buildApiPeerColor, buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
import { buildApiPeerColor, buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
||||||
import { buildMessageReactions } from './reactions';
|
import { buildMessageReactions } from './reactions';
|
||||||
|
|
||||||
|
|||||||
@ -19,8 +19,6 @@ import type {
|
|||||||
ApiPrepaidGiveaway,
|
ApiPrepaidGiveaway,
|
||||||
ApiPrepaidStarsGiveaway,
|
ApiPrepaidStarsGiveaway,
|
||||||
ApiReceipt,
|
ApiReceipt,
|
||||||
ApiStarGift,
|
|
||||||
ApiStarGiftAttribute,
|
|
||||||
ApiStarGiveawayOption,
|
ApiStarGiveawayOption,
|
||||||
ApiStarsAmount,
|
ApiStarsAmount,
|
||||||
ApiStarsGiveawayWinnerOption,
|
ApiStarsGiveawayWinnerOption,
|
||||||
@ -28,19 +26,17 @@ import type {
|
|||||||
ApiStarsTransaction,
|
ApiStarsTransaction,
|
||||||
ApiStarsTransactionPeer,
|
ApiStarsTransactionPeer,
|
||||||
ApiStarTopupOption,
|
ApiStarTopupOption,
|
||||||
ApiUserStarGift,
|
|
||||||
BoughtPaidMedia,
|
BoughtPaidMedia,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import { numberToHexColor } from '../../../util/colors';
|
import { addWebDocumentToLocalDb } from '../helpers';
|
||||||
import { addDocumentToLocalDb, addWebDocumentToLocalDb } from '../helpers';
|
|
||||||
import { buildApiStarsSubscriptionPricing } from './chats';
|
import { buildApiStarsSubscriptionPricing } from './chats';
|
||||||
import { buildApiFormattedText, buildApiMessageEntity } from './common';
|
import { buildApiMessageEntity } from './common';
|
||||||
|
import { buildApiStarGift } from './gifts';
|
||||||
import { omitVirtualClassFields } from './helpers';
|
import { omitVirtualClassFields } from './helpers';
|
||||||
import { buildApiDocument, buildApiWebDocument, buildMessageMediaContent } from './messageContent';
|
import { buildApiDocument, buildApiWebDocument, buildMessageMediaContent } from './messageContent';
|
||||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
||||||
import { buildStatisticsPercentage } from './statistics';
|
import { buildStatisticsPercentage } from './statistics';
|
||||||
import { buildStickerFromDocument } from './symbols';
|
|
||||||
|
|
||||||
export function buildShippingOptions(shippingOptions: GramJs.ShippingOption[] | undefined) {
|
export function buildShippingOptions(shippingOptions: GramJs.ShippingOption[] | undefined) {
|
||||||
if (!shippingOptions) {
|
if (!shippingOptions) {
|
||||||
@ -612,131 +608,3 @@ export function buildApiStarTopupOption(option: GramJs.TypeStarsTopupOption): Ap
|
|||||||
isExtended: extended,
|
isExtended: extended,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildApiStarGift(starGift: GramJs.TypeStarGift): ApiStarGift {
|
|
||||||
if (starGift instanceof GramJs.StarGiftUnique) {
|
|
||||||
const {
|
|
||||||
id, num, ownerId, ownerName, title, attributes, availabilityIssued, availabilityTotal,
|
|
||||||
} = starGift;
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'starGiftUnique',
|
|
||||||
id: id.toString(),
|
|
||||||
number: num,
|
|
||||||
ownerId: ownerId && buildApiPeerId(ownerId, 'user'),
|
|
||||||
ownerName,
|
|
||||||
attributes: attributes.map(buildApiStarGiftAttribute).filter(Boolean),
|
|
||||||
title,
|
|
||||||
totalCount: availabilityTotal,
|
|
||||||
issuedCount: availabilityIssued,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
id, limited, stars, availabilityRemains, availabilityTotal, convertStars, firstSaleDate, lastSaleDate, soldOut,
|
|
||||||
birthday, upgradeStars,
|
|
||||||
} = starGift;
|
|
||||||
|
|
||||||
addDocumentToLocalDb(starGift.sticker);
|
|
||||||
|
|
||||||
const sticker = buildStickerFromDocument(starGift.sticker)!;
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'starGift',
|
|
||||||
id: id.toString(),
|
|
||||||
isLimited: limited,
|
|
||||||
sticker,
|
|
||||||
stars: stars.toJSNumber(),
|
|
||||||
availabilityRemains,
|
|
||||||
availabilityTotal,
|
|
||||||
starsToConvert: convertStars.toJSNumber(),
|
|
||||||
firstSaleDate,
|
|
||||||
lastSaleDate,
|
|
||||||
isSoldOut: soldOut,
|
|
||||||
isBirthday: birthday,
|
|
||||||
upgradeStars: upgradeStars?.toJSNumber(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function buildApiStarGiftAttribute(attribute: GramJs.TypeStarGiftAttribute): ApiStarGiftAttribute | undefined {
|
|
||||||
if (attribute instanceof GramJs.StarGiftAttributeModel) {
|
|
||||||
const sticker = buildStickerFromDocument(attribute.document);
|
|
||||||
if (!sticker) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
addDocumentToLocalDb(attribute.document);
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'model',
|
|
||||||
name: attribute.name,
|
|
||||||
rarityPercent: attribute.rarityPermille / 10,
|
|
||||||
sticker,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribute instanceof GramJs.StarGiftAttributePattern) {
|
|
||||||
const sticker = buildStickerFromDocument(attribute.document);
|
|
||||||
if (!sticker) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
addDocumentToLocalDb(attribute.document);
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'pattern',
|
|
||||||
name: attribute.name,
|
|
||||||
rarityPercent: attribute.rarityPermille / 10,
|
|
||||||
sticker,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribute instanceof GramJs.StarGiftAttributeBackdrop) {
|
|
||||||
const {
|
|
||||||
name, rarityPermille, centerColor, edgeColor, patternColor, textColor,
|
|
||||||
} = attribute;
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'backdrop',
|
|
||||||
name,
|
|
||||||
rarityPercent: rarityPermille / 10,
|
|
||||||
centerColor: numberToHexColor(centerColor),
|
|
||||||
edgeColor: numberToHexColor(edgeColor),
|
|
||||||
patternColor: numberToHexColor(patternColor),
|
|
||||||
textColor: numberToHexColor(textColor),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribute instanceof GramJs.StarGiftAttributeOriginalDetails) {
|
|
||||||
const {
|
|
||||||
date, recipientId, message, senderId,
|
|
||||||
} = attribute;
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'originalDetails',
|
|
||||||
date,
|
|
||||||
recipientId: recipientId && buildApiPeerId(recipientId, 'user'),
|
|
||||||
message: message && buildApiFormattedText(message),
|
|
||||||
senderId: senderId && buildApiPeerId(senderId, 'user'),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function buildApiUserStarGift(userStarGift: GramJs.UserStarGift): ApiUserStarGift {
|
|
||||||
const {
|
|
||||||
gift, date, convertStars, fromId, message, msgId, nameHidden, unsaved,
|
|
||||||
} = userStarGift;
|
|
||||||
|
|
||||||
return {
|
|
||||||
gift: buildApiStarGift(gift),
|
|
||||||
date,
|
|
||||||
starsToConvert: convertStars?.toJSNumber(),
|
|
||||||
fromId: fromId && buildApiPeerId(fromId, 'user'),
|
|
||||||
message: message && buildApiFormattedText(message),
|
|
||||||
messageId: msgId,
|
|
||||||
isNameHidden: nameHidden,
|
|
||||||
isUnsaved: unsaved,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@ -12,6 +12,10 @@ import type {
|
|||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import { DEBUG } from '../../../config';
|
import { DEBUG } from '../../../config';
|
||||||
|
import {
|
||||||
|
buildApiStarGift,
|
||||||
|
buildApiUserStarGift,
|
||||||
|
} from '../apiBuilders/gifts';
|
||||||
import {
|
import {
|
||||||
buildApiBoost,
|
buildApiBoost,
|
||||||
buildApiBoostsStatus,
|
buildApiBoostsStatus,
|
||||||
@ -22,14 +26,12 @@ import {
|
|||||||
buildApiPremiumGiftCodeOption,
|
buildApiPremiumGiftCodeOption,
|
||||||
buildApiPremiumPromo,
|
buildApiPremiumPromo,
|
||||||
buildApiReceipt,
|
buildApiReceipt,
|
||||||
buildApiStarGift,
|
|
||||||
buildApiStarsAmount,
|
buildApiStarsAmount,
|
||||||
buildApiStarsGiftOptions,
|
buildApiStarsGiftOptions,
|
||||||
buildApiStarsGiveawayOptions,
|
buildApiStarsGiveawayOptions,
|
||||||
buildApiStarsSubscription,
|
buildApiStarsSubscription,
|
||||||
buildApiStarsTransaction,
|
buildApiStarsTransaction,
|
||||||
buildApiStarTopupOption,
|
buildApiStarTopupOption,
|
||||||
buildApiUserStarGift,
|
|
||||||
buildShippingOptions,
|
buildShippingOptions,
|
||||||
} from '../apiBuilders/payments';
|
} from '../apiBuilders/payments';
|
||||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||||
@ -638,3 +640,15 @@ export async function fetchStarsTopupOptions() {
|
|||||||
|
|
||||||
return result.map(buildApiStarTopupOption);
|
return result.map(buildApiStarTopupOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchUniqueStarGift({ slug }: {
|
||||||
|
slug: string;
|
||||||
|
}) {
|
||||||
|
const result = await invokeRequest(new GramJs.payments.GetUniqueStarGift({ slug }));
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const gift = buildApiStarGift(result.gift);
|
||||||
|
return gift.type === 'starGiftUnique' ? gift : undefined;
|
||||||
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import type {
|
|||||||
ApiLabeledPrice,
|
ApiLabeledPrice,
|
||||||
ApiPremiumGiftCodeOption,
|
ApiPremiumGiftCodeOption,
|
||||||
ApiStarGift,
|
ApiStarGift,
|
||||||
|
ApiStarGiftUnique,
|
||||||
} from './payments';
|
} from './payments';
|
||||||
import type {
|
import type {
|
||||||
ApiMessageStoryData, ApiStory, ApiWebPageStickerData, ApiWebPageStoryData,
|
ApiMessageStoryData, ApiStory, ApiWebPageStickerData, ApiWebPageStoryData,
|
||||||
@ -543,6 +544,7 @@ export interface ApiWebPage {
|
|||||||
document?: ApiDocument;
|
document?: ApiDocument;
|
||||||
video?: ApiVideo;
|
video?: ApiVideo;
|
||||||
story?: ApiWebPageStoryData;
|
story?: ApiWebPageStoryData;
|
||||||
|
gift?: ApiStarGiftUnique;
|
||||||
stickers?: ApiWebPageStickerData;
|
stickers?: ApiWebPageStickerData;
|
||||||
mediaSize?: WebPageMediaSize;
|
mediaSize?: WebPageMediaSize;
|
||||||
hasLargeMedia?: boolean;
|
hasLargeMedia?: boolean;
|
||||||
|
|||||||
@ -1494,3 +1494,19 @@
|
|||||||
"ActionUnsupportedTitle" = "Action not supported yet";
|
"ActionUnsupportedTitle" = "Action not supported yet";
|
||||||
"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}**.";
|
||||||
|
"GiftWasNotFound" = "Gift was not found";
|
||||||
|
"ViewButtonRequestJoin" = "REQUEST TO JOIN";
|
||||||
|
"ViewButtonMessage" = "VIEW MESSAGE";
|
||||||
|
"ViewButtonBot" = "VIEW BOT";
|
||||||
|
"ViewButtonVoiceChat" = "VOICE CHAT";
|
||||||
|
"ViewButtonVoiceChatChannel" = "LIVE STREAM";
|
||||||
|
"ViewButtonGroup" = "VIEW GROUP";
|
||||||
|
"ViewButtonChannel" = "VIEW CHANNEL";
|
||||||
|
"ViewButtonUser" = "SEND MESSAGE";
|
||||||
|
"ViewButtonBotApp" = "LAUNCH";
|
||||||
|
"ViewChatList" = "VIEW CHAT LIST";
|
||||||
|
"ViewButtonStory" = "VIEW STORY";
|
||||||
|
"ViewButtonBoost" = "BOOST";
|
||||||
|
"ViewButtonStickerset" = "VIEW STICKERS";
|
||||||
|
"ViewButtonGiftUnique" = "VIEW COLLECTIBLE";
|
||||||
|
|
||||||
|
|||||||
@ -277,6 +277,7 @@
|
|||||||
max-width: 17rem;
|
max-width: 17rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.web-page-gift,
|
||||||
.action-message-gift {
|
.action-message-gift {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
width: 13.75rem;
|
width: 13.75rem;
|
||||||
@ -290,10 +291,21 @@
|
|||||||
font-weight: var(--font-weight-semibold);
|
font-weight: var(--font-weight-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.web-page-gift {
|
||||||
|
position: relative;
|
||||||
|
min-width: 12.5rem;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 0;
|
||||||
|
padding-block: 2rem !important;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.web-page-centered,
|
||||||
.action-message-centered {
|
.action-message-centered {
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.web-page-unique,
|
||||||
.action-message-unique {
|
.action-message-unique {
|
||||||
&::before {
|
&::before {
|
||||||
content: "";
|
content: "";
|
||||||
@ -305,6 +317,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.web-page-unique-background-wrapper,
|
||||||
.action-message-unique-background-wrapper {
|
.action-message-unique-background-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
@ -312,11 +325,15 @@
|
|||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.web-page-unique-background,
|
||||||
.action-message-unique-background {
|
.action-message-unique-background {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
top: -6rem;
|
top: -6rem;
|
||||||
}
|
}
|
||||||
|
.web-page-unique-background {
|
||||||
|
top: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.action-message-user-caption,
|
.action-message-user-caption,
|
||||||
.action-message-stars-balance {
|
.action-message-stars-balance {
|
||||||
|
|||||||
@ -34,6 +34,14 @@
|
|||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--unique-sticker {
|
||||||
|
position: relative;
|
||||||
|
width: 7.5rem;
|
||||||
|
height: 7.5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-block: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
&--stickers {
|
&--stickers {
|
||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
@ -60,6 +68,7 @@
|
|||||||
.WebPage--content {
|
.WebPage--content {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&.is-gift,
|
||||||
&.is-story {
|
&.is-story {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
@ -85,6 +94,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-gift &--quick-button {
|
||||||
|
border-top: inherit;
|
||||||
|
margin-top: 0.0625rem;
|
||||||
|
margin-bottom: -0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
&-text {
|
&-text {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@ -1,21 +1,24 @@
|
|||||||
import type { FC } from '../../../lib/teact/teact';
|
import type { FC } from '../../../lib/teact/teact';
|
||||||
import React, { memo, useRef } from '../../../lib/teact/teact';
|
import React, { memo, useRef } from '../../../lib/teact/teact';
|
||||||
import { getActions } from '../../../global';
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
import type { ApiMessage, ApiTypeStory } from '../../../api/types';
|
import type { ApiMessage, ApiTypeStory } from '../../../api/types';
|
||||||
import type { ObserveFn } from '../../../hooks/useIntersectionObserver';
|
import type { ObserveFn } from '../../../hooks/useIntersectionObserver';
|
||||||
import { AudioOrigin, type ISettings } from '../../../types';
|
import { AudioOrigin, type ISettings } from '../../../types';
|
||||||
|
|
||||||
import { getMessageWebPage } from '../../../global/helpers';
|
import { getMessageWebPage } from '../../../global/helpers';
|
||||||
|
import { selectCanPlayAnimatedEmojis } from '../../../global/selectors';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import trimText from '../../../util/trimText';
|
import trimText from '../../../util/trimText';
|
||||||
|
import { getGiftAttributes, getStickerFromGift } from '../../common/helpers/gifts';
|
||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
import { calculateMediaDimensions } from './helpers/mediaDimensions';
|
import { calculateMediaDimensions } from './helpers/mediaDimensions';
|
||||||
import { getWebpageButtonText } from './helpers/webpageType';
|
import { getWebpageButtonLangKey } from './helpers/webpageType';
|
||||||
|
|
||||||
import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorListener';
|
import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorListener';
|
||||||
import useAppLayout from '../../../hooks/useAppLayout';
|
import useAppLayout from '../../../hooks/useAppLayout';
|
||||||
import useEnsureStory from '../../../hooks/useEnsureStory';
|
import useEnsureStory from '../../../hooks/useEnsureStory';
|
||||||
|
import useLang from '../../../hooks/useLang';
|
||||||
import useLastCallback from '../../../hooks/useLastCallback';
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
import useOldLang from '../../../hooks/useOldLang';
|
||||||
|
|
||||||
@ -23,6 +26,7 @@ import Audio from '../../common/Audio';
|
|||||||
import Document from '../../common/Document';
|
import Document from '../../common/Document';
|
||||||
import EmojiIconBackground from '../../common/embedded/EmojiIconBackground';
|
import EmojiIconBackground from '../../common/embedded/EmojiIconBackground';
|
||||||
import PeerColorWrapper from '../../common/PeerColorWrapper';
|
import PeerColorWrapper from '../../common/PeerColorWrapper';
|
||||||
|
import RadialPatternBackground from '../../common/profile/RadialPatternBackground';
|
||||||
import SafeLink from '../../common/SafeLink';
|
import SafeLink from '../../common/SafeLink';
|
||||||
import StickerView from '../../common/StickerView';
|
import StickerView from '../../common/StickerView';
|
||||||
import Button from '../../ui/Button';
|
import Button from '../../ui/Button';
|
||||||
@ -34,6 +38,7 @@ import './WebPage.scss';
|
|||||||
|
|
||||||
const MAX_TEXT_LENGTH = 170; // symbols
|
const MAX_TEXT_LENGTH = 170; // symbols
|
||||||
const WEBPAGE_STORY_TYPE = 'telegram_story';
|
const WEBPAGE_STORY_TYPE = 'telegram_story';
|
||||||
|
const WEBPAGE_GIFT_TYPE = 'telegram_nft';
|
||||||
const STICKER_SIZE = 80;
|
const STICKER_SIZE = 80;
|
||||||
const EMOJI_SIZE = 38;
|
const EMOJI_SIZE = 38;
|
||||||
|
|
||||||
@ -60,8 +65,12 @@ type OwnProps = {
|
|||||||
onContainerClick?: ((e: React.MouseEvent) => void);
|
onContainerClick?: ((e: React.MouseEvent) => void);
|
||||||
isEditing?: boolean;
|
isEditing?: boolean;
|
||||||
};
|
};
|
||||||
|
type StateProps = {
|
||||||
|
canPlayAnimatedEmojis: boolean;
|
||||||
|
};
|
||||||
|
const STAR_GIFT_STICKER_SIZE = 120;
|
||||||
|
|
||||||
const WebPage: FC<OwnProps> = ({
|
const WebPage: FC<OwnProps & StateProps> = ({
|
||||||
message,
|
message,
|
||||||
observeIntersectionForLoading,
|
observeIntersectionForLoading,
|
||||||
observeIntersectionForPlaying,
|
observeIntersectionForPlaying,
|
||||||
@ -89,8 +98,11 @@ const WebPage: FC<OwnProps> = ({
|
|||||||
const { isMobile } = useAppLayout();
|
const { isMobile } = useAppLayout();
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const stickersRef = useRef<HTMLDivElement>(null);
|
const stickersRef = useRef<HTMLDivElement>(null);
|
||||||
|
// eslint-disable-next-line no-null/no-null
|
||||||
|
const giftStickersRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const lang = useOldLang();
|
const oldLang = useOldLang();
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
const handleMediaClick = useLastCallback(() => {
|
const handleMediaClick = useLastCallback(() => {
|
||||||
onMediaClick!();
|
onMediaClick!();
|
||||||
@ -100,8 +112,9 @@ const WebPage: FC<OwnProps> = ({
|
|||||||
onContainerClick?.(e);
|
onContainerClick?.(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleQuickButtonClick = useLastCallback(() => {
|
const handleOpenTelegramLink = useLastCallback(() => {
|
||||||
if (!webPage) return;
|
if (!webPage) return;
|
||||||
|
|
||||||
openTelegramLink({
|
openTelegramLink({
|
||||||
url: webPage.url,
|
url: webPage.url,
|
||||||
});
|
});
|
||||||
@ -132,8 +145,10 @@ const WebPage: FC<OwnProps> = ({
|
|||||||
mediaSize,
|
mediaSize,
|
||||||
} = webPage;
|
} = webPage;
|
||||||
const isStory = type === WEBPAGE_STORY_TYPE;
|
const isStory = type === WEBPAGE_STORY_TYPE;
|
||||||
|
const isGift = type === WEBPAGE_GIFT_TYPE;
|
||||||
const isExpiredStory = story && 'isDeleted' in story;
|
const isExpiredStory = story && 'isDeleted' in story;
|
||||||
const quickButtonLangKey = !inPreview && !isExpiredStory ? getWebpageButtonText(type) : undefined;
|
const quickButtonLangKey = !inPreview && !isExpiredStory ? getWebpageButtonLangKey(type) : undefined;
|
||||||
|
const quickButtonTitle = quickButtonLangKey && lang(quickButtonLangKey);
|
||||||
const truncatedDescription = trimText(description, MAX_TEXT_LENGTH);
|
const truncatedDescription = trimText(description, MAX_TEXT_LENGTH);
|
||||||
const isArticle = Boolean(truncatedDescription || title || siteName);
|
const isArticle = Boolean(truncatedDescription || title || siteName);
|
||||||
let isSquarePhoto = Boolean(stickers);
|
let isSquarePhoto = Boolean(stickers);
|
||||||
@ -159,31 +174,75 @@ const WebPage: FC<OwnProps> = ({
|
|||||||
video && 'with-video',
|
video && 'with-video',
|
||||||
!isArticle && 'no-article',
|
!isArticle && 'no-article',
|
||||||
document && 'with-document',
|
document && 'with-document',
|
||||||
quickButtonLangKey && 'with-quick-button',
|
quickButtonTitle && 'with-quick-button',
|
||||||
|
isGift && 'with-gift',
|
||||||
);
|
);
|
||||||
|
|
||||||
function renderQuickButton(langKey: string) {
|
function renderQuickButton(caption: string) {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
className="WebPage--quick-button"
|
className="WebPage--quick-button"
|
||||||
size="tiny"
|
size="tiny"
|
||||||
color="translucent"
|
color="translucent"
|
||||||
isRectangular
|
isRectangular
|
||||||
onClick={handleQuickButtonClick}
|
onClick={handleOpenTelegramLink}
|
||||||
>
|
>
|
||||||
{lang(langKey)}
|
{caption}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderStarGiftUnique() {
|
||||||
|
const gift = webPage?.gift;
|
||||||
|
if (!gift || gift.type !== 'starGiftUnique') return undefined;
|
||||||
|
|
||||||
|
const sticker = getStickerFromGift(gift)!;
|
||||||
|
const attributes = getGiftAttributes(gift);
|
||||||
|
const { backdrop, pattern, model } = attributes || {};
|
||||||
|
|
||||||
|
if (!backdrop || !pattern || !model) return undefined;
|
||||||
|
|
||||||
|
const backgroundColors = [backdrop.centerColor, backdrop.edgeColor];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="web-page-gift web-page-centered web-page-unique"
|
||||||
|
onClick={() => handleOpenTelegramLink()}
|
||||||
|
>
|
||||||
|
<div className="web-page-unique-background-wrapper">
|
||||||
|
<RadialPatternBackground
|
||||||
|
className="web-page-unique-background"
|
||||||
|
backgroundColors={backgroundColors}
|
||||||
|
patternColor={backdrop.patternColor}
|
||||||
|
patternIcon={pattern.sticker}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div ref={giftStickersRef} key={sticker.id} className="WebPage--unique-sticker">
|
||||||
|
<StickerView
|
||||||
|
containerRef={giftStickersRef}
|
||||||
|
sticker={sticker}
|
||||||
|
size={STAR_GIFT_STICKER_SIZE}
|
||||||
|
observeIntersectionForPlaying={observeIntersectionForPlaying}
|
||||||
|
observeIntersectionForLoading={observeIntersectionForLoading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PeerColorWrapper
|
<PeerColorWrapper
|
||||||
className={className}
|
className={className}
|
||||||
data-initial={(siteName || displayUrl)[0]}
|
data-initial={(siteName || displayUrl)[0]}
|
||||||
dir={lang.isRtl ? 'rtl' : 'auto'}
|
dir={oldLang.isRtl ? 'rtl' : 'auto'}
|
||||||
onClick={handleContainerClick}
|
onClick={handleContainerClick}
|
||||||
>
|
>
|
||||||
<div className={buildClassName('WebPage--content', isStory && 'is-story')}>
|
<div className={buildClassName(
|
||||||
|
'WebPage--content',
|
||||||
|
isStory && 'is-story',
|
||||||
|
isGift && 'is-gift',
|
||||||
|
)}
|
||||||
|
>
|
||||||
{backgroundEmojiId && (
|
{backgroundEmojiId && (
|
||||||
<EmojiIconBackground
|
<EmojiIconBackground
|
||||||
emojiDocumentId={backgroundEmojiId}
|
emojiDocumentId={backgroundEmojiId}
|
||||||
@ -193,21 +252,24 @@ const WebPage: FC<OwnProps> = ({
|
|||||||
{isStory && (
|
{isStory && (
|
||||||
<BaseStory story={story} isProtected={isProtected} isConnected={isConnected} isPreview />
|
<BaseStory story={story} isProtected={isProtected} isConnected={isConnected} isPreview />
|
||||||
)}
|
)}
|
||||||
|
{isGift && !inPreview && (
|
||||||
|
renderStarGiftUnique()
|
||||||
|
)}
|
||||||
{isArticle && (
|
{isArticle && (
|
||||||
<div
|
<div
|
||||||
className={buildClassName('WebPage-text', !inPreview && 'WebPage-text_interactive')}
|
className={buildClassName('WebPage-text', !inPreview && 'WebPage-text_interactive')}
|
||||||
onClick={!inPreview ? () => openUrl({ url, shouldSkipModal: true }) : undefined}
|
onClick={!inPreview ? () => openUrl({ url, shouldSkipModal: true }) : undefined}
|
||||||
>
|
>
|
||||||
<SafeLink className="site-name" url={url} text={siteName || displayUrl} />
|
<SafeLink className="site-name" url={url} text={siteName || displayUrl} />
|
||||||
{!inPreview && title && (
|
{(!inPreview || isGift) && title && (
|
||||||
<p className="site-title">{renderText(title)}</p>
|
<p className="site-title">{renderText(title)}</p>
|
||||||
)}
|
)}
|
||||||
{truncatedDescription && (
|
{truncatedDescription && !isGift && (
|
||||||
<p className="site-description">{renderText(truncatedDescription, ['emoji', 'br'])}</p>
|
<p className="site-description">{renderText(truncatedDescription, ['emoji', 'br'])}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{photo && !video && !document && (
|
{photo && !isGift && !video && !document && (
|
||||||
<Photo
|
<Photo
|
||||||
photo={photo}
|
photo={photo}
|
||||||
isOwn={message.isOutgoing}
|
isOwn={message.isOutgoing}
|
||||||
@ -289,13 +351,19 @@ const WebPage: FC<OwnProps> = ({
|
|||||||
{inPreview && displayUrl && !isArticle && (
|
{inPreview && displayUrl && !isArticle && (
|
||||||
<div className="WebPage-text">
|
<div className="WebPage-text">
|
||||||
<p className="site-name">{displayUrl}</p>
|
<p className="site-name">{displayUrl}</p>
|
||||||
<p className="site-description">{lang('Chat.Empty.LinkPreview')}</p>
|
<p className="site-description">{oldLang('Chat.Empty.LinkPreview')}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{quickButtonLangKey && renderQuickButton(quickButtonLangKey)}
|
{quickButtonTitle && renderQuickButton(quickButtonTitle)}
|
||||||
</PeerColorWrapper>
|
</PeerColorWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(WebPage);
|
export default memo(withGlobal<OwnProps>(
|
||||||
|
(global): StateProps => {
|
||||||
|
return {
|
||||||
|
canPlayAnimatedEmojis: selectCanPlayAnimatedEmojis(global),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
)(WebPage));
|
||||||
|
|||||||
@ -21,6 +21,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.message-content {
|
.message-content {
|
||||||
|
&.gift {
|
||||||
|
--max-width: 18rem;
|
||||||
|
}
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
max-width: var(--max-width);
|
max-width: var(--max-width);
|
||||||
|
|
||||||
|
|||||||
@ -138,6 +138,10 @@ export function buildContentClassName(
|
|||||||
if (webPage.document) {
|
if (webPage.document) {
|
||||||
classNames.push('document');
|
classNames.push('document');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (webPage.gift) {
|
||||||
|
classNames.push('gift');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invoice && !invoice.extendedMedia) {
|
if (invoice && !invoice.extendedMedia) {
|
||||||
|
|||||||
@ -1,36 +1,38 @@
|
|||||||
// https://github.com/telegramdesktop/tdesktop/blob/3da787791f6d227f69b32bf4003bc6071d05e2ac/Telegram/SourceFiles/history/view/history_view_view_button.cpp#L51
|
// https://github.com/telegramdesktop/tdesktop/blob/3da787791f6d227f69b32bf4003bc6071d05e2ac/Telegram/SourceFiles/history/view/history_view_view_button.cpp#L51
|
||||||
export function getWebpageButtonText(type?: string) {
|
export function getWebpageButtonLangKey(type?: string) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'telegram_channel_request':
|
case 'telegram_channel_request':
|
||||||
case 'telegram_megagroup_request':
|
case 'telegram_megagroup_request':
|
||||||
case 'telegram_chat_request':
|
case 'telegram_chat_request':
|
||||||
return 'lng_view_button_request_join';
|
return 'ViewButtonRequestJoin';
|
||||||
case 'telegram_message':
|
case 'telegram_message':
|
||||||
return 'lng_view_button_message';
|
return 'ViewButtonMessage';
|
||||||
case 'telegram_bot':
|
case 'telegram_bot':
|
||||||
return 'lng_view_button_bot';
|
return 'ViewButtonBot';
|
||||||
case 'telegram_voicechat':
|
case 'telegram_voicechat':
|
||||||
return 'lng_view_button_voice_chat';
|
return 'ViewButtonVoiceChat';
|
||||||
case 'telegram_livestream':
|
case 'telegram_livestream':
|
||||||
return 'lng_view_button_voice_chat_channel';
|
return 'ViewButtonVoiceChatChannel';
|
||||||
case 'telegram_megagroup':
|
case 'telegram_megagroup':
|
||||||
case 'telegram_chat':
|
case 'telegram_chat':
|
||||||
return 'lng_view_button_group';
|
return 'ViewButtonGroup';
|
||||||
case 'telegram_channel':
|
case 'telegram_channel':
|
||||||
return 'lng_view_button_channel';
|
return 'ViewButtonChannel';
|
||||||
case 'telegram_user':
|
case 'telegram_user':
|
||||||
return 'lng_view_button_user';
|
return 'ViewButtonUser';
|
||||||
case 'telegram_botapp':
|
case 'telegram_botapp':
|
||||||
return 'lng_view_button_bot_app';
|
return 'ViewButtonBotApp';
|
||||||
case 'telegram_chatlist':
|
case 'telegram_chatlist':
|
||||||
return 'ViewChatList';
|
return 'ViewChatList';
|
||||||
case 'telegram_story':
|
case 'telegram_story':
|
||||||
return 'lng_view_button_story';
|
return 'ViewButtonStory';
|
||||||
case 'telegram_channel_boost':
|
case 'telegram_channel_boost':
|
||||||
case 'telegram_group_boost':
|
case 'telegram_group_boost':
|
||||||
return 'lng_view_button_boost';
|
return 'ViewButtonBoost';
|
||||||
case 'telegram_stickerset':
|
case 'telegram_stickerset':
|
||||||
return 'lng_view_button_stickerset';
|
return 'ViewButtonStickerset';
|
||||||
|
case 'telegram_nft':
|
||||||
|
return 'ViewButtonGiftUnique';
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -312,11 +312,10 @@ const GiftInfoModal = ({
|
|||||||
const {
|
const {
|
||||||
model, backdrop, pattern, originalDetails,
|
model, backdrop, pattern, originalDetails,
|
||||||
} = giftAttributes || {};
|
} = giftAttributes || {};
|
||||||
const ownerId = gift.ownerId;
|
|
||||||
const ownerName = gift.ownerName;
|
const ownerName = gift.ownerName;
|
||||||
tableData.push([
|
tableData.push([
|
||||||
lang('GiftInfoOwner'),
|
lang('GiftInfoOwner'),
|
||||||
ownerId ? { chatId: ownerId } : ownerName || '',
|
gift.ownerId ? { chatId: gift.ownerId } : ownerName || '',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (model) {
|
if (model) {
|
||||||
|
|||||||
@ -990,3 +990,23 @@ addActionHandler('launchPrepaidStarsGiveaway', async (global, actions, payload):
|
|||||||
|
|
||||||
actions.openBoostStatistics({ chatId, tabId });
|
actions.openBoostStatistics({ chatId, tabId });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('openUniqueGiftBySlug', async (global, actions, payload): Promise<void> => {
|
||||||
|
const {
|
||||||
|
slug, tabId = getCurrentTabId(),
|
||||||
|
} = payload;
|
||||||
|
|
||||||
|
const gift = await callApi('fetchUniqueStarGift', { slug });
|
||||||
|
|
||||||
|
if (!gift) {
|
||||||
|
actions.showNotification({
|
||||||
|
message: {
|
||||||
|
key: 'GiftWasNotFound',
|
||||||
|
},
|
||||||
|
tabId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.openGiftInfoModal({ gift, tabId });
|
||||||
|
});
|
||||||
|
|||||||
@ -1468,6 +1468,9 @@ export interface ActionPayloads {
|
|||||||
storyId: number;
|
storyId: number;
|
||||||
origin?: StoryViewerOrigin;
|
origin?: StoryViewerOrigin;
|
||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
|
openUniqueGiftBySlug: {
|
||||||
|
slug: string;
|
||||||
|
} & WithTabId;
|
||||||
openPreviousStory: WithTabId | undefined;
|
openPreviousStory: WithTabId | undefined;
|
||||||
openNextStory: WithTabId | undefined;
|
openNextStory: WithTabId | undefined;
|
||||||
setStoryViewerMuted: {
|
setStoryViewerMuted: {
|
||||||
|
|||||||
@ -1713,6 +1713,7 @@ payments.getStarGifts#c4563590 hash:int = payments.StarGifts;
|
|||||||
payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts;
|
payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts;
|
||||||
payments.saveStarGift#92fd2aae flags:# unsave:flags.0?true msg_id:int = Bool;
|
payments.saveStarGift#92fd2aae flags:# unsave:flags.0?true msg_id:int = Bool;
|
||||||
payments.convertStarGift#72770c83 msg_id:int = Bool;
|
payments.convertStarGift#72770c83 msg_id:int = Bool;
|
||||||
|
payments.getUniqueStarGift#a1974d72 slug:string = payments.UniqueStarGift;
|
||||||
phone.requestCall#a6c4600c flags:# video:flags.0?true user_id:InputUser conference_call:flags.1?InputGroupCall random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
phone.requestCall#a6c4600c flags:# video:flags.0?true user_id:InputUser conference_call:flags.1?InputGroupCall random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||||
phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||||
phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
|
phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||||
|
|||||||
@ -384,5 +384,6 @@
|
|||||||
"payments.getUserStarGifts",
|
"payments.getUserStarGifts",
|
||||||
"payments.saveStarGift",
|
"payments.saveStarGift",
|
||||||
"payments.convertStarGift",
|
"payments.convertStarGift",
|
||||||
|
"payments.getUniqueStarGift",
|
||||||
"fragment.getCollectibleInfo"
|
"fragment.getCollectibleInfo"
|
||||||
]
|
]
|
||||||
|
|||||||
@ -2508,6 +2508,7 @@ payments.getStarGifts#c4563590 hash:int = payments.StarGifts;
|
|||||||
payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts;
|
payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts;
|
||||||
payments.saveStarGift#92fd2aae flags:# unsave:flags.0?true msg_id:int = Bool;
|
payments.saveStarGift#92fd2aae flags:# unsave:flags.0?true msg_id:int = Bool;
|
||||||
payments.convertStarGift#72770c83 msg_id:int = Bool;
|
payments.convertStarGift#72770c83 msg_id:int = Bool;
|
||||||
|
payments.getUniqueStarGift#a1974d72 slug:string = payments.UniqueStarGift;
|
||||||
payments.botCancelStarsSubscription#6dfa0622 flags:# restore:flags.0?true user_id:InputUser charge_id:string = Bool;
|
payments.botCancelStarsSubscription#6dfa0622 flags:# restore:flags.0?true user_id:InputUser charge_id:string = Bool;
|
||||||
payments.getConnectedStarRefBots#5869a553 flags:# peer:InputPeer offset_date:flags.2?int offset_link:flags.2?string limit:int = payments.ConnectedStarRefBots;
|
payments.getConnectedStarRefBots#5869a553 flags:# peer:InputPeer offset_date:flags.2?int offset_link:flags.2?string limit:int = payments.ConnectedStarRefBots;
|
||||||
payments.getConnectedStarRefBot#b7d998f0 peer:InputPeer bot:InputUser = payments.ConnectedStarRefBots;
|
payments.getConnectedStarRefBot#b7d998f0 peer:InputPeer bot:InputUser = payments.ConnectedStarRefBots;
|
||||||
|
|||||||
15
src/types/language.d.ts
vendored
15
src/types/language.d.ts
vendored
@ -1222,6 +1222,21 @@ export interface LangPair {
|
|||||||
'ProfileTabSimilarChannels': undefined;
|
'ProfileTabSimilarChannels': undefined;
|
||||||
'ActionUnsupportedTitle': undefined;
|
'ActionUnsupportedTitle': undefined;
|
||||||
'ActionUnsupportedDescription': undefined;
|
'ActionUnsupportedDescription': undefined;
|
||||||
|
'GiftWasNotFound': undefined;
|
||||||
|
'ViewButtonRequestJoin': undefined;
|
||||||
|
'ViewButtonMessage': undefined;
|
||||||
|
'ViewButtonBot': undefined;
|
||||||
|
'ViewButtonVoiceChat': undefined;
|
||||||
|
'ViewButtonVoiceChatChannel': undefined;
|
||||||
|
'ViewButtonGroup': undefined;
|
||||||
|
'ViewButtonChannel': undefined;
|
||||||
|
'ViewButtonUser': undefined;
|
||||||
|
'ViewButtonBotApp': undefined;
|
||||||
|
'ViewChatList': undefined;
|
||||||
|
'ViewButtonStory': undefined;
|
||||||
|
'ViewButtonBoost': undefined;
|
||||||
|
'ViewButtonStickerset': undefined;
|
||||||
|
'ViewButtonGiftUnique': undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
||||||
|
|||||||
@ -8,7 +8,8 @@ import { IS_BAD_URL_PARSER } from './windowEnvironment';
|
|||||||
|
|
||||||
export type DeepLinkMethod = 'resolve' | 'login' | 'passport' | 'settings' | 'join' | 'addstickers' | 'addemoji' |
|
export type DeepLinkMethod = 'resolve' | 'login' | 'passport' | 'settings' | 'join' | 'addstickers' | 'addemoji' |
|
||||||
'setlanguage' | 'addtheme' | 'confirmphone' | 'socks' | 'proxy' | 'privatepost' | 'bg' | 'share' | 'msg' | 'msg_url' |
|
'setlanguage' | 'addtheme' | 'confirmphone' | 'socks' | 'proxy' | 'privatepost' | 'bg' | 'share' | 'msg' | 'msg_url' |
|
||||||
'invoice' | 'addlist' | 'boost' | 'giftcode' | 'message' | 'premium_offer' | 'premium_multigift' | 'stars_topup';
|
'invoice' | 'addlist' | 'boost' | 'giftcode' | 'message' | 'premium_offer' | 'premium_multigift' | 'stars_topup'
|
||||||
|
| 'nft';
|
||||||
|
|
||||||
interface PublicMessageLink {
|
interface PublicMessageLink {
|
||||||
type: 'publicMessageLink';
|
type: 'publicMessageLink';
|
||||||
@ -96,6 +97,11 @@ interface PremiumMultigiftLink {
|
|||||||
referrer: string;
|
referrer: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GiftUniqueLink {
|
||||||
|
type: 'giftUniqueLink';
|
||||||
|
slug: string;
|
||||||
|
}
|
||||||
|
|
||||||
type DeepLink =
|
type DeepLink =
|
||||||
TelegramPassportLink |
|
TelegramPassportLink |
|
||||||
LoginCodeLink |
|
LoginCodeLink |
|
||||||
@ -108,7 +114,8 @@ type DeepLink =
|
|||||||
BusinessChatLink |
|
BusinessChatLink |
|
||||||
PremiumReferrerLink |
|
PremiumReferrerLink |
|
||||||
PremiumMultigiftLink |
|
PremiumMultigiftLink |
|
||||||
ChatBoostLink;
|
ChatBoostLink |
|
||||||
|
GiftUniqueLink;
|
||||||
|
|
||||||
type BuilderParams<T extends DeepLink> = Record<keyof Omit<T, 'type'>, string | undefined>;
|
type BuilderParams<T extends DeepLink> = Record<keyof Omit<T, 'type'>, string | undefined>;
|
||||||
type BuilderReturnType<T extends DeepLink> = T | undefined;
|
type BuilderReturnType<T extends DeepLink> = T | undefined;
|
||||||
@ -229,6 +236,8 @@ function parseTgLink(url: URL) {
|
|||||||
return buildPremiumMultigiftLink({ referrer: queryParams.ref });
|
return buildPremiumMultigiftLink({ referrer: queryParams.ref });
|
||||||
case 'chatBoostLink':
|
case 'chatBoostLink':
|
||||||
return buildChatBoostLink({ username: queryParams.domain, id: queryParams.channel });
|
return buildChatBoostLink({ username: queryParams.domain, id: queryParams.channel });
|
||||||
|
case 'giftUniqueLink':
|
||||||
|
return buildGiftUniqueLink({ slug: queryParams.slug });
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -331,6 +340,12 @@ function parseHttpLink(url: URL) {
|
|||||||
id: isPrivateChannel ? pathParams[1] : undefined,
|
id: isPrivateChannel ? pathParams[1] : undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
case 'giftUniqueLink': {
|
||||||
|
const slug = pathParams.slice(1).join('/');
|
||||||
|
return buildGiftUniqueLink({
|
||||||
|
slug,
|
||||||
|
});
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -355,6 +370,7 @@ function getHttpDeepLinkType(
|
|||||||
if (method === 'login') return 'loginCodeLink';
|
if (method === 'login') return 'loginCodeLink';
|
||||||
if (method === 'm') return 'businessChatLink';
|
if (method === 'm') return 'businessChatLink';
|
||||||
if (method === 'boost') return 'chatBoostLink';
|
if (method === 'boost') return 'chatBoostLink';
|
||||||
|
if (method === 'nft') return 'giftUniqueLink';
|
||||||
if (method === 'c') {
|
if (method === 'c') {
|
||||||
if (queryParams.boost !== undefined) return 'chatBoostLink';
|
if (queryParams.boost !== undefined) return 'chatBoostLink';
|
||||||
return 'privateChannelLink';
|
return 'privateChannelLink';
|
||||||
@ -370,6 +386,7 @@ function getHttpDeepLinkType(
|
|||||||
if (isUsernameValid(pathParams[0]) && pathParams.slice(1).every(isNumber)) {
|
if (isUsernameValid(pathParams[0]) && pathParams.slice(1).every(isNumber)) {
|
||||||
return 'publicMessageLink';
|
return 'publicMessageLink';
|
||||||
}
|
}
|
||||||
|
if (method === 'nft') return 'giftUniqueLink';
|
||||||
} else if (len === 4) {
|
} else if (len === 4) {
|
||||||
if (method === 'c' && pathParams.slice(1).every(isNumber)) {
|
if (method === 'c' && pathParams.slice(1).every(isNumber)) {
|
||||||
return 'privateMessageLink';
|
return 'privateMessageLink';
|
||||||
@ -424,6 +441,8 @@ function getTgDeepLinkType(
|
|||||||
return 'premiumMultigiftLink';
|
return 'premiumMultigiftLink';
|
||||||
case 'boost':
|
case 'boost':
|
||||||
return 'chatBoostLink';
|
return 'chatBoostLink';
|
||||||
|
case 'nft':
|
||||||
|
return 'giftUniqueLink';
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -629,6 +648,21 @@ function buildBusinessChatLink(params: BuilderParams<BusinessChatLink>): Builder
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildGiftUniqueLink(params: BuilderParams<GiftUniqueLink>): BuilderReturnType<GiftUniqueLink> {
|
||||||
|
const {
|
||||||
|
slug,
|
||||||
|
} = params;
|
||||||
|
|
||||||
|
if (!slug) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'giftUniqueLink',
|
||||||
|
slug,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildPremiumReferrerLink(params: BuilderParams<PremiumReferrerLink>): BuilderReturnType<PremiumReferrerLink> {
|
function buildPremiumReferrerLink(params: BuilderParams<PremiumReferrerLink>): BuilderReturnType<PremiumReferrerLink> {
|
||||||
const {
|
const {
|
||||||
referrer,
|
referrer,
|
||||||
|
|||||||
@ -66,6 +66,9 @@ export const processDeepLink = (url: string): boolean => {
|
|||||||
isPrivate: Boolean(parsedLink.id),
|
isPrivate: Boolean(parsedLink.id),
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
case 'giftUniqueLink':
|
||||||
|
actions.openUniqueGiftBySlug({ slug: parsedLink.slug });
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user