Gifts: Support channels (#5527)

This commit is contained in:
zubiden 2025-01-27 23:50:53 +01:00 committed by Alexander Zinchuk
parent c492bc677a
commit 10009ce9ba
45 changed files with 1075 additions and 663 deletions

View File

@ -1,29 +1,31 @@
import { Api as GramJs } from '../../../lib/gramjs'; import { Api as GramJs } from '../../../lib/gramjs';
import type { import type {
ApiInputSavedStarGift,
ApiSavedStarGift,
ApiStarGift, ApiStarGift,
ApiStarGiftAttribute, ApiStarGiftAttribute,
ApiUserStarGift,
} from '../../types'; } from '../../types';
import { numberToHexColor } from '../../../util/colors'; import { numberToHexColor } from '../../../util/colors';
import { addDocumentToLocalDb } from '../helpers'; import { addDocumentToLocalDb } from '../helpers';
import { buildApiFormattedText } from './common'; import { buildApiFormattedText } from './common';
import { buildApiPeerId } from './peers'; import { getApiChatIdFromMtpPeer } from './peers';
import { buildStickerFromDocument } from './symbols'; import { buildStickerFromDocument } from './symbols';
export function buildApiStarGift(starGift: GramJs.TypeStarGift): ApiStarGift { 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, id, num, ownerId, ownerName, title, attributes, availabilityIssued, availabilityTotal, slug, ownerAddress,
} = starGift; } = starGift;
return { return {
type: 'starGiftUnique', type: 'starGiftUnique',
id: id.toString(), id: id.toString(),
number: num, number: num,
ownerId: ownerId && buildApiPeerId(ownerId, 'user'), ownerId: ownerId && getApiChatIdFromMtpPeer(ownerId),
ownerName, ownerName,
ownerAddress,
attributes: attributes.map(buildApiStarGiftAttribute).filter(Boolean), attributes: attributes.map(buildApiStarGiftAttribute).filter(Boolean),
title, title,
totalCount: availabilityTotal, totalCount: availabilityTotal,
@ -115,25 +117,30 @@ export function buildApiStarGiftAttribute(attribute: GramJs.TypeStarGiftAttribut
return { return {
type: 'originalDetails', type: 'originalDetails',
date, date,
recipientId: recipientId && buildApiPeerId(recipientId, 'user'), recipientId: recipientId && getApiChatIdFromMtpPeer(recipientId),
message: message && buildApiFormattedText(message), message: message && buildApiFormattedText(message),
senderId: senderId && buildApiPeerId(senderId, 'user'), senderId: senderId && getApiChatIdFromMtpPeer(senderId),
}; };
} }
return undefined; return undefined;
} }
export function buildApiUserStarGift(userStarGift: GramJs.UserStarGift): ApiUserStarGift { export function buildApiSavedStarGift(userStarGift: GramJs.SavedStarGift, peerId: string): ApiSavedStarGift {
const { const {
gift, date, convertStars, fromId, message, msgId, nameHidden, unsaved, upgradeStars, transferStars, canUpgrade, gift, date, convertStars, fromId, message, msgId, nameHidden, unsaved, upgradeStars, transferStars, canUpgrade,
savedId,
} = userStarGift; } = userStarGift;
const inputGift: ApiInputSavedStarGift | undefined = savedId && peerId
? { type: 'chat', chatId: peerId, savedId: savedId.toString() }
: msgId ? { type: 'user', messageId: msgId } : undefined;
return { return {
gift: buildApiStarGift(gift), gift: buildApiStarGift(gift),
date, date,
starsToConvert: convertStars?.toJSNumber(), starsToConvert: convertStars?.toJSNumber(),
fromId: fromId && buildApiPeerId(fromId, 'user'), fromId: fromId && getApiChatIdFromMtpPeer(fromId),
message: message && buildApiFormattedText(message), message: message && buildApiFormattedText(message),
messageId: msgId, messageId: msgId,
isNameHidden: nameHidden, isNameHidden: nameHidden,
@ -141,5 +148,7 @@ export function buildApiUserStarGift(userStarGift: GramJs.UserStarGift): ApiUser
canUpgrade, canUpgrade,
alreadyPaidUpgradeStars: upgradeStars?.toJSNumber(), alreadyPaidUpgradeStars: upgradeStars?.toJSNumber(),
transferStars: transferStars?.toJSNumber(), transferStars: transferStars?.toJSNumber(),
inputGift,
savedId: savedId?.toString(),
}; };
} }

View File

@ -11,6 +11,7 @@ import type {
ApiGroupCall, ApiGroupCall,
ApiInputMessageReplyInfo, ApiInputMessageReplyInfo,
ApiInputReplyInfo, ApiInputReplyInfo,
ApiInputSavedStarGift,
ApiKeyboardButton, ApiKeyboardButton,
ApiMessage, ApiMessage,
ApiMessageActionStarGift, ApiMessageActionStarGift,
@ -193,7 +194,7 @@ export function buildApiMessageWithChatId(
: isSavedOutgoing; : isSavedOutgoing;
const content = buildMessageContent(mtpMessage); const content = buildMessageContent(mtpMessage);
const action = mtpMessage.action const action = mtpMessage.action
&& buildAction(mtpMessage.action, fromId, peerId, Boolean(mtpMessage.post), isOutgoing); && buildAction(mtpMessage.action, mtpMessage.id, fromId, peerId, Boolean(mtpMessage.post), isOutgoing);
if (action) { if (action) {
content.action = action; content.action = action;
} }
@ -369,16 +370,29 @@ export function buildApiFactCheck(factCheck: GramJs.FactCheck): ApiFactCheck {
}; };
} }
function buildApiMessageActionStarGift(action: GramJs.MessageActionStarGift) : ApiMessageActionStarGift { function buildApiMessageActionStarGift(
action: GramJs.MessageActionStarGift, messageId: number,
): ApiMessageActionStarGift {
const { const {
nameHidden, saved, converted, gift, message, convertStars, canUpgrade, upgraded, upgradeMsgId, upgradeStars, nameHidden, saved, converted, gift, message, convertStars, canUpgrade, upgraded, upgradeMsgId, upgradeStars,
peer, savedId, fromId,
} = action; } = action;
const inputSavedGift: ApiInputSavedStarGift = savedId && peer ? {
type: 'chat',
chatId: getApiChatIdFromMtpPeer(peer),
savedId: savedId.toString(),
} : {
type: 'user',
messageId,
};
return { return {
type: 'starGift', type: 'starGift',
isNameHidden: Boolean(nameHidden), isNameHidden: Boolean(nameHidden),
isSaved: Boolean(saved), isSaved: Boolean(saved),
isConverted: converted, isConverted: converted,
fromId: fromId && getApiChatIdFromMtpPeer(fromId),
gift: buildApiStarGift(gift) as ApiStarGiftRegular, gift: buildApiStarGift(gift) as ApiStarGiftRegular,
message: message && buildApiFormattedText(message), message: message && buildApiFormattedText(message),
starsToConvert: convertStars?.toJSNumber(), starsToConvert: convertStars?.toJSNumber(),
@ -386,16 +400,28 @@ function buildApiMessageActionStarGift(action: GramJs.MessageActionStarGift) : A
isUpgraded: upgraded, isUpgraded: upgraded,
upgradeMsgId, upgradeMsgId,
alreadyPaidUpgradeStars: upgradeStars?.toJSNumber(), alreadyPaidUpgradeStars: upgradeStars?.toJSNumber(),
peerId: peer && getApiChatIdFromMtpPeer(peer),
savedId: savedId?.toString(),
inputSavedGift,
}; };
} }
function buildApiMessageActionStarGiftUnique( function buildApiMessageActionStarGiftUnique(
action: GramJs.MessageActionStarGiftUnique, action: GramJs.MessageActionStarGiftUnique, messageId: number,
): ApiMessageActionStarGiftUnique { ): ApiMessageActionStarGiftUnique {
const { const {
gift, canExportAt, refunded, saved, transferStars, transferred, upgrade, gift, canExportAt, refunded, saved, transferStars, transferred, upgrade, fromId, peer, savedId,
} = action; } = action;
const inputSavedGift: ApiInputSavedStarGift = savedId && peer ? {
type: 'chat',
chatId: getApiChatIdFromMtpPeer(peer),
savedId: savedId.toString(),
} : {
type: 'user',
messageId,
};
return { return {
type: 'starGiftUnique', type: 'starGiftUnique',
gift: buildApiStarGift(gift) as ApiStarGiftUnique, gift: buildApiStarGift(gift) as ApiStarGiftUnique,
@ -405,11 +431,16 @@ function buildApiMessageActionStarGiftUnique(
transferStars: transferStars?.toJSNumber(), transferStars: transferStars?.toJSNumber(),
isTransferred: transferred, isTransferred: transferred,
isUpgrade: upgrade, isUpgrade: upgrade,
fromId: fromId && getApiChatIdFromMtpPeer(fromId),
peerId: peer && getApiChatIdFromMtpPeer(peer),
savedId: savedId?.toString(),
inputSavedGift,
}; };
} }
function buildAction( function buildAction(
action: GramJs.TypeMessageAction, action: GramJs.TypeMessageAction,
messageId: number,
senderId: string | undefined, senderId: string | undefined,
targetPeerId: string | undefined, targetPeerId: string | undefined,
isChannelPost: boolean, isChannelPost: boolean,
@ -738,7 +769,7 @@ function buildAction(
transactionId = action.transactionId; transactionId = action.transactionId;
} else if (action instanceof GramJs.MessageActionStarGift && action.gift instanceof GramJs.StarGift) { } else if (action instanceof GramJs.MessageActionStarGift && action.gift instanceof GramJs.StarGift) {
type = 'starGift'; type = 'starGift';
starGift = buildApiMessageActionStarGift(action); starGift = buildApiMessageActionStarGift(action, messageId);
if (isOutgoing) { if (isOutgoing) {
text = 'ActionGiftOutbound'; text = 'ActionGiftOutbound';
translationValues.push('%gift_payment_amount%'); translationValues.push('%gift_payment_amount%');
@ -763,9 +794,11 @@ function buildAction(
translationValues.push('%action_origin_chat%'); translationValues.push('%action_origin_chat%');
} }
starGift = buildApiMessageActionStarGiftUnique(action); starGift = buildApiMessageActionStarGiftUnique(action, messageId);
if (targetPeerId) { if (action.peer) {
targetChatId = getApiChatIdFromMtpPeer(action.peer);
} else if (targetPeerId) {
targetUserIds.push(targetPeerId); targetUserIds.push(targetPeerId);
targetChatId = targetPeerId; targetChatId = targetPeerId;
} }

View File

@ -52,10 +52,11 @@ export function buildApiPeerColor(peerColor: GramJs.TypePeerColor): ApiPeerColor
export function buildApiEmojiStatus(mtpEmojiStatus: GramJs.TypeEmojiStatus): ApiEmojiStatus | undefined { export function buildApiEmojiStatus(mtpEmojiStatus: GramJs.TypeEmojiStatus): ApiEmojiStatus | undefined {
if (mtpEmojiStatus instanceof GramJs.EmojiStatus) { if (mtpEmojiStatus instanceof GramJs.EmojiStatus) {
return { documentId: mtpEmojiStatus.documentId.toString() }; return { documentId: mtpEmojiStatus.documentId.toString(), until: mtpEmojiStatus.until };
} }
if (mtpEmojiStatus instanceof GramJs.EmojiStatusUntil) { // TODO: Support other parameters
if (mtpEmojiStatus instanceof GramJs.EmojiStatusCollectible) {
return { documentId: mtpEmojiStatus.documentId.toString(), until: mtpEmojiStatus.until }; return { documentId: mtpEmojiStatus.documentId.toString(), until: mtpEmojiStatus.until };
} }

View File

@ -23,6 +23,7 @@ import type {
ApiReactionWithPaid, ApiReactionWithPaid,
ApiReportReason, ApiReportReason,
ApiRequestInputInvoice, ApiRequestInputInvoice,
ApiRequestInputSavedStarGift,
ApiSendMessageAction, ApiSendMessageAction,
ApiSticker, ApiSticker,
ApiStory, ApiStory,
@ -643,10 +644,10 @@ export function buildInputInvoice(invoice: ApiRequestInputInvoice) {
case 'stargift': { case 'stargift': {
const { const {
user, shouldHideName, giftId, message, shouldUpgrade, peer, shouldHideName, giftId, message, shouldUpgrade,
} = invoice; } = invoice;
return new GramJs.InputInvoiceStarGift({ return new GramJs.InputInvoiceStarGift({
userId: buildInputEntity(user.id, user.accessHash) as GramJs.InputUser, peer: buildInputPeer(peer.id, peer.accessHash),
hideName: shouldHideName || undefined, hideName: shouldHideName || undefined,
giftId: BigInt(giftId), giftId: BigInt(giftId),
message: message && buildInputTextWithEntities(message), message: message && buildInputTextWithEntities(message),
@ -676,7 +677,7 @@ export function buildInputInvoice(invoice: ApiRequestInputInvoice) {
case 'stargiftUpgrade': { case 'stargiftUpgrade': {
return new GramJs.InputInvoiceStarGiftUpgrade({ return new GramJs.InputInvoiceStarGiftUpgrade({
msgId: invoice.messageId, stargift: buildInputSavedStarGift(invoice.inputSavedGift),
keepOriginalDetails: invoice.shouldKeepOriginalDetails, keepOriginalDetails: invoice.shouldKeepOriginalDetails,
}); });
} }
@ -732,15 +733,9 @@ export function buildInputEmojiStatus(emojiStatusId: string, expires?: number) {
return new GramJs.EmojiStatusEmpty(); return new GramJs.EmojiStatusEmpty();
} }
if (expires) {
return new GramJs.EmojiStatusUntil({
documentId: BigInt(emojiStatusId),
until: expires,
});
}
return new GramJs.EmojiStatus({ return new GramJs.EmojiStatus({
documentId: BigInt(emojiStatusId), documentId: BigInt(emojiStatusId),
until: expires,
}); });
} }
@ -845,3 +840,16 @@ export function buildInputPrivacyRules(
return privacyRules; return privacyRules;
} }
export function buildInputSavedStarGift(inputGift: ApiRequestInputSavedStarGift) {
if (inputGift.type === 'user') {
return new GramJs.InputSavedStarGiftUser({
msgId: inputGift.messageId,
});
}
return new GramJs.InputSavedStarGiftChat({
peer: buildInputPeer(inputGift.chat.id, inputGift.chat.accessHash),
savedId: BigInt(inputGift.savedId),
});
}

View File

@ -608,6 +608,8 @@ async function getFullChannelInfo(
canViewRevenue: canViewMonetization, canViewRevenue: canViewMonetization,
paidReactionsAvailable, paidReactionsAvailable,
hasScheduled, hasScheduled,
stargiftsCount,
stargiftsAvailable,
} = result.fullChat; } = result.fullChat;
if (chatPhoto) { if (chatPhoto) {
@ -700,6 +702,8 @@ async function getFullChannelInfo(
botVerification: botVerification && buildApiBotVerification(botVerification), botVerification: botVerification && buildApiBotVerification(botVerification),
isPaidReactionAvailable: paidReactionsAvailable, isPaidReactionAvailable: paidReactionsAvailable,
hasScheduledMessages: hasScheduled, hasScheduledMessages: hasScheduled,
starGiftCount: stargiftsCount,
areStarGiftsAvailable: Boolean(stargiftsAvailable),
}, },
chats, chats,
userStatusesById: statusesById, userStatusesById: statusesById,

View File

@ -6,16 +6,16 @@ import type {
ApiInputStorePaymentPurpose, ApiInputStorePaymentPurpose,
ApiPeer, ApiPeer,
ApiRequestInputInvoice, ApiRequestInputInvoice,
ApiRequestInputSavedStarGift,
ApiStarGiftRegular, ApiStarGiftRegular,
ApiThemeParameters, ApiThemeParameters,
ApiUser,
} from '../../types'; } from '../../types';
import { DEBUG } from '../../../config'; import { DEBUG } from '../../../config';
import { import {
buildApiSavedStarGift,
buildApiStarGift, buildApiStarGift,
buildApiStarGiftAttribute, buildApiStarGiftAttribute,
buildApiUserStarGift,
} from '../apiBuilders/gifts'; } from '../apiBuilders/gifts';
import { import {
buildApiBoost, buildApiBoost,
@ -37,7 +37,12 @@ import {
} from '../apiBuilders/payments'; } from '../apiBuilders/payments';
import { buildApiPeerId } from '../apiBuilders/peers'; import { buildApiPeerId } from '../apiBuilders/peers';
import { import {
buildInputInvoice, buildInputPeer, buildInputStorePaymentPurpose, buildInputThemeParams, buildShippingInfo, buildInputInvoice,
buildInputPeer,
buildInputSavedStarGift,
buildInputStorePaymentPurpose,
buildInputThemeParams,
buildShippingInfo,
} from '../gramjsBuilders'; } from '../gramjsBuilders';
import { import {
deserializeBytes, deserializeBytes,
@ -440,17 +445,17 @@ export async function fetchStarGifts() {
return result.gifts.map(buildApiStarGift).filter((gift): gift is ApiStarGiftRegular => gift.type === 'starGift'); return result.gifts.map(buildApiStarGift).filter((gift): gift is ApiStarGiftRegular => gift.type === 'starGift');
} }
export async function fetchUserStarGifts({ export async function fetchSavedStarGifts({
user, peer,
offset = '', offset = '',
limit, limit,
}: { }: {
user: ApiUser; peer: ApiPeer;
offset?: string; offset?: string;
limit?: number; limit?: number;
}) { }) {
const result = await invokeRequest(new GramJs.payments.GetUserStarGifts({ const result = await invokeRequest(new GramJs.payments.GetSavedStarGifts({
userId: buildInputPeer(user.id, user.accessHash), peer: buildInputPeer(peer.id, peer.accessHash),
offset, offset,
limit, limit,
})); }));
@ -459,7 +464,7 @@ export async function fetchUserStarGifts({
return undefined; return undefined;
} }
const gifts = result.gifts.map(buildApiUserStarGift); const gifts = result.gifts.map((g) => buildApiSavedStarGift(g, peer.id));
return { return {
gifts, gifts,
@ -468,25 +473,25 @@ export async function fetchUserStarGifts({
} }
export function saveStarGift({ export function saveStarGift({
messageId, inputGift,
shouldUnsave, shouldUnsave,
}: { }: {
messageId: number; inputGift: ApiRequestInputSavedStarGift;
shouldUnsave?: boolean; shouldUnsave?: boolean;
}) { }) {
return invokeRequest(new GramJs.payments.SaveStarGift({ return invokeRequest(new GramJs.payments.SaveStarGift({
msgId: messageId, stargift: buildInputSavedStarGift(inputGift),
unsave: shouldUnsave || undefined, unsave: shouldUnsave || undefined,
})); }));
} }
export function convertStarGift({ export function convertStarGift({
messageId, inputSavedGift,
}: { }: {
messageId: number; inputSavedGift: ApiRequestInputSavedStarGift;
}) { }) {
return invokeRequest(new GramJs.payments.ConvertStarGift({ return invokeRequest(new GramJs.payments.ConvertStarGift({
msgId: messageId, stargift: buildInputSavedStarGift(inputSavedGift),
})); }));
} }
@ -671,14 +676,14 @@ export async function fetchStarGiftUpgradePreview({
} }
export function upgradeGift({ export function upgradeGift({
messageId, inputSavedGift,
shouldKeepOriginalDetails, shouldKeepOriginalDetails,
}: { }: {
messageId: number; inputSavedGift: ApiRequestInputSavedStarGift;
shouldKeepOriginalDetails?: true; shouldKeepOriginalDetails?: true;
}) { }) {
return invokeRequest(new GramJs.payments.UpgradeStarGift({ return invokeRequest(new GramJs.payments.UpgradeStarGift({
msgId: messageId, stargift: buildInputSavedStarGift(inputSavedGift),
keepOriginalDetails: shouldKeepOriginalDetails, keepOriginalDetails: shouldKeepOriginalDetails,
}), { }), {
shouldReturnTrue: true, shouldReturnTrue: true,

View File

@ -141,6 +141,8 @@ export interface ApiChatFullInfo {
hasPinnedStories?: boolean; hasPinnedStories?: boolean;
isPaidReactionAvailable?: boolean; isPaidReactionAvailable?: boolean;
hasScheduledMessages?: boolean; hasScheduledMessages?: boolean;
starGiftCount?: number;
areStarGiftsAvailable?: boolean;
boostsApplied?: number; boostsApplied?: number;
boostsToUnrestrict?: number; boostsToUnrestrict?: number;

View File

@ -1,18 +1,16 @@
import type { ThreadId, WebPageMediaSize } from '../../types'; import type { ThreadId, WebPageMediaSize } from '../../types';
import type { ApiWebDocument } from './bots'; import type { ApiWebDocument } from './bots';
import type { ApiGroupCall, PhoneCallAction } from './calls'; import type { ApiGroupCall, PhoneCallAction } from './calls';
import type { ApiChat, ApiPeerColor } from './chats'; import type { ApiPeerColor } from './chats';
import type { import type {
ApiInputStorePaymentPurpose, ApiInputSavedStarGift,
ApiLabeledPrice, ApiLabeledPrice,
ApiPremiumGiftCodeOption,
ApiStarGiftRegular, ApiStarGiftRegular,
ApiStarGiftUnique, ApiStarGiftUnique,
} from './payments'; } from './payments';
import type { import type {
ApiMessageStoryData, ApiStory, ApiWebPageStickerData, ApiWebPageStoryData, ApiMessageStoryData, ApiStory, ApiWebPageStickerData, ApiWebPageStoryData,
} from './stories'; } from './stories';
import type { ApiUser } from './users';
export interface ApiDimensions { export interface ApiDimensions {
width: number; width: number;
@ -207,149 +205,6 @@ export interface ApiPoll {
}; };
} }
/* Used for Invoice UI */
export type ApiInputInvoiceMessage = {
type: 'message';
chatId: string;
messageId: number;
isExtendedMedia?: boolean;
};
export type ApiInputInvoiceSlug = {
type: 'slug';
slug: string;
};
export type ApiInputInvoiceGiveaway = {
type: 'giveaway';
chatId: string;
additionalChannelIds?: string[];
isOnlyForNewSubscribers?: boolean;
areWinnersVisible?: boolean;
prizeDescription?: string;
countries?: string[];
untilDate: number;
currency: string;
amount: number;
option: ApiPremiumGiftCodeOption;
};
export type ApiInputInvoiceGiftCode = {
type: 'giftcode';
userIds: string[];
boostChannelId?: string;
currency: string;
amount: number;
option: ApiPremiumGiftCodeOption;
message?: ApiFormattedText;
};
export type ApiInputInvoiceStars = {
type: 'stars';
stars: number;
currency: string;
amount: number;
};
export type ApiInputInvoiceStarsGift = {
type: 'starsgift';
userId: string;
stars: number;
currency: string;
amount: number;
};
export type ApiInputInvoiceStarGift = {
type: 'stargift';
shouldHideName?: boolean;
userId: string;
giftId: string;
message?: ApiFormattedText;
shouldUpgrade?: true;
};
export type ApiInputInvoiceStarsGiveaway = {
type: 'starsgiveaway';
chatId: string;
additionalChannelIds?: string[];
isOnlyForNewSubscribers?: boolean;
areWinnersVisible?: boolean;
prizeDescription?: string;
countries?: string[];
untilDate: number;
currency: string;
amount: number;
stars: number;
users: number;
};
export type ApiInputInvoiceChatInviteSubscription = {
type: 'chatInviteSubscription';
hash: string;
};
export type ApiInputInvoiceStarGiftUpgrade = {
type: 'stargiftUpgrade';
messageId: number;
shouldKeepOriginalDetails?: true;
};
export type ApiInputInvoice = ApiInputInvoiceMessage | ApiInputInvoiceSlug | ApiInputInvoiceGiveaway
| ApiInputInvoiceGiftCode | ApiInputInvoiceStars | ApiInputInvoiceStarsGift | ApiInputInvoiceStarGiftUpgrade
| ApiInputInvoiceStarsGiveaway | ApiInputInvoiceStarGift | ApiInputInvoiceChatInviteSubscription;
/* Used for Invoice request */
export type ApiRequestInputInvoiceMessage = {
type: 'message';
chat: ApiChat;
messageId: number;
};
export type ApiRequestInputInvoiceSlug = {
type: 'slug';
slug: string;
};
export type ApiRequestInputInvoiceGiveaway = {
type: 'giveaway';
purpose: ApiInputStorePaymentPurpose;
option: ApiPremiumGiftCodeOption;
};
export type ApiRequestInputInvoiceStars = {
type: 'stars';
purpose: ApiInputStorePaymentPurpose;
};
export type ApiRequestInputInvoiceStarsGiveaway = {
type: 'starsgiveaway';
purpose: ApiInputStorePaymentPurpose;
};
export type ApiRequestInputInvoiceStarGift = {
type: 'stargift';
shouldHideName?: boolean;
user: ApiUser;
giftId: string;
message?: ApiFormattedText;
shouldUpgrade?: true;
};
export type ApiRequestInputInvoiceChatInviteSubscription = {
type: 'chatInviteSubscription';
hash: string;
};
export type ApiRequestInputInvoiceStarGiftUpgrade = {
type: 'stargiftUpgrade';
messageId: number;
shouldKeepOriginalDetails?: true;
};
export type ApiRequestInputInvoice = ApiRequestInputInvoiceMessage | ApiRequestInputInvoiceSlug
| ApiRequestInputInvoiceGiveaway | ApiRequestInputInvoiceStars | ApiRequestInputInvoiceStarsGiveaway
| ApiRequestInputInvoiceChatInviteSubscription | ApiRequestInputInvoiceStarGift | ApiRequestInputInvoiceStarGiftUpgrade;
export interface ApiInvoice { export interface ApiInvoice {
prices: ApiLabeledPrice[]; prices: ApiLabeledPrice[];
totalAmount: number; totalAmount: number;
@ -485,6 +340,10 @@ export interface ApiMessageActionStarGift {
isUpgraded?: true; isUpgraded?: true;
upgradeMsgId?: number; upgradeMsgId?: number;
alreadyPaidUpgradeStars?: number; alreadyPaidUpgradeStars?: number;
fromId?: string;
peerId?: string;
savedId?: string;
inputSavedGift?: ApiInputSavedStarGift;
} }
export interface ApiMessageActionStarGiftUnique { export interface ApiMessageActionStarGiftUnique {
@ -496,6 +355,10 @@ export interface ApiMessageActionStarGiftUnique {
gift: ApiStarGiftUnique; gift: ApiStarGiftUnique;
canExportAt?: number; canExportAt?: number;
transferStars?: number; transferStars?: number;
fromId?: string;
peerId?: string;
savedId?: string;
inputSavedGift?: ApiInputSavedStarGift;
} }
export interface ApiAction { export interface ApiAction {

View File

@ -1,6 +1,6 @@
import type { PREMIUM_FEATURE_SECTIONS } from '../../config'; import type { PREMIUM_FEATURE_SECTIONS } from '../../config';
import type { ApiWebDocument } from './bots'; import type { ApiWebDocument } from './bots';
import type { ApiChat } from './chats'; import type { ApiChat, ApiPeer } from './chats';
import type { import type {
ApiDocument, ApiDocument,
ApiFormattedText, ApiFormattedText,
@ -213,6 +213,7 @@ export interface ApiStarGiftUnique {
number: number; number: number;
ownerId?: string; ownerId?: string;
ownerName?: string; ownerName?: string;
ownerAddress?: string;
issuedCount: number; issuedCount: number;
totalCount: number; totalCount: number;
attributes: ApiStarGiftAttribute[]; attributes: ApiStarGiftAttribute[];
@ -256,12 +257,14 @@ export interface ApiStarGiftAttributeOriginalDetails {
export type ApiStarGiftAttribute = ApiStarGiftAttributeModel | ApiStarGiftAttributePattern export type ApiStarGiftAttribute = ApiStarGiftAttributeModel | ApiStarGiftAttributePattern
| ApiStarGiftAttributeBackdrop | ApiStarGiftAttributeOriginalDetails; | ApiStarGiftAttributeBackdrop | ApiStarGiftAttributeOriginalDetails;
export interface ApiUserStarGift { export interface ApiSavedStarGift {
isNameHidden?: boolean; isNameHidden?: boolean;
isUnsaved?: boolean; isUnsaved?: boolean;
fromId?: string; fromId?: string;
date: number; date: number;
gift: ApiStarGift; gift: ApiStarGift;
inputGift?: ApiInputSavedStarGift;
savedId?: string;
message?: ApiFormattedText; message?: ApiFormattedText;
messageId?: number; messageId?: number;
starsToConvert?: number; starsToConvert?: number;
@ -272,6 +275,27 @@ export interface ApiUserStarGift {
upgradeMsgId?: number; // Local field, used for Action Message upgradeMsgId?: number; // Local field, used for Action Message
} }
export interface ApiInputSavedStarGiftUser {
type: 'user';
messageId: number;
}
export interface ApiInputSavedStarGiftChat {
type: 'chat';
chatId: string;
savedId: string;
}
export type ApiInputSavedStarGift = ApiInputSavedStarGiftUser | ApiInputSavedStarGiftChat;
export type ApiRequestInputSavedStarGiftUser = ApiInputSavedStarGiftUser;
export type ApiRequestInputSavedStarGiftChat = {
type: 'chat';
chat: ApiChat;
savedId: string;
};
export type ApiRequestInputSavedStarGift = ApiRequestInputSavedStarGiftUser | ApiRequestInputSavedStarGiftChat;
export interface ApiPremiumGiftCodeOption { export interface ApiPremiumGiftCodeOption {
users: number; users: number;
months: number; months: number;
@ -476,3 +500,146 @@ export interface ApiStarGiveawayOption {
} }
export type ApiPaymentStatus = 'paid' | 'failed' | 'pending' | 'cancelled'; export type ApiPaymentStatus = 'paid' | 'failed' | 'pending' | 'cancelled';
/* Used for Invoice UI */
export type ApiInputInvoiceMessage = {
type: 'message';
chatId: string;
messageId: number;
isExtendedMedia?: boolean;
};
export type ApiInputInvoiceSlug = {
type: 'slug';
slug: string;
};
export type ApiInputInvoiceGiveaway = {
type: 'giveaway';
chatId: string;
additionalChannelIds?: string[];
isOnlyForNewSubscribers?: boolean;
areWinnersVisible?: boolean;
prizeDescription?: string;
countries?: string[];
untilDate: number;
currency: string;
amount: number;
option: ApiPremiumGiftCodeOption;
};
export type ApiInputInvoiceGiftCode = {
type: 'giftcode';
userIds: string[];
boostChannelId?: string;
currency: string;
amount: number;
option: ApiPremiumGiftCodeOption;
message?: ApiFormattedText;
};
export type ApiInputInvoiceStars = {
type: 'stars';
stars: number;
currency: string;
amount: number;
};
export type ApiInputInvoiceStarsGift = {
type: 'starsgift';
userId: string;
stars: number;
currency: string;
amount: number;
};
export type ApiInputInvoiceStarGift = {
type: 'stargift';
shouldHideName?: boolean;
peerId: string;
giftId: string;
message?: ApiFormattedText;
shouldUpgrade?: true;
};
export type ApiInputInvoiceStarsGiveaway = {
type: 'starsgiveaway';
chatId: string;
additionalChannelIds?: string[];
isOnlyForNewSubscribers?: boolean;
areWinnersVisible?: boolean;
prizeDescription?: string;
countries?: string[];
untilDate: number;
currency: string;
amount: number;
stars: number;
users: number;
};
export type ApiInputInvoiceChatInviteSubscription = {
type: 'chatInviteSubscription';
hash: string;
};
export type ApiInputInvoiceStarGiftUpgrade = {
type: 'stargiftUpgrade';
inputSavedGift: ApiInputSavedStarGift;
shouldKeepOriginalDetails?: true;
};
export type ApiInputInvoice = ApiInputInvoiceMessage | ApiInputInvoiceSlug | ApiInputInvoiceGiveaway
| ApiInputInvoiceGiftCode | ApiInputInvoiceStars | ApiInputInvoiceStarsGift | ApiInputInvoiceStarGiftUpgrade
| ApiInputInvoiceStarsGiveaway | ApiInputInvoiceStarGift | ApiInputInvoiceChatInviteSubscription;
/* Used for Invoice request */
export type ApiRequestInputInvoiceMessage = {
type: 'message';
chat: ApiChat;
messageId: number;
};
export type ApiRequestInputInvoiceSlug = {
type: 'slug';
slug: string;
};
export type ApiRequestInputInvoiceGiveaway = {
type: 'giveaway';
purpose: ApiInputStorePaymentPurpose;
option: ApiPremiumGiftCodeOption;
};
export type ApiRequestInputInvoiceStars = {
type: 'stars';
purpose: ApiInputStorePaymentPurpose;
};
export type ApiRequestInputInvoiceStarsGiveaway = {
type: 'starsgiveaway';
purpose: ApiInputStorePaymentPurpose;
};
export type ApiRequestInputInvoiceStarGift = {
type: 'stargift';
shouldHideName?: boolean;
peer: ApiPeer;
giftId: string;
message?: ApiFormattedText;
shouldUpgrade?: true;
};
export type ApiRequestInputInvoiceChatInviteSubscription = {
type: 'chatInviteSubscription';
hash: string;
};
export type ApiRequestInputInvoiceStarGiftUpgrade = {
type: 'stargiftUpgrade';
inputSavedGift: ApiRequestInputSavedStarGift;
shouldKeepOriginalDetails?: true;
};
export type ApiRequestInputInvoice = ApiRequestInputInvoiceMessage | ApiRequestInputInvoiceSlug
| ApiRequestInputInvoiceGiveaway | ApiRequestInputInvoiceStars | ApiRequestInputInvoiceStarsGiveaway
| ApiRequestInputInvoiceChatInviteSubscription | ApiRequestInputInvoiceStarGift | ApiRequestInputInvoiceStarGiftUpgrade;

View File

@ -4,7 +4,7 @@ import type { ApiBusinessIntro, ApiBusinessLocation, ApiBusinessWorkHours } from
import type { ApiPeerColor } from './chats'; import type { ApiPeerColor } from './chats';
import type { ApiDocument, ApiPhoto } from './messages'; import type { ApiDocument, ApiPhoto } from './messages';
import type { ApiBotVerification } from './misc'; import type { ApiBotVerification } from './misc';
import type { ApiUserStarGift } from './payments'; import type { ApiSavedStarGift } from './payments';
export interface ApiUser { export interface ApiUser {
id: string; id: string;
@ -89,8 +89,8 @@ export interface ApiUserCommonChats {
isFullyLoaded: boolean; isFullyLoaded: boolean;
} }
export interface ApiUserGifts { export interface ApiSavedGifts {
gifts: ApiUserStarGift[]; gifts: ApiSavedStarGift[];
nextOffset?: string; nextOffset?: string;
} }

View File

@ -244,6 +244,7 @@
"SavedMessagesInfo" = "Forward here to save"; "SavedMessagesInfo" = "Forward here to save";
"BlockedListNotFound" = "No users found."; "BlockedListNotFound" = "No users found.";
"TextCopied" = "Text copied to clipboard."; "TextCopied" = "Text copied to clipboard.";
"WalletAddressCopied" = "Wallet address copied to clipboard.";
"Copy" = "Copy"; "Copy" = "Copy";
"ChatListDeleteAndLeaveGroupConfirmation" = "Are you sure you want to leave and delete {chat}?"; "ChatListDeleteAndLeaveGroupConfirmation" = "Are you sure you want to leave and delete {chat}?";
"ChannelLeaveAlertWithName" = "Are you sure you want to leave **{chat}**?"; "ChannelLeaveAlertWithName" = "Are you sure you want to leave **{chat}**?";
@ -1361,6 +1362,7 @@
"StarsGiftHeaderSelf" = "Buy a Gift"; "StarsGiftHeaderSelf" = "Buy a Gift";
"StarGiftDescription" = "Give {user} gifts that can be kept on the profile or converted to Stars."; "StarGiftDescription" = "Give {user} gifts that can be kept on the profile or converted to Stars.";
"StarGiftDescriptionSelf" = "Buy yourself a gift to add to your profile or reserve for later.\n\nLimited-edition gifts upgraded to collectibles can be gifted to others."; "StarGiftDescriptionSelf" = "Buy yourself a gift to add to your profile or reserve for later.\n\nLimited-edition gifts upgraded to collectibles can be gifted to others.";
"StarGiftDescriptionChannel" = "Select gift to show appreciation to **{peer}**.";
"GiftLimited" = "limited"; "GiftLimited" = "limited";
"GiftDiscount" = "-{percent}%"; "GiftDiscount" = "-{percent}%";
"GiftSoldCount" = "{count} sold"; "GiftSoldCount" = "{count} sold";
@ -1368,23 +1370,24 @@
"GiftSoldOut" = "sold out"; "GiftSoldOut" = "sold out";
"GiftMessagePlaceholder" = "Enter Message (Optional)"; "GiftMessagePlaceholder" = "Enter Message (Optional)";
"GiftHideMyName" = "Hide My Name"; "GiftHideMyName" = "Hide My Name";
"GiftHideNameDescription" = "Hide my name and message from visitors to {profile}'s profile. {receiver} will still see your name and message."; "GiftHideNameDescription" = "You can hide your name and message from visitors to {receiver}'s profile. {receiver} will still see your name and message.";
"GiftHideNameDescriptionChannel" = "You can hide your name and message from all visitors of this channel except its admins.";
"GiftSend" = "Send a Gift for {amount}"; "GiftSend" = "Send a Gift for {amount}";
"GiftInfoSent" = "Sent Gift"; "GiftInfoSent" = "Sent Gift";
"GiftInfoReceived" = "Received Gift"; "GiftInfoReceived" = "Received Gift";
"GiftInfoTitle" = "Gift"; "GiftInfoTitle" = "Gift";
"GiftInfoDescription_one" = "You can keep this gift in your Profile or convert it to **{amount}** Star."; "GiftInfoDescription_one" = "You can keep this gift in your Profile or convert it to **{amount}** Star.";
"GiftInfoDescription_other" = "You can keep this gift in your Profile or convert it to **{amount}** Stars."; "GiftInfoDescription_other" = "You can keep this gift in your Profile or convert it to **{amount}** Stars.";
"GiftInfoDescriptionOut_one" = "{user} can keep this gift in profile or convert it to **{amount}** Star."; "GiftInfoPeerDescriptionOut_one" = "{peer} can keep this gift in profile or convert it to **{amount}** Star.";
"GiftInfoDescriptionOut_other" = "{user} can keep this gift in profile or convert it to **{amount}** Stars."; "GiftInfoPeerDescriptionOut_other" = "{peer} can keep this gift in profile or convert it to **{amount}** Stars.";
"GiftInfoDescriptionUpgrade_one" = "You can keep this gift, upgrade it, or sell it for **{amount}** Star."; "GiftInfoDescriptionUpgrade_one" = "You can keep this gift, upgrade it, or sell it for **{amount}** Star.";
"GiftInfoDescriptionUpgrade_other" = "You can keep this gift, upgrade it, or sell it for **{amount}** Stars."; "GiftInfoDescriptionUpgrade_other" = "You can keep this gift, upgrade it, or sell it for **{amount}** Stars.";
"GiftInfoDescriptionConverted_one" = "You converted this gift to **{amount}** Star."; "GiftInfoDescriptionConverted_one" = "You converted this gift to **{amount}** Star.";
"GiftInfoDescriptionConverted_other" = "You converted this gift to **{amount}** Stars."; "GiftInfoDescriptionConverted_other" = "You converted this gift to **{amount}** Stars.";
"GiftInfoDescriptionOutConverted_one" = "{user} converted this gift to **{amount}** Star."; "GiftInfoPeerDescriptionOutConverted_one" = "{peer} converted this gift to **{amount}** Star.";
"GiftInfoDescriptionOutConverted_other" = "{user} converted this gift to **{amount}** Stars."; "GiftInfoPeerDescriptionOutConverted_other" = "{peer} converted this gift to **{amount}** Stars.";
"GiftInfoDescriptionFreeUpgrade" = "Upgrade this gift for free to turn it to a unique collectible."; "GiftInfoDescriptionFreeUpgrade" = "Upgrade this gift for free to turn it to a unique collectible.";
"GiftInfoDescriptionFreeUpgradeOut" = "{user} can turn this gift to a unique collectible"; "GiftInfoPeerDescriptionFreeUpgradeOut" = "{peer} can turn this gift to a unique collectible";
"GiftInfoDescriptionUpgraded" = "This gift was turned into a unique collectible."; "GiftInfoDescriptionUpgraded" = "This gift was turned into a unique collectible.";
"GiftInfoFrom" = "From"; "GiftInfoFrom" = "From";
"GiftInfoDate" = "Date"; "GiftInfoDate" = "Date";
@ -1392,14 +1395,16 @@
"GiftInfoConvert_one" = "Convert to {amount} Star"; "GiftInfoConvert_one" = "Convert to {amount} Star";
"GiftInfoConvert_other" = "Convert to {amount} Stars"; "GiftInfoConvert_other" = "Convert to {amount} Stars";
"GiftInfoConvertTitle" = "Convert Gift to Stars"; "GiftInfoConvertTitle" = "Convert Gift to Stars";
"GiftInfoConvertDescription1" = "Do you want to convert this gift from **{user}** to **{amount}**?"; "GiftInfoPeerConvertDescription" = "Do you want to convert this gift from **{peer}** to **{amount}**?";
"GiftInfoConvertDescription2" = "This action cannot be undone. This will permanently destroy the gift."; "GiftInfoConvertDescription2" = "This action cannot be undone. This will permanently destroy the gift.";
"GiftInfoConvertDescriptionPeriod_one" = "Conversion is available for the next **{count} days**."; "GiftInfoConvertDescriptionPeriod_one" = "Conversion is available for the next **{count} days**.";
"GiftInfoConvertDescriptionPeriod_other" = "Conversion is available for the next **{count} days**."; "GiftInfoConvertDescriptionPeriod_other" = "Conversion is available for the next **{count} days**.";
"GiftInfoSaved" = "This gift is visible on your profile. {link}"; "GiftInfoSaved" = "This gift is visible on your profile. {link}";
"GiftInfoHidden" = "This gift is hidden. Only you can see it. {link}";
"GiftInfoChannelSaved" = "This gift is visible in your channel's Gifts. {link}";
"GiftInfoChannelHidden" = "This gift is hidden from visitors of your channel. {link}";
"GiftInfoSavedHide" = "Hide >"; "GiftInfoSavedHide" = "Hide >";
"GiftInfoSavedShow" = "Show >"; "GiftInfoSavedShow" = "Show >";
"GiftInfoHidden" = "This gift is hidden. Only you can see it. {link}";
"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";
@ -1415,10 +1420,10 @@
"GiftAttributeModel" = "Model"; "GiftAttributeModel" = "Model";
"GiftAttributeBackdrop" = "Backdrop"; "GiftAttributeBackdrop" = "Backdrop";
"GiftAttributeSymbol" = "Symbol"; "GiftAttributeSymbol" = "Symbol";
"GiftInfoOriginalInfo" = "Gifted to {user} on {date}."; "GiftInfoPeerOriginalInfo" = "Gifted to {peer} on {date}.";
"GiftInfoOriginalInfoSender" = "Gifted by {sender} to {user} on {date}."; "GiftInfoPeerOriginalInfoSender" = "Gifted by {sender} to {peer} on {date}.";
"GiftInfoOriginalInfoText" = "Gifted to {user} on {date} with comment \"{text}\"."; "GiftInfoPeerOriginalInfoText" = "Gifted to {peer} on {date} with comment \"{text}\".";
"GiftInfoOriginalInfoTextSender" = "Gifted by {sender} to {user} on {date} with comment \"{text}\"."; "GiftInfoPeerOriginalInfoTextSender" = "Gifted by {sender} to {peer} on {date} with comment \"{text}\".";
"GiftInfoStatus" = "Status"; "GiftInfoStatus" = "Status";
"GiftInfoStatusNonUnique" = "Non-Unique"; "GiftInfoStatusNonUnique" = "Non-Unique";
"GiftInfoViewUpgraded" = "View Upgraded Gift"; "GiftInfoViewUpgraded" = "View Upgraded Gift";
@ -1431,7 +1436,7 @@
"GiftUpgradeTradeableTitle" = "Tradable"; "GiftUpgradeTradeableTitle" = "Tradable";
"GiftUpgradeTradeableDescription" = "Sell or auction your gift on third-party NFT marketplaces."; "GiftUpgradeTradeableDescription" = "Sell or auction your gift on third-party NFT marketplaces.";
"GiftUpgradeTitle" = "Make unique"; "GiftUpgradeTitle" = "Make unique";
"GiftUpgradeText" = "Let {peer} turn your gift into a unique collectible."; "GiftPeerUpgradeText" = "Let {peer} turn your gift into a unique collectible.";
"GiftUpgradeTextOwn" = "Turn your gift into a unique collectible that you can transfer or auction."; "GiftUpgradeTextOwn" = "Turn your gift into a unique collectible that you can transfer or auction.";
"GiftUpgradeKeepDetails" = "Keep sender's name and comment"; "GiftUpgradeKeepDetails" = "Keep sender's name and comment";
"GiftUpgradeButton" = "Upgrade {amount}"; "GiftUpgradeButton" = "Upgrade {amount}";
@ -1440,6 +1445,7 @@
"GiftMakeUnique" = "Make unique for {stars}"; "GiftMakeUnique" = "Make unique for {stars}";
"GiftMakeUniqueAcc" = "Make unique"; "GiftMakeUniqueAcc" = "Make unique";
"GiftMakeUniqueDescription" = "Enable this to let {user} turn your gift into a unique collectible. {link}"; "GiftMakeUniqueDescription" = "Enable this to let {user} turn your gift into a unique collectible. {link}";
"GiftMakeUniqueDescriptionChannel" = "Enable this to let admins of {peer} to turn your gift into a unique collectible. {link}";
"GiftMakeUniqueLink" = "Learn More >"; "GiftMakeUniqueLink" = "Learn More >";
"StarsAmount" = "⭐️{amount}"; "StarsAmount" = "⭐️{amount}";
"StarsAmountText_one" = "{amount} Star"; "StarsAmountText_one" = "{amount} Star";
@ -1457,14 +1463,15 @@
"MiniAppsMoreTabs_other" = "{botName} & {count} Others"; "MiniAppsMoreTabs_other" = "{botName} & {count} Others";
"PrizeCredits2_one" = "Your prize is {count} Star."; "PrizeCredits2_one" = "Your prize is {count} Star.";
"PrizeCredits2_other" = "Your prize is {count} Stars."; "PrizeCredits2_other" = "Your prize is {count} Stars.";
"ActionStarGiftTitle" = "{user} sent you a Gift for {count} Stars"; "ActionStarGiftPeerTitle" = "{peer} sent you a Gift for {count} Stars";
"ActionStarGiftOutTitle" = "You have sent a gift for {count} Stars"; "ActionStarGiftOutTitle" = "You have sent a gift for {count} Stars";
"ActionStarGiftOutDescription2_one" = "{user} can display this gift on their profile or convert it to {count} Star."; "ActionStarGiftPeerOutDescription_one" = "{peer} can display this gift on their profile or convert it to {count} Star.";
"ActionStarGiftOutDescription2_other" = "{user} can display this gift on their profile or convert it to {count} Stars."; "ActionStarGiftPeerOutDescription_other" = "{peer} can display this gift on their profile or convert it to {count} Stars.";
"ActionStarGiftDescription2_one" = "Add this gift to your profile or convert it to {count} Star."; "ActionStarGiftDescription2_one" = "Add this gift to your profile or convert it to {count} Star.";
"ActionStarGiftDescription2_other" = "Add this gift to your profile or convert it to {count} Stars."; "ActionStarGiftDescription2_other" = "Add this gift to your profile or convert it to {count} Stars.";
"ActionStarGiftDisplaying" = "You kept this gift on your profile."; "ActionStarGiftDisplaying" = "You kept this gift on your profile.";
"ActionStarGiftOutDescriptionUpgrade" = "{user} can turn this gift to a unique collectible."; "ActionStarGiftChannelDisplaying" = "This gift is displayed to visitors of your channel.";
"ActionStarGiftPeerOutDescriptionUpgrade" = "{peer} can turn this gift to a unique collectible.";
"ActionStarGiftDescriptionUpgrade" = "Tap “Unpack” to turn this gift to a unique collectible."; "ActionStarGiftDescriptionUpgrade" = "Tap “Unpack” to turn this gift to a unique collectible.";
"ActionStarGiftUpgraded" = "This gift was upgraded."; "ActionStarGiftUpgraded" = "This gift was upgraded.";
"ActionStarGiftUnpack" = "Unpack"; "ActionStarGiftUnpack" = "Unpack";

View File

@ -1,9 +1,9 @@
import React, { memo, useMemo, useRef } from '../../../lib/teact/teact'; import React, { memo, useMemo, useRef } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { ApiUser, ApiUserStarGift } from '../../../api/types'; import type { ApiPeer, ApiSavedStarGift } from '../../../api/types';
import { selectUser } from '../../../global/selectors'; import { selectPeer } from '../../../global/selectors';
import { CUSTOM_PEER_HIDDEN } from '../../../util/objects/customPeer'; import { CUSTOM_PEER_HIDDEN } from '../../../util/objects/customPeer';
import { formatIntegerCompact } from '../../../util/textFormat'; import { formatIntegerCompact } from '../../../util/textFormat';
import { getGiftAttributes, getStickerFromGift, getTotalGiftAvailability } from '../helpers/gifts'; import { getGiftAttributes, getStickerFromGift, getTotalGiftAvailability } from '../helpers/gifts';
@ -19,22 +19,22 @@ import Icon from '../icons/Icon';
import RadialPatternBackground from '../profile/RadialPatternBackground'; import RadialPatternBackground from '../profile/RadialPatternBackground';
import GiftRibbon from './GiftRibbon'; import GiftRibbon from './GiftRibbon';
import styles from './UserGift.module.scss'; import styles from './SavedGift.module.scss';
type OwnProps = { type OwnProps = {
userId: string; peerId: string;
gift: ApiUserStarGift; gift: ApiSavedStarGift;
observeIntersection?: ObserveFn; observeIntersection?: ObserveFn;
}; };
type StateProps = { type StateProps = {
fromPeer?: ApiUser; fromPeer?: ApiPeer;
}; };
const GIFT_STICKER_SIZE = 90; const GIFT_STICKER_SIZE = 90;
const UserGift = ({ const SavedGift = ({
userId, peerId,
gift, gift,
fromPeer, fromPeer,
observeIntersection, observeIntersection,
@ -50,7 +50,7 @@ const UserGift = ({
const handleClick = useLastCallback(() => { const handleClick = useLastCallback(() => {
openGiftInfoModal({ openGiftInfoModal({
userId, peerId,
gift, gift,
}); });
}); });
@ -92,7 +92,7 @@ const UserGift = ({
return ( return (
<div ref={ref} className={styles.root} onClick={handleClick}> <div ref={ref} className={styles.root} onClick={handleClick}>
{radialPatternBackdrop} {radialPatternBackdrop}
<Avatar className={styles.avatar} peer={avatarPeer} size="micro" /> {!radialPatternBackdrop && <Avatar className={styles.avatar} peer={avatarPeer} size="micro" />}
<AnimatedIconFromSticker <AnimatedIconFromSticker
sticker={sticker} sticker={sticker}
noLoop noLoop
@ -117,10 +117,10 @@ const UserGift = ({
export default memo(withGlobal<OwnProps>( export default memo(withGlobal<OwnProps>(
(global, { gift }): StateProps => { (global, { gift }): StateProps => {
const fromPeer = gift.fromId ? selectUser(global, gift.fromId) : undefined; const fromPeer = gift.fromId ? selectPeer(global, gift.fromId) : undefined;
return { return {
fromPeer, fromPeer,
}; };
}, },
)(UserGift)); )(SavedGift));

View File

@ -11,7 +11,9 @@ import type { ObserveFn } from '../../hooks/useIntersectionObserver';
import type { FocusDirection, MessageListType, ThreadId } from '../../types'; import type { FocusDirection, MessageListType, ThreadId } from '../../types';
import type { OnIntersectPinnedMessage } from './hooks/usePinnedMessage'; import type { OnIntersectPinnedMessage } from './hooks/usePinnedMessage';
import { getChatTitle, getMessageHtmlId, isJoinedChannelMessage } from '../../global/helpers'; import {
getChatTitle, getMessageHtmlId, getPeerTitle, isJoinedChannelMessage,
} from '../../global/helpers';
import { getMessageReplyInfo } from '../../global/helpers/replies'; import { getMessageReplyInfo } from '../../global/helpers/replies';
import { import {
selectCanPlayAnimatedEmojis, selectCanPlayAnimatedEmojis,
@ -21,6 +23,7 @@ import {
selectGiftStickerForStars, selectGiftStickerForStars,
selectIsCurrentUserPremium, selectIsCurrentUserPremium,
selectIsMessageFocused, selectIsMessageFocused,
selectPeer,
selectTabState, selectTabState,
selectTheme, selectTheme,
selectTopicFromMessage, selectTopicFromMessage,
@ -86,6 +89,7 @@ type StateProps = {
starsGiftSticker?: ApiSticker; starsGiftSticker?: ApiSticker;
canPlayAnimatedEmojis?: boolean; canPlayAnimatedEmojis?: boolean;
patternColor?: string; patternColor?: string;
currentUserId?: string;
isCurrentUserPremium?: boolean; isCurrentUserPremium?: boolean;
}; };
@ -119,6 +123,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
observeIntersectionForLoading, observeIntersectionForLoading,
observeIntersectionForPlaying, observeIntersectionForPlaying,
onIntersectPinnedMessage, onIntersectPinnedMessage,
currentUserId,
isCurrentUserPremium, isCurrentUserPremium,
}) => { }) => {
const { const {
@ -407,16 +412,24 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
} }
function renderStarGiftUserCaption() { function renderStarGiftUserCaption() {
const targetUser = targetUsers && targetUsers[0];
const starGift = message.content.action?.starGift; const starGift = message.content.action?.starGift;
if (!targetUser || !senderUser || !starGift) return undefined; if (!starGift) return undefined;
const { fromId, peerId } = starGift;
if (message.isOutgoing || (starGift.type === 'starGiftUnique' && starGift.isUpgrade)) { const fromPeer = fromId ? selectPeer(getGlobal(), fromId) : undefined;
const targetPeer = peerId
? selectPeer(getGlobal(), peerId)
: starGift.type === 'starGiftUnique' && !message.isOutgoing
? targetChat : undefined;
if (targetPeer && targetPeer.id !== currentUserId) {
return ( return (
<div className="action-message-user-caption"> <div className="action-message-user-caption">
<span> {lang('GiftTo')} </span> <span> {lang('GiftTo')} </span>
<Avatar className="action-message-user-avatar" size="micro" peer={targetChat} /> {starGift.type === 'starGift' && (
<span> {targetUser.firstName} </span> <Avatar className="action-message-user-avatar" size="micro" peer={targetPeer} />
)}
<span> {getPeerTitle(lang, targetPeer)} </span>
</div> </div>
); );
} }
@ -424,15 +437,17 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
return ( return (
<div className="action-message-user-caption"> <div className="action-message-user-caption">
<span> {lang('GiftFrom')} </span> <span> {lang('GiftFrom')} </span>
<Avatar className="action-message-user-avatar" size="micro" peer={senderUser} /> {starGift.type === 'starGift' && (
<span> {senderUser.firstName} </span> <Avatar className="action-message-user-avatar" size="micro" peer={fromPeer || senderUser} />
)}
<span> {getPeerTitle(lang, fromPeer || senderUser!)} </span>
</div> </div>
); );
} }
function renderStarGiftUserDescription() { function renderStarGiftUserDescription() {
const starGift = message.content.action?.starGift as ApiMessageActionStarGift; const starGift = message.content.action?.starGift as ApiMessageActionStarGift;
const targetUser = targetUsers && targetUsers[0]?.firstName; const targetChatTitle = targetChat && getPeerTitle(lang, targetChat);
const starGiftMessage = starGift?.message; const starGiftMessage = starGift?.message;
if (!starGift) return undefined; if (!starGift) return undefined;
@ -442,7 +457,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
const amountToConvert = starGift?.starsToConvert; const amountToConvert = starGift?.starsToConvert;
if (starGift.isSaved) { if (starGift.isSaved) {
return lang('ActionStarGiftDisplaying'); return lang(starGift.savedId ? 'ActionStarGiftChannelDisplaying' : 'ActionStarGiftDisplaying');
} }
if (starGift.isUpgraded) { if (starGift.isUpgraded) {
@ -451,24 +466,24 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
if (message.isOutgoing) { if (message.isOutgoing) {
if (amountToConvert) { if (amountToConvert) {
return lang('ActionStarGiftOutDescription2', { return lang('ActionStarGiftPeerOutDescription', {
user: targetUser || 'User', peer: targetChatTitle || 'Someone',
count: amountToConvert, count: amountToConvert,
}, { withNodes: true, pluralValue: amountToConvert }); }, { withNodes: true, pluralValue: amountToConvert });
} }
if (starGift.canUpgrade) { if (starGift.canUpgrade) {
return lang('ActionStarGiftOutDescriptionUpgrade', { return lang('ActionStarGiftPeerOutDescriptionUpgrade', {
user: targetUser || 'User', peer: targetChatTitle || 'Someone',
}); });
} }
} }
if (starGift.isConverted) { if (starGift.isConverted) {
return message.isOutgoing return message.isOutgoing
? lang('GiftInfoDescriptionOutConverted', { ? lang('GiftInfoPeerDescriptionOutConverted', {
amount: formatInteger(amountToConvert!), amount: formatInteger(amountToConvert!),
user: targetUser || 'User', peer: targetChatTitle || 'Chat',
}, { }, {
pluralValue: amountToConvert!, pluralValue: amountToConvert!,
withNodes: true, withNodes: true,
@ -768,6 +783,7 @@ export default memo(withGlobal<OwnProps>(
noFocusHighlight, noFocusHighlight,
}), }),
isCurrentUserPremium: selectIsCurrentUserPremium(global), isCurrentUserPremium: selectIsCurrentUserPremium(global),
currentUserId: global.currentUserId,
}; };
}, },
)(ActionMessage)); )(ActionMessage));

View File

@ -4,13 +4,14 @@ import React, {
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { ApiMessage, ApiUser } from '../../../api/types'; import type { ApiMessage, ApiPeer } from '../../../api/types';
import type { ThemeKey } from '../../../types'; import type { ThemeKey } from '../../../types';
import type { GiftOption } from './GiftModal'; import type { GiftOption } from './GiftModal';
import { STARS_CURRENCY_CODE } from '../../../config'; import { STARS_CURRENCY_CODE } from '../../../config';
import { getUserFullName } from '../../../global/helpers'; import { getPeerTitle } from '../../../global/helpers';
import { selectTabState, selectTheme, selectUser } from '../../../global/selectors'; import { isApiPeerUser } from '../../../global/helpers/peers';
import { selectPeer, selectTabState, selectTheme } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import buildStyle from '../../../util/buildStyle'; import buildStyle from '../../../util/buildStyle';
import { formatCurrency } from '../../../util/formatCurrency'; import { formatCurrency } from '../../../util/formatCurrency';
@ -32,7 +33,7 @@ import styles from './GiftComposer.module.scss';
export type OwnProps = { export type OwnProps = {
gift: GiftOption; gift: GiftOption;
userId: string; peerId: string;
}; };
export type StateProps = { export type StateProps = {
@ -42,7 +43,7 @@ export type StateProps = {
patternColor?: string; patternColor?: string;
customBackground?: string; customBackground?: string;
backgroundColor?: string; backgroundColor?: string;
user?: ApiUser; peer?: ApiPeer;
currentUserId?: string; currentUserId?: string;
isPaymentFormLoading?: boolean; isPaymentFormLoading?: boolean;
}; };
@ -51,8 +52,8 @@ const LIMIT_DISPLAY_THRESHOLD = 50;
function GiftComposer({ function GiftComposer({
gift, gift,
userId, peerId,
user, peer,
captionLimit, captionLimit,
theme, theme,
isBackgroundBlurred, isBackgroundBlurred,
@ -73,6 +74,7 @@ function GiftComposer({
const customBackgroundValue = useCustomBackground(theme, customBackground); const customBackgroundValue = useCustomBackground(theme, customBackground);
const isStarGift = 'id' in gift; const isStarGift = 'id' in gift;
const isPeerUser = peer && isApiPeerUser(peer);
const localMessage = useMemo(() => { const localMessage = useMemo(() => {
if (!isStarGift) { if (!isStarGift) {
@ -84,7 +86,7 @@ function GiftComposer({
date: Math.floor(Date.now() / 1000), date: Math.floor(Date.now() / 1000),
content: { content: {
action: { action: {
targetUserIds: [userId], targetChatId: peerId,
mediaType: 'action', mediaType: 'action',
text: 'ActionGiftInbound', text: 'ActionGiftInbound',
type: 'giftPremium', type: 'giftPremium',
@ -108,7 +110,7 @@ function GiftComposer({
date: Math.floor(Date.now() / 1000), date: Math.floor(Date.now() / 1000),
content: { content: {
action: { action: {
targetUserIds: [userId], targetChatId: peerId,
mediaType: 'action', mediaType: 'action',
text: 'ActionGiftInbound', text: 'ActionGiftInbound',
type: 'starGift', type: 'starGift',
@ -122,14 +124,17 @@ function GiftComposer({
isNameHidden: shouldHideName, isNameHidden: shouldHideName,
starsToConvert: gift.starsToConvert, starsToConvert: gift.starsToConvert,
canUpgrade: shouldPayForUpgrade || undefined, canUpgrade: shouldPayForUpgrade || undefined,
alreadyPaidUpgradeStars: shouldPayForUpgrade ? gift.upgradeStars : undefined,
isSaved: false, isSaved: false,
gift, gift,
peerId,
fromId: currentUserId,
}, },
translationValues: ['%action_origin%', '%gift_payment_amount%'], translationValues: ['%action_origin%', '%gift_payment_amount%'],
}, },
}, },
} satisfies ApiMessage; } satisfies ApiMessage;
}, [currentUserId, gift, giftMessage, isStarGift, shouldHideName, shouldPayForUpgrade, userId]); }, [currentUserId, gift, giftMessage, isStarGift, shouldHideName, shouldPayForUpgrade, peerId]);
const handleGiftMessageChange = useLastCallback((e: ChangeEvent<HTMLTextAreaElement>) => { const handleGiftMessageChange = useLastCallback((e: ChangeEvent<HTMLTextAreaElement>) => {
setGiftMessage(e.target.value); setGiftMessage(e.target.value);
@ -147,14 +152,14 @@ function GiftComposer({
if (!isStarGift) return; if (!isStarGift) return;
openGiftUpgradeModal({ openGiftUpgradeModal({
giftId: gift.id, giftId: gift.id,
peerId: userId, peerId,
}); });
}); });
const handleMainButtonClick = useLastCallback(() => { const handleMainButtonClick = useLastCallback(() => {
if (isStarGift) { if (isStarGift) {
sendStarGift({ sendStarGift({
userId, peerId,
shouldHideName, shouldHideName,
gift, gift,
message: giftMessage ? { text: giftMessage } : undefined, message: giftMessage ? { text: giftMessage } : undefined,
@ -165,7 +170,7 @@ function GiftComposer({
openInvoice({ openInvoice({
type: 'giftcode', type: 'giftcode',
userIds: [userId], userIds: [peerId],
currency: gift.currency, currency: gift.currency,
amount: gift.amount, amount: gift.amount,
option: gift, option: gift,
@ -176,7 +181,7 @@ function GiftComposer({
function renderOptionsSection() { function renderOptionsSection() {
const symbolsLeft = captionLimit ? captionLimit - giftMessage.length : undefined; const symbolsLeft = captionLimit ? captionLimit - giftMessage.length : undefined;
const userFullName = getUserFullName(user)!; const title = getPeerTitle(lang, peer!)!;
return ( return (
<div className={styles.optionsSection}> <div className={styles.optionsSection}>
<TextArea <TextArea
@ -204,12 +209,19 @@ function GiftComposer({
)} )}
{isStarGift && ( {isStarGift && (
<div className={styles.description}> <div className={styles.description}>
{lang('GiftMakeUniqueDescription', { {isPeerUser
user: userFullName, ? lang('GiftMakeUniqueDescription', {
link: <Link isPrimary onClick={handleOpenUpgradePreview}>{lang('GiftMakeUniqueLink')}</Link>, user: title,
}, { link: <Link isPrimary onClick={handleOpenUpgradePreview}>{lang('GiftMakeUniqueLink')}</Link>,
withNodes: true, }, {
})} withNodes: true,
})
: lang('GiftMakeUniqueDescriptionChannel', {
peer: title,
link: <Link isPrimary onClick={handleOpenUpgradePreview}>{lang('GiftMakeUniqueLink')}</Link>,
}, {
withNodes: true,
})}
</div> </div>
)} )}
@ -225,7 +237,7 @@ function GiftComposer({
)} )}
{isStarGift && ( {isStarGift && (
<div className={styles.description}> <div className={styles.description}>
{lang('GiftHideNameDescription', { profile: userFullName, receiver: userFullName })} {isPeerUser ? lang('GiftHideNameDescription', { receiver: title }) : lang('GiftHideNameDescriptionChannel')}
</div> </div>
)} )}
</div> </div>
@ -298,7 +310,7 @@ function GiftComposer({
} }
export default memo(withGlobal<OwnProps>( export default memo(withGlobal<OwnProps>(
(global, { userId }): StateProps => { (global, { peerId }): StateProps => {
const theme = selectTheme(global); const theme = selectTheme(global);
const { const {
isBlurred: isBackgroundBlurred, isBlurred: isBackgroundBlurred,
@ -306,12 +318,12 @@ export default memo(withGlobal<OwnProps>(
background: customBackground, background: customBackground,
backgroundColor, backgroundColor,
} = global.settings.themes[theme] || {}; } = global.settings.themes[theme] || {};
const user = selectUser(global, userId); const peer = selectPeer(global, peerId);
const tabState = selectTabState(global); const tabState = selectTabState(global);
return { return {
user, peer,
theme, theme,
isBackgroundBlurred, isBackgroundBlurred,
patternColor, patternColor,

View File

@ -5,16 +5,17 @@ import React, {
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { import type {
ApiPeer,
ApiPremiumGiftCodeOption, ApiPremiumGiftCodeOption,
ApiStarGiftRegular, ApiStarGiftRegular,
ApiStarsAmount, ApiStarsAmount,
ApiUser,
} from '../../../api/types'; } from '../../../api/types';
import type { TabState } from '../../../global/types'; import type { TabState } from '../../../global/types';
import type { StarGiftCategory } from '../../../types'; import type { StarGiftCategory } from '../../../types';
import { getUserFullName } from '../../../global/helpers'; import { getPeerTitle, getUserFullName } from '../../../global/helpers';
import { selectUser } from '../../../global/selectors'; import { isApiPeerChat, isApiPeerUser } from '../../../global/helpers/peers';
import { selectPeer } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev'; import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev';
@ -49,7 +50,7 @@ type StateProps = {
starGiftsById?: Record<string, ApiStarGiftRegular>; starGiftsById?: Record<string, ApiStarGiftRegular>;
starGiftIdsByCategory?: Record<StarGiftCategory, string[]>; starGiftIdsByCategory?: Record<StarGiftCategory, string[]>;
starBalance?: ApiStarsAmount; starBalance?: ApiStarsAmount;
user?: ApiUser; peer?: ApiPeer;
isSelf?: boolean; isSelf?: boolean;
}; };
@ -61,7 +62,7 @@ const PremiumGiftModal: FC<OwnProps & StateProps> = ({
starGiftsById, starGiftsById,
starGiftIdsByCategory, starGiftIdsByCategory,
starBalance, starBalance,
user, peer,
isSelf, isSelf,
}) => { }) => {
const { const {
@ -80,6 +81,9 @@ const PremiumGiftModal: FC<OwnProps & StateProps> = ({
const isOpen = Boolean(modal); const isOpen = Boolean(modal);
const renderingModal = useCurrentOrPrev(modal); const renderingModal = useCurrentOrPrev(modal);
const user = peer && isApiPeerUser(peer) ? peer : undefined;
const chat = peer && isApiPeerChat(peer) ? peer : undefined;
const [selectedGift, setSelectedGift] = useState<GiftOption | undefined>(); const [selectedGift, setSelectedGift] = useState<GiftOption | undefined>();
const [isHeaderHidden, setIsHeaderHidden] = useState(true); const [isHeaderHidden, setIsHeaderHidden] = useState(true);
const [isHeaderForStarGifts, setIsHeaderForStarGifts] = useState(false); const [isHeaderForStarGifts, setIsHeaderForStarGifts] = useState(false);
@ -156,14 +160,19 @@ const PremiumGiftModal: FC<OwnProps & StateProps> = ({
), ),
}, { withNodes: true }); }, { withNodes: true });
const starGiftDescription = isSelf const starGiftDescription = chat
? lang('StarGiftDescriptionSelf', undefined, { ? lang('StarGiftDescriptionChannel', { peer: getPeerTitle(lang, chat) }, {
withNodes: true, withNodes: true,
renderTextFilters: ['br'], withMarkdown: true,
}) })
: lang('StarGiftDescription', { : isSelf
user: getUserFullName(user)!, ? lang('StarGiftDescriptionSelf', undefined, {
}, { withNodes: true, withMarkdown: true }); withNodes: true,
renderTextFilters: ['br'],
})
: lang('StarGiftDescription', {
user: getUserFullName(user)!,
}, { withNodes: true, withMarkdown: true });
function renderGiftPremiumHeader() { function renderGiftPremiumHeader() {
return ( return (
@ -254,13 +263,13 @@ const PremiumGiftModal: FC<OwnProps & StateProps> = ({
<div className={styles.avatars}> <div className={styles.avatars}>
<Avatar <Avatar
size={AVATAR_SIZE} size={AVATAR_SIZE}
peer={user} peer={peer}
/> />
<img className={styles.logoBackground} src={StarsBackground} alt="" draggable={false} /> <img className={styles.logoBackground} src={StarsBackground} alt="" draggable={false} />
</div> </div>
{!isSelf && renderGiftPremiumHeader()} {!isSelf && !chat && renderGiftPremiumHeader()}
{!isSelf && renderGiftPremiumDescription()} {!isSelf && !chat && renderGiftPremiumDescription()}
{!isSelf && renderPremiumGifts()} {!isSelf && !chat && renderPremiumGifts()}
{renderStarGiftsHeader()} {renderStarGiftsHeader()}
{renderStarGiftsDescription()} {renderStarGiftsDescription()}
@ -321,8 +330,8 @@ const PremiumGiftModal: FC<OwnProps & StateProps> = ({
activeKey={selectedGift ? 1 : 0} activeKey={selectedGift ? 1 : 0}
> >
{!selectedGift && renderMainScreen()} {!selectedGift && renderMainScreen()}
{selectedGift && renderingModal?.forUserId && ( {selectedGift && renderingModal?.forPeerId && (
<GiftSendingOptions gift={selectedGift} userId={renderingModal.forUserId} /> <GiftSendingOptions gift={selectedGift} peerId={renderingModal.forPeerId} />
)} )}
</Transition> </Transition>
</Modal> </Modal>
@ -336,22 +345,22 @@ export default memo(withGlobal<OwnProps>((global, { modal }): StateProps => {
currentUserId, currentUserId,
} = global; } = global;
const user = modal?.forUserId ? selectUser(global, modal.forUserId) : undefined; const peer = modal?.forPeerId ? selectPeer(global, modal.forPeerId) : undefined;
const isSelf = Boolean(currentUserId && modal?.forUserId === currentUserId); const isSelf = Boolean(currentUserId && modal?.forPeerId === currentUserId);
return { return {
boostPerSentGift: global.appConfig?.boostsPerSentGift, boostPerSentGift: global.appConfig?.boostsPerSentGift,
starGiftsById: starGifts?.byId, starGiftsById: starGifts?.byId,
starGiftIdsByCategory: starGifts?.idsByCategory, starGiftIdsByCategory: starGifts?.idsByCategory,
starBalance: stars?.balance, starBalance: stars?.balance,
user, peer,
isSelf, isSelf,
}; };
})(PremiumGiftModal)); })(PremiumGiftModal));
function getCategoryKey(category: StarGiftCategory) { function getCategoryKey(category: StarGiftCategory) {
if (category === 'all') return -2; if (category === 'all') return -2;
if (category === 'stock') return -1; if (category === 'limited') return -1;
if (category === 'limited') return 0; if (category === 'stock') return 0;
return category; return category;
} }

View File

@ -78,8 +78,8 @@ const StarGiftCategoryList = ({
return ( return (
<div ref={ref} className={buildClassName(styles.list, 'no-scrollbar')}> <div ref={ref} className={buildClassName(styles.list, 'no-scrollbar')}>
{renderCategoryItem('all')} {renderCategoryItem('all')}
{renderCategoryItem('stock')}
{renderCategoryItem('limited')} {renderCategoryItem('limited')}
{renderCategoryItem('stock')}
{starCategories?.map(renderCategoryItem)} {starCategories?.map(renderCategoryItem)}
</div> </div>
); );

View File

@ -52,6 +52,7 @@
gap: 0.25rem; gap: 0.25rem;
} }
/* stylelint-disable-next-line plugin/stylelint-group-selectors */
.uniqueGift { .uniqueGift {
margin-bottom: 0; margin-bottom: 0;
} }
@ -59,3 +60,17 @@
.starAmountIcon { .starAmountIcon {
margin-inline-start: 0 !important; margin-inline-start: 0 !important;
} }
.ownerAddress {
font-family: var(--font-family-monospace);
font-size: 0.875rem;
cursor: pointer;
overflow: hidden;
}
.copyIcon {
margin-inline-start: 0.25rem;
color: var(--color-primary);
pointer-events: none;
}

View File

@ -3,13 +3,15 @@ import React, { memo, useMemo } from '../../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../../global'; import { getActions, getGlobal, withGlobal } from '../../../../global';
import type { import type {
ApiUser, ApiPeer,
} from '../../../../api/types'; } from '../../../../api/types';
import type { TabState } from '../../../../global/types'; import type { TabState } from '../../../../global/types';
import { getUserFullName } from '../../../../global/helpers'; import { getHasAdminRight, getPeerTitle } from '../../../../global/helpers';
import { selectUser } from '../../../../global/selectors'; import { isApiPeerChat } from '../../../../global/helpers/peers';
import { selectPeer } from '../../../../global/selectors';
import buildClassName from '../../../../util/buildClassName'; import buildClassName from '../../../../util/buildClassName';
import { copyTextToClipboard } from '../../../../util/clipboard';
import { formatDateTimeToString } from '../../../../util/dates/dateFormat'; import { formatDateTimeToString } from '../../../../util/dates/dateFormat';
import { formatStarsAsIcon, formatStarsAsText } from '../../../../util/localization/format'; import { formatStarsAsIcon, formatStarsAsText } from '../../../../util/localization/format';
import { CUSTOM_PEER_HIDDEN } from '../../../../util/objects/customPeer'; import { CUSTOM_PEER_HIDDEN } from '../../../../util/objects/customPeer';
@ -27,6 +29,7 @@ import useOldLang from '../../../../hooks/useOldLang';
import AnimatedIconFromSticker from '../../../common/AnimatedIconFromSticker'; 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 Button from '../../../ui/Button'; import Button from '../../../ui/Button';
import ConfirmDialog from '../../../ui/ConfirmDialog'; import ConfirmDialog from '../../../ui/ConfirmDialog';
import Link from '../../../ui/Link'; import Link from '../../../ui/Link';
@ -40,16 +43,22 @@ export type OwnProps = {
}; };
type StateProps = { type StateProps = {
userFrom?: ApiUser; fromPeer?: ApiPeer;
targetUser?: ApiUser; targetPeer?: ApiPeer;
currentUserId?: string; currentUserId?: string;
starGiftMaxConvertPeriod?: number; starGiftMaxConvertPeriod?: number;
hasAdminRights?: boolean;
}; };
const STICKER_SIZE = 120; const STICKER_SIZE = 120;
const GiftInfoModal = ({ const GiftInfoModal = ({
modal, userFrom, targetUser, currentUserId, starGiftMaxConvertPeriod, modal,
fromPeer,
targetPeer,
currentUserId,
starGiftMaxConvertPeriod,
hasAdminRights,
}: OwnProps & StateProps) => { }: OwnProps & StateProps) => {
const { const {
closeGiftInfoModal, closeGiftInfoModal,
@ -58,6 +67,7 @@ const GiftInfoModal = ({
openChatWithInfo, openChatWithInfo,
focusMessage, focusMessage,
openGiftUpgradeModal, openGiftUpgradeModal,
showNotification,
} = getActions(); } = getActions();
const [isConvertConfirmOpen, openConvertConfirm, closeConvertConfirm] = useFlag(); const [isConvertConfirmOpen, openConvertConfirm, closeConvertConfirm] = useFlag();
@ -67,48 +77,55 @@ const GiftInfoModal = ({
const isOpen = Boolean(modal); const isOpen = Boolean(modal);
const renderingModal = useCurrentOrPrev(modal); const renderingModal = useCurrentOrPrev(modal);
const renderingFromPeer = useCurrentOrPrev(fromPeer);
const renderingTargetPeer = useCurrentOrPrev(targetPeer);
const isTargetChat = renderingTargetPeer && isApiPeerChat(renderingTargetPeer);
const { gift: typeGift } = renderingModal || {}; const { gift: typeGift } = renderingModal || {};
const isUserGift = typeGift && 'gift' in typeGift; const isSavedGift = typeGift && 'gift' in typeGift;
const userGift = isUserGift ? typeGift : undefined; const savedGift = isSavedGift ? typeGift : undefined;
const isSender = userGift?.fromId === currentUserId; const isSender = savedGift?.fromId === currentUserId;
const canConvertDifference = (userGift && starGiftMaxConvertPeriod && ( const canConvertDifference = (savedGift && starGiftMaxConvertPeriod && (
userGift.date + starGiftMaxConvertPeriod - getServerTime() savedGift.date + starGiftMaxConvertPeriod - getServerTime()
)) || 0; )) || 0;
const conversionLeft = Math.ceil(canConvertDifference / 60 / 60 / 24); const conversionLeft = Math.ceil(canConvertDifference / 60 / 60 / 24);
const gift = isUserGift ? typeGift.gift : typeGift; const gift = isSavedGift ? typeGift.gift : typeGift;
const giftSticker = gift && getStickerFromGift(gift); const giftSticker = gift && getStickerFromGift(gift);
const canFocusUpgrade = Boolean(userGift?.upgradeMsgId); const canFocusUpgrade = Boolean(savedGift?.upgradeMsgId);
const canUpdate = Boolean(userGift?.messageId) && targetUser?.id === currentUserId && !canFocusUpgrade; const canUpdate = !canFocusUpgrade && savedGift?.inputGift && (
isTargetChat ? hasAdminRights : renderingTargetPeer?.id === currentUserId
);
const handleClose = useLastCallback(() => { const handleClose = useLastCallback(() => {
closeGiftInfoModal(); closeGiftInfoModal();
}); });
const handleFocusUpgraded = useLastCallback(() => { const handleFocusUpgraded = useLastCallback(() => {
if (!userGift?.upgradeMsgId || !targetUser) return; if (!savedGift?.upgradeMsgId || !renderingTargetPeer) return;
const { upgradeMsgId } = userGift; const { upgradeMsgId } = savedGift;
focusMessage({ chatId: targetUser.id, messageId: upgradeMsgId! }); focusMessage({ chatId: renderingTargetPeer.id, messageId: upgradeMsgId! });
handleClose(); handleClose();
}); });
const handleTriggerVisibility = useLastCallback(() => { const handleTriggerVisibility = useLastCallback(() => {
const { messageId, isUnsaved } = userGift!; const { inputGift, isUnsaved } = savedGift!;
changeGiftVisibility({ messageId: messageId!, shouldUnsave: !isUnsaved }); changeGiftVisibility({ gift: inputGift!, shouldUnsave: !isUnsaved });
handleClose(); handleClose();
}); });
const handleConvertToStars = useLastCallback(() => { const handleConvertToStars = useLastCallback(() => {
const { messageId } = userGift!; const { inputGift } = savedGift!;
convertGiftToStars({ messageId: messageId! }); convertGiftToStars({ gift: inputGift! });
closeConvertConfirm(); closeConvertConfirm();
handleClose(); handleClose();
}); });
const handleOpenUpgradeModal = useLastCallback(() => { const handleOpenUpgradeModal = useLastCallback(() => {
if (!userGift) return; if (!savedGift) return;
openGiftUpgradeModal({ giftId: userGift.gift.id, gift: userGift }); openGiftUpgradeModal({ giftId: savedGift.gift.id, gift: savedGift });
}); });
const giftAttributes = useMemo(() => { const giftAttributes = useMemo(() => {
@ -124,7 +141,7 @@ const GiftInfoModal = ({
); );
} }
if (canUpdate && userGift?.alreadyPaidUpgradeStars && !userGift.upgradeMsgId) { if (canUpdate && savedGift?.alreadyPaidUpgradeStars && !savedGift.upgradeMsgId) {
return ( return (
<Button size="smaller" isShiny onClick={handleOpenUpgradeModal}> <Button size="smaller" isShiny onClick={handleOpenUpgradeModal}>
{lang('GiftInfoUpgradeForFree')} {lang('GiftInfoUpgradeForFree')}
@ -146,17 +163,19 @@ const GiftInfoModal = ({
const { const {
fromId, isNameHidden, starsToConvert, isUnsaved, isConverted, fromId, isNameHidden, starsToConvert, isUnsaved, isConverted,
} = userGift || {}; } = savedGift || {};
const isVisibleForMe = isNameHidden && targetUser; const isVisibleForMe = isNameHidden && renderingTargetPeer;
const description = (() => { const description = (() => {
if (!userGift) return lang('GiftInfoSoldOutDescription'); if (!savedGift) return lang('GiftInfoSoldOutDescription');
if (userGift.upgradeMsgId) return lang('GiftInfoDescriptionUpgraded'); if (isTargetChat) return undefined;
if (userGift.canUpgrade && userGift.alreadyPaidUpgradeStars) {
if (savedGift.upgradeMsgId) return lang('GiftInfoDescriptionUpgraded');
if (savedGift.canUpgrade && savedGift.alreadyPaidUpgradeStars) {
return canUpdate return canUpdate
? lang('GiftInfoDescriptionFreeUpgrade') ? lang('GiftInfoDescriptionFreeUpgrade')
: lang('GiftInfoDescriptionFreeUpgradeOut', { user: getUserFullName(targetUser)! }); : lang('GiftInfoPeerDescriptionFreeUpgradeOut', { peer: getPeerTitle(lang, renderingTargetPeer!)! });
} }
if (!canUpdate && !isSender) return undefined; if (!canUpdate && !isSender) return undefined;
if (isConverted && starsToConvert) { if (isConverted && starsToConvert) {
@ -168,9 +187,9 @@ const GiftInfoModal = ({
withNodes: true, withNodes: true,
withMarkdown: true, withMarkdown: true,
}) })
: lang('GiftInfoDescriptionOutConverted', { : lang('GiftInfoPeerDescriptionOutConverted', {
amount: formatInteger(starsToConvert!), amount: formatInteger(starsToConvert!),
user: getUserFullName(targetUser)!, peer: getPeerTitle(lang, renderingTargetPeer!)!,
}, { }, {
pluralValue: starsToConvert, pluralValue: starsToConvert,
withNodes: true, withNodes: true,
@ -178,7 +197,7 @@ const GiftInfoModal = ({
}); });
} }
if (userGift.canUpgrade && canUpdate) { if (savedGift.canUpgrade && canUpdate) {
return lang('GiftInfoDescriptionUpgrade', { return lang('GiftInfoDescriptionUpgrade', {
amount: formatInteger(starsToConvert!), amount: formatInteger(starsToConvert!),
}, { }, {
@ -196,9 +215,9 @@ const GiftInfoModal = ({
withMarkdown: true, withMarkdown: true,
pluralValue: starsToConvert || 0, pluralValue: starsToConvert || 0,
}) })
: lang('GiftInfoDescriptionOut', { : lang('GiftInfoPeerDescriptionOut', {
amount: starsToConvert, amount: starsToConvert,
user: getUserFullName(targetUser)!, peer: getPeerTitle(lang, renderingTargetPeer!)!,
}, { }, {
withNodes: true, withNodes: true,
withMarkdown: true, withMarkdown: true,
@ -208,7 +227,7 @@ const GiftInfoModal = ({
function getTitle() { function getTitle() {
if (gift?.type === 'starGiftUnique') return gift.title; if (gift?.type === 'starGiftUnique') return gift.title;
if (!userGift) return lang('GiftInfoSoldOutTitle'); if (!savedGift) return lang('GiftInfoSoldOutTitle');
return canUpdate ? lang('GiftInfoReceived') : lang('GiftInfoTitle'); return canUpdate ? lang('GiftInfoReceived') : lang('GiftInfoTitle');
} }
@ -238,7 +257,7 @@ const GiftInfoModal = ({
{getTitle()} {getTitle()}
</h1> </h1>
{description && ( {description && (
<p className={buildClassName(styles.description, !userGift && gift?.type === 'starGift' && styles.soldOut)}> <p className={buildClassName(styles.description, !savedGift && gift?.type === 'starGift' && styles.soldOut)}>
{description} {description}
</p> </p>
)} )}
@ -259,10 +278,10 @@ const GiftInfoModal = ({
]); ]);
} }
if (userGift?.date) { if (savedGift?.date) {
tableData.push([ tableData.push([
lang('GiftInfoDate'), lang('GiftInfoDate'),
formatDateTimeToString(userGift.date * 1000, lang.code, true), formatDateTimeToString(savedGift.date * 1000, lang.code, true),
]); ]);
} }
@ -280,7 +299,7 @@ const GiftInfoModal = ({
]); ]);
} }
const starsValue = gift.stars + (userGift?.alreadyPaidUpgradeStars || 0); const starsValue = gift.stars + (savedGift?.alreadyPaidUpgradeStars || 0);
tableData.push([ tableData.push([
lang('GiftInfoValue'), lang('GiftInfoValue'),
@ -306,7 +325,7 @@ const GiftInfoModal = ({
]); ]);
} }
if (gift.upgradeStars && !userGift?.upgradeMsgId) { if (gift.upgradeStars && !savedGift?.upgradeMsgId) {
tableData.push([ tableData.push([
lang('GiftInfoStatus'), lang('GiftInfoStatus'),
<div className={styles.giftValue}> <div className={styles.giftValue}>
@ -316,23 +335,43 @@ const GiftInfoModal = ({
]); ]);
} }
if (userGift?.message) { if (savedGift?.message) {
tableData.push([ tableData.push([
undefined, undefined,
renderTextWithEntities(userGift.message), renderTextWithEntities(savedGift.message),
]); ]);
} }
} }
if (gift.type === 'starGiftUnique') { if (gift.type === 'starGiftUnique') {
const { ownerName, ownerAddress, ownerId } = gift;
const { const {
model, backdrop, pattern, originalDetails, model, backdrop, pattern, originalDetails,
} = giftAttributes || {}; } = giftAttributes || {};
const ownerName = gift.ownerName;
tableData.push([ if (ownerAddress) {
lang('GiftInfoOwner'), tableData.push([
gift.ownerId ? { chatId: gift.ownerId } : ownerName || '', lang('GiftInfoOwner'),
]); <span
className={styles.ownerAddress}
onClick={() => {
copyTextToClipboard(ownerAddress);
showNotification({
message: { key: 'WalletAddressCopied' },
icon: 'copy',
});
}}
>
{ownerAddress}
<Icon className={styles.copyIcon} name="copy" />
</span>,
]);
} else {
tableData.push([
lang('GiftInfoOwner'),
ownerId ? { chatId: ownerId } : ownerName || '',
]);
}
if (model) { if (model) {
tableData.push([ tableData.push([
@ -373,34 +412,34 @@ const GiftInfoModal = ({
const { const {
date, recipientId, message, senderId, date, recipientId, message, senderId,
} = originalDetails; } = originalDetails;
const global = getGlobal(); // User names does not need to be reactive const global = getGlobal(); // Peer titles do not need to be reactive
const openChat = (id: string) => { const openChat = (id: string) => {
openChatWithInfo({ id }); openChatWithInfo({ id });
closeGiftInfoModal(); closeGiftInfoModal();
}; };
const recipient = selectUser(global, recipientId)!; const recipient = selectPeer(global, recipientId)!;
const sender = senderId ? selectUser(global, senderId) : undefined; const sender = senderId ? selectPeer(global, senderId) : undefined;
const formattedDate = formatDateTimeToString(date * 1000, lang.code, true); const formattedDate = formatDateTimeToString(date * 1000, lang.code, true);
const recipientLink = ( const recipientLink = (
// eslint-disable-next-line react/jsx-no-bind // eslint-disable-next-line react/jsx-no-bind
<Link onClick={() => openChat(recipientId)} isPrimary> <Link onClick={() => openChat(recipientId)} isPrimary>
{getUserFullName(recipient)} {getPeerTitle(lang, recipient)}
</Link> </Link>
); );
let text: TeactNode | undefined; let text: TeactNode | undefined;
if (!sender || senderId === recipientId) { if (!sender || senderId === recipientId) {
text = message ? lang('GiftInfoOriginalInfoText', { text = message ? lang('GiftInfoPeerOriginalInfoText', {
user: recipientLink, peer: recipientLink,
text: renderTextWithEntities(message), text: renderTextWithEntities(message),
date: formattedDate, date: formattedDate,
}, { }, {
withNodes: true, withNodes: true,
}) : lang('GiftInfoOriginalInfo', { }) : lang('GiftInfoPeerOriginalInfo', {
user: recipientLink, peer: recipientLink,
date: formattedDate, date: formattedDate,
}, { }, {
withNodes: true, withNodes: true,
@ -409,18 +448,18 @@ const GiftInfoModal = ({
const senderLink = ( const senderLink = (
// eslint-disable-next-line react/jsx-no-bind // eslint-disable-next-line react/jsx-no-bind
<Link onClick={() => openChat(sender.id)} isPrimary> <Link onClick={() => openChat(sender.id)} isPrimary>
{getUserFullName(sender)} {getPeerTitle(lang, sender)}
</Link> </Link>
); );
text = message ? lang('GiftInfoOriginalInfoTextSender', { text = message ? lang('GiftInfoPeerOriginalInfoTextSender', {
user: recipientLink, peer: recipientLink,
sender: senderLink, sender: senderLink,
text: renderTextWithEntities(message), text: renderTextWithEntities(message),
date: formattedDate, date: formattedDate,
}, { }, {
withNodes: true, withNodes: true,
}) : lang('GiftInfoOriginalInfoSender', { }) : lang('GiftInfoPeerOriginalInfoSender', {
user: recipientLink, peer: recipientLink,
date: formattedDate, date: formattedDate,
sender: senderLink, sender: senderLink,
}, { }, {
@ -440,8 +479,12 @@ const GiftInfoModal = ({
{canUpdate && ( {canUpdate && (
<div className={styles.footerDescription}> <div className={styles.footerDescription}>
<div> <div>
{lang(isUnsaved ? 'GiftInfoHidden' : 'GiftInfoSaved', { {lang(`GiftInfo${isTargetChat ? 'Channel' : ''}${isUnsaved ? 'Hidden' : 'Saved'}`, {
link: <Link isPrimary onClick={handleTriggerVisibility}>{lang('GiftInfoSavedHide')}</Link>, link: (
<Link isPrimary onClick={handleTriggerVisibility}>
{lang(`GiftInfoSaved${isUnsaved ? 'Show' : 'Hide'}`)}
</Link>
),
}, { }, {
withNodes: true, withNodes: true,
})} })}
@ -463,8 +506,8 @@ const GiftInfoModal = ({
footer, footer,
}; };
}, [ }, [
typeGift, userGift, targetUser, giftSticker, lang, canUpdate, canConvertDifference, isSender, oldLang, gift, typeGift, savedGift, renderingTargetPeer, giftSticker, lang, canUpdate, canConvertDifference, isSender, oldLang,
giftAttributes, renderFooterButton, gift, giftAttributes, renderFooterButton, isTargetChat,
]); ]);
return ( return (
@ -478,7 +521,7 @@ const GiftInfoModal = ({
className={styles.modal} className={styles.modal}
onClose={handleClose} onClose={handleClose}
/> />
{userGift && ( {savedGift && (
<ConfirmDialog <ConfirmDialog
isOpen={isConvertConfirmOpen} isOpen={isConvertConfirmOpen}
onClose={closeConvertConfirm} onClose={closeConvertConfirm}
@ -486,9 +529,9 @@ const GiftInfoModal = ({
title={lang('GiftInfoConvertTitle')} title={lang('GiftInfoConvertTitle')}
> >
<div> <div>
{lang('GiftInfoConvertDescription1', { {lang('GiftInfoPeerConvertDescription', {
amount: formatStarsAsText(lang, userGift.starsToConvert!), amount: formatStarsAsText(lang, savedGift.starsToConvert!),
user: getUserFullName(userFrom)!, peer: getPeerTitle(lang, renderingFromPeer!)!,
}, { }, {
withNodes: true, withNodes: true,
withMarkdown: true, withMarkdown: true,
@ -515,17 +558,20 @@ const GiftInfoModal = ({
export default memo(withGlobal<OwnProps>( export default memo(withGlobal<OwnProps>(
(global, { modal }): StateProps => { (global, { modal }): StateProps => {
const typeGift = modal?.gift; const typeGift = modal?.gift;
const isUserGift = typeGift && 'gift' in typeGift; const isSavedGift = typeGift && 'gift' in typeGift;
const fromId = isUserGift && typeGift.fromId; const fromId = isSavedGift && typeGift.fromId;
const userFrom = fromId ? selectUser(global, fromId) : undefined; const fromPeer = fromId ? selectPeer(global, fromId) : undefined;
const targetUser = modal?.userId ? selectUser(global, modal.userId) : undefined; const targetPeer = modal?.peerId ? selectPeer(global, modal.peerId) : undefined;
const chat = targetPeer && isApiPeerChat(targetPeer) ? targetPeer : undefined;
const hasAdminRights = chat && getHasAdminRight(chat, 'postMessages');
return { return {
userFrom, fromPeer,
targetUser, targetPeer,
currentUserId: global.currentUserId, currentUserId: global.currentUserId,
starGiftMaxConvertPeriod: global.appConfig?.starGiftMaxConvertPeriod, starGiftMaxConvertPeriod: global.appConfig?.starGiftMaxConvertPeriod,
hasAdminRights,
}; };
}, },
)(GiftInfoModal)); )(GiftInfoModal));

View File

@ -63,9 +63,10 @@ const GiftUpgradeModal = ({ modal, recipient }: OwnProps & StateProps) => {
const handleUpgrade = useLastCallback(() => { const handleUpgrade = useLastCallback(() => {
const gift = renderingModal?.gift; const gift = renderingModal?.gift;
if (!gift?.messageId) return; if (!gift?.inputGift) return;
upgradeGift({ upgradeGift({
messageId: gift.messageId, gift: gift.inputGift,
shouldKeepOriginalDetails, shouldKeepOriginalDetails,
upgradeStars: !gift.alreadyPaidUpgradeStars ? (gift.gift as ApiStarGiftRegular).upgradeStars : undefined, upgradeStars: !gift.alreadyPaidUpgradeStars ? (gift.gift as ApiStarGiftRegular).upgradeStars : undefined,
}); });
@ -114,7 +115,7 @@ const GiftUpgradeModal = ({ modal, recipient }: OwnProps & StateProps) => {
] satisfies TableAboutData; ] satisfies TableAboutData;
const subtitle = renderingRecipient const subtitle = renderingRecipient
? lang('GiftUpgradeText', { peer: getPeerTitle(lang, renderingRecipient) }) ? lang('GiftPeerUpgradeText', { peer: getPeerTitle(lang, renderingRecipient) })
: lang('GiftUpgradeTextOwn'); : lang('GiftUpgradeTextOwn');
const header = ( const header = (

View File

@ -7,7 +7,7 @@ import type { ApiStarTopupOption } from '../../../api/types';
import type { GlobalState, TabState } from '../../../global/types'; import type { GlobalState, TabState } from '../../../global/types';
import type { RegularLangKey } from '../../../types/language'; import type { RegularLangKey } from '../../../types/language';
import { getChatTitle, getUserFullName } from '../../../global/helpers'; import { getChatTitle, getPeerTitle, getUserFullName } from '../../../global/helpers';
import { selectChat, selectIsPremiumPurchaseBlocked, selectUser } from '../../../global/selectors'; import { selectChat, selectIsPremiumPurchaseBlocked, selectUser } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import renderText from '../../common/helpers/renderText'; import renderText from '../../common/helpers/renderText';
@ -99,9 +99,9 @@ const StarsBalanceModal = ({
} }
if (originGift) { if (originGift) {
const user = selectUser(global, originGift.userId); const peer = selectUser(global, originGift.peerId);
if (!user) return undefined; if (!peer) return undefined;
return oldLang('StarsNeededTextGift', getUserFullName(user)); return oldLang('StarsNeededTextGift', getPeerTitle(lang, peer));
} }
if (topup?.purpose === SUBSCRIPTION_PURPOSE) { if (topup?.purpose === SUBSCRIPTION_PURPOSE) {
@ -109,7 +109,7 @@ const StarsBalanceModal = ({
} }
return undefined; return undefined;
}, [originReaction, originStarsPayment, originGift, topup?.purpose, oldLang]); }, [originReaction, originStarsPayment, originGift, topup?.purpose, lang, oldLang]);
const shouldShowItems = Boolean(history?.all?.transactions.length && !shouldOpenOnBuy); const shouldShowItems = Boolean(history?.all?.transactions.length && !shouldOpenOnBuy);
const shouldSuggestGifting = !shouldOpenOnBuy; const shouldSuggestGifting = !shouldOpenOnBuy;

View File

@ -10,9 +10,9 @@ import type {
ApiChat, ApiChat,
ApiChatMember, ApiChatMember,
ApiMessage, ApiMessage,
ApiSavedStarGift,
ApiTypeStory, ApiTypeStory,
ApiUser, ApiUser,
ApiUserStarGift,
ApiUserStatus, ApiUserStatus,
} from '../../api/types'; } from '../../api/types';
import type { TabState } from '../../global/types'; import type { TabState } from '../../global/types';
@ -81,7 +81,7 @@ import useTransitionFixes from './hooks/useTransitionFixes';
import Audio from '../common/Audio'; import Audio from '../common/Audio';
import Document from '../common/Document'; import Document from '../common/Document';
import UserGift from '../common/gift/UserGift'; import SavedGift from '../common/gift/SavedGift';
import GroupChatInfo from '../common/GroupChatInfo'; import GroupChatInfo from '../common/GroupChatInfo';
import Icon from '../common/icons/Icon'; import Icon from '../common/icons/Icon';
import Media from '../common/Media'; import Media from '../common/Media';
@ -125,7 +125,7 @@ type StateProps = {
hasMembersTab?: boolean; hasMembersTab?: boolean;
hasPreviewMediaTab?: boolean; hasPreviewMediaTab?: boolean;
hasGiftsTab?: boolean; hasGiftsTab?: boolean;
gifts?: ApiUserStarGift[]; gifts?: ApiSavedStarGift[];
areMembersHidden?: boolean; areMembersHidden?: boolean;
canAddMembers?: boolean; canAddMembers?: boolean;
canDeleteMembers?: boolean; canDeleteMembers?: boolean;
@ -234,7 +234,7 @@ const Profile: FC<OwnProps & StateProps> = ({
loadChannelRecommendations, loadChannelRecommendations,
loadBotRecommendations, loadBotRecommendations,
loadPreviewMedias, loadPreviewMedias,
loadUserGifts, loadPeerSavedGifts,
} = getActions(); } = getActions();
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
@ -364,7 +364,7 @@ const Profile: FC<OwnProps & StateProps> = ({
loadStoriesArchive({ peerId: currentUserId!, offsetId }); loadStoriesArchive({ peerId: currentUserId!, offsetId });
}, [currentUserId]); }, [currentUserId]);
const handleLoadGifts = useCallback(() => { const handleLoadGifts = useCallback(() => {
loadUserGifts({ userId: chatId }); loadPeerSavedGifts({ peerId: chatId });
}, [chatId]); }, [chatId]);
const [resultType, viewportIds, getMore, noProfileInfo] = useProfileViewportIds({ const [resultType, viewportIds, getMore, noProfileInfo] = useProfileViewportIds({
@ -774,8 +774,8 @@ const Profile: FC<OwnProps & StateProps> = ({
</div> </div>
) : resultType === 'gifts' ? ( ) : resultType === 'gifts' ? (
(gifts?.map((gift) => ( (gifts?.map((gift) => (
<UserGift <SavedGift
userId={chatId} peerId={chatId}
key={`${gift.date}-${gift.fromId}-${gift.gift.id}`} key={`${gift.date}-${gift.fromId}-${gift.gift.id}`}
gift={gift} gift={gift}
observeIntersection={observeIntersectionForMedia} observeIntersection={observeIntersectionForMedia}
@ -908,8 +908,8 @@ export default memo(withGlobal<OwnProps>(
const storyByIds = peerStories?.byId; const storyByIds = peerStories?.byId;
const archiveStoryIds = peerStories?.archiveIds; const archiveStoryIds = peerStories?.archiveIds;
const hasGiftsTab = Boolean(userFullInfo?.starGiftCount) && !isSavedDialog; const hasGiftsTab = Boolean(peerFullInfo?.starGiftCount) && !isSavedDialog;
const userGifts = global.users.giftsById[chatId]; const peerGifts = global.peers.giftsById[chatId];
return { return {
theme: selectTheme(global), theme: selectTheme(global),
@ -934,7 +934,7 @@ export default memo(withGlobal<OwnProps>(
chatsById, chatsById,
storyIds, storyIds,
hasGiftsTab, hasGiftsTab,
gifts: userGifts?.gifts, gifts: peerGifts?.gifts,
pinnedStoryIds, pinnedStoryIds,
archiveStoryIds, archiveStoryIds,
storyByIds, storyByIds,

View File

@ -17,6 +17,7 @@ import { callApi } from '../../../api/gramjs';
import { isChatChannel, isChatSuperGroup } from '../../helpers'; import { isChatChannel, isChatSuperGroup } from '../../helpers';
import { import {
getRequestInputInvoice, getRequestInputInvoice,
getRequestInputSavedStarGift,
} from '../../helpers/payments'; } from '../../helpers/payments';
import { import {
addActionHandler, getActions, getGlobal, setGlobal, addActionHandler, getActions, getGlobal, setGlobal,
@ -123,12 +124,12 @@ addActionHandler('openInvoice', async (global, actions, payload): Promise<void>
addActionHandler('sendStarGift', (global, actions, payload): ActionReturnType => { addActionHandler('sendStarGift', (global, actions, payload): ActionReturnType => {
const { const {
gift, userId, message, shouldHideName, shouldUpgrade, tabId = getCurrentTabId(), gift, peerId, message, shouldHideName, shouldUpgrade, tabId = getCurrentTabId(),
} = payload; } = payload;
const inputInvoice: ApiInputInvoiceStarGift = { const inputInvoice: ApiInputInvoiceStarGift = {
type: 'stargift', type: 'stargift',
userId, peerId,
giftId: gift.id, giftId: gift.id,
message, message,
shouldHideName, shouldHideName,
@ -520,7 +521,7 @@ addActionHandler('openGiftModal', async (global, actions, payload): Promise<void
global = getGlobal(); global = getGlobal();
global = updateTabState(global, { global = updateTabState(global, {
giftModal: { giftModal: {
forUserId, forPeerId: forUserId,
gifts, gifts,
}, },
}, tabId); }, tabId);
@ -956,9 +957,14 @@ addActionHandler('launchPrepaidStarsGiveaway', async (global, actions, payload):
addActionHandler('upgradeGift', (global, actions, payload): ActionReturnType => { addActionHandler('upgradeGift', (global, actions, payload): ActionReturnType => {
const { const {
messageId, shouldKeepOriginalDetails, upgradeStars, tabId = getCurrentTabId(), gift, shouldKeepOriginalDetails, upgradeStars, tabId = getCurrentTabId(),
} = payload; } = payload;
const requestSavedGift = getRequestInputSavedStarGift(global, gift);
if (!requestSavedGift) {
return;
}
global = updateTabState(global, { global = updateTabState(global, {
isWaitingForStarGiftUpgrade: true, isWaitingForStarGiftUpgrade: true,
}, tabId); }, tabId);
@ -971,7 +977,7 @@ addActionHandler('upgradeGift', (global, actions, payload): ActionReturnType =>
if (!upgradeStars) { if (!upgradeStars) {
callApi('upgradeGift', { callApi('upgradeGift', {
messageId, inputSavedGift: requestSavedGift,
shouldKeepOriginalDetails: shouldKeepOriginalDetails || undefined, shouldKeepOriginalDetails: shouldKeepOriginalDetails || undefined,
}); });
@ -980,7 +986,7 @@ addActionHandler('upgradeGift', (global, actions, payload): ActionReturnType =>
const invoice: ApiInputInvoiceStarGiftUpgrade = { const invoice: ApiInputInvoiceStarGiftUpgrade = {
type: 'stargiftUpgrade', type: 'stargiftUpgrade',
messageId, inputSavedGift: gift,
shouldKeepOriginalDetails: shouldKeepOriginalDetails || undefined, shouldKeepOriginalDetails: shouldKeepOriginalDetails || undefined,
}; };

View File

@ -1,21 +1,21 @@
import type { ApiUserStarGift } from '../../../api/types'; import type { ApiSavedStarGift } from '../../../api/types';
import type { StarGiftCategory } from '../../../types'; import type { StarGiftCategory } from '../../../types';
import { getCurrentTabId } from '../../../util/establishMultitabRole'; import { getCurrentTabId } from '../../../util/establishMultitabRole';
import { buildCollectionByKey } from '../../../util/iteratees'; import { buildCollectionByKey } from '../../../util/iteratees';
import { callApi } from '../../../api/gramjs'; import { callApi } from '../../../api/gramjs';
import { areInputSavedGiftsEqual, getRequestInputSavedStarGift } from '../../helpers/payments';
import { addActionHandler, getGlobal, setGlobal } from '../../index'; import { addActionHandler, getGlobal, setGlobal } from '../../index';
import { import {
appendStarsSubscriptions, appendStarsSubscriptions,
appendStarsTransactions, appendStarsTransactions,
replaceUserGifts, replacePeerSavedGifts,
updateStarsBalance, updateStarsBalance,
updateStarsSubscriptionLoading, updateStarsSubscriptionLoading,
} from '../../reducers'; } from '../../reducers';
import { updateTabState } from '../../reducers/tabs'; import { updateTabState } from '../../reducers/tabs';
import { import {
selectPeer, selectPeer,
selectUser,
} from '../../selectors'; } from '../../selectors';
addActionHandler('loadStarStatus', async (global): Promise<void> => { addActionHandler('loadStarStatus', async (global): Promise<void> => {
@ -133,19 +133,19 @@ addActionHandler('loadStarGifts', async (global): Promise<void> => {
setGlobal(global); setGlobal(global);
}); });
addActionHandler('loadUserGifts', async (global, actions, payload): Promise<void> => { addActionHandler('loadPeerSavedGifts', async (global, actions, payload): Promise<void> => {
const { userId, shouldRefresh } = payload; const { peerId, shouldRefresh } = payload;
const user = selectUser(global, userId); const peer = selectPeer(global, peerId);
if (!user) return; if (!peer) return;
const currentGifts = global.users.giftsById[userId]; const currentGifts = global.peers.giftsById[peerId];
const localNextOffset = currentGifts?.nextOffset; const localNextOffset = currentGifts?.nextOffset;
if (!shouldRefresh && currentGifts && !localNextOffset) return; // Already loaded all if (!shouldRefresh && currentGifts && !localNextOffset) return; // Already loaded all
const result = await callApi('fetchUserStarGifts', { const result = await callApi('fetchSavedStarGifts', {
user, peer,
offset: !shouldRefresh ? localNextOffset : '', offset: !shouldRefresh ? localNextOffset : '',
}); });
@ -157,7 +157,7 @@ addActionHandler('loadUserGifts', async (global, actions, payload): Promise<void
const newGifts = currentGifts && !shouldRefresh ? currentGifts.gifts.concat(result.gifts) : result.gifts; const newGifts = currentGifts && !shouldRefresh ? currentGifts.gifts.concat(result.gifts) : result.gifts;
global = replaceUserGifts(global, userId, newGifts, result.nextOffset); global = replacePeerSavedGifts(global, peerId, newGifts, result.nextOffset);
setGlobal(global); setGlobal(global);
}); });
@ -216,53 +216,59 @@ addActionHandler('fulfillStarsSubscription', async (global, actions, payload): P
}); });
addActionHandler('changeGiftVisibility', async (global, actions, payload): Promise<void> => { addActionHandler('changeGiftVisibility', async (global, actions, payload): Promise<void> => {
const { messageId, shouldUnsave } = payload; const { gift, shouldUnsave } = payload;
const currentUserId = global.currentUserId!; const peerId = gift.type === 'user' ? global.currentUserId! : gift.chatId;
const oldGifts = global.users.giftsById[currentUserId]; const requestInputGift = getRequestInputSavedStarGift(global, gift);
if (!requestInputGift) return;
const oldGifts = global.peers.giftsById[peerId];
if (oldGifts?.gifts?.length) { if (oldGifts?.gifts?.length) {
const newGifts = oldGifts.gifts.map((gift) => { const newGifts = oldGifts.gifts.map((g) => {
if (gift.messageId === messageId) { if (g.inputGift && areInputSavedGiftsEqual(g.inputGift, gift)) {
return { return {
...gift, ...g,
isUnsaved: shouldUnsave, isUnsaved: shouldUnsave,
} satisfies ApiUserStarGift; } satisfies ApiSavedStarGift;
} }
return gift; return g;
}); });
global = replaceUserGifts(global, currentUserId, newGifts, oldGifts.nextOffset); global = replacePeerSavedGifts(global, peerId, newGifts, oldGifts.nextOffset);
setGlobal(global); setGlobal(global);
} }
const result = await callApi('saveStarGift', { const result = await callApi('saveStarGift', {
messageId, inputGift: requestInputGift,
shouldUnsave, shouldUnsave,
}); });
global = getGlobal(); global = getGlobal();
if (!result) { if (!result) {
global = replaceUserGifts(global, currentUserId, oldGifts.gifts, oldGifts.nextOffset); global = replacePeerSavedGifts(global, peerId, oldGifts.gifts, oldGifts.nextOffset);
setGlobal(global); setGlobal(global);
return; return;
} }
// Reload gift list to avoid issues with pagination // Reload gift list to avoid issues with pagination
actions.loadUserGifts({ userId: currentUserId, shouldRefresh: true }); actions.loadPeerSavedGifts({ peerId, shouldRefresh: true });
}); });
addActionHandler('convertGiftToStars', async (global, actions, payload): Promise<void> => { addActionHandler('convertGiftToStars', async (global, actions, payload): Promise<void> => {
const { messageId, tabId = getCurrentTabId() } = payload; const { gift, tabId = getCurrentTabId() } = payload;
const requestInputGift = getRequestInputSavedStarGift(global, gift);
if (!requestInputGift) return;
const result = await callApi('convertStarGift', { const result = await callApi('convertStarGift', {
messageId, inputSavedGift: requestInputGift,
}); });
if (!result) { if (!result) {
return; return;
} }
actions.loadUserGifts({ userId: global.currentUserId!, shouldRefresh: true }); actions.loadPeerSavedGifts({ peerId: global.currentUserId!, shouldRefresh: true });
actions.openStarsBalanceModal({ tabId }); actions.openStarsBalanceModal({ tabId });
}); });

View File

@ -1,6 +1,7 @@
import type { ActionReturnType } from '../../types'; import type { ActionReturnType } from '../../types';
import { PaymentStep } from '../../../types'; import { PaymentStep } from '../../../types';
import { SERVICE_NOTIFICATIONS_USER_ID } from '../../../config';
import { applyLangPackDifference, requestLangPackDifference } from '../../../util/localization'; import { applyLangPackDifference, requestLangPackDifference } from '../../../util/localization';
import { addActionHandler, setGlobal } from '../../index'; import { addActionHandler, setGlobal } from '../../index';
import { import {
@ -211,9 +212,9 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
case 'newMessage': { case 'newMessage': {
const actionStarGift = update.message.content?.action?.starGift; const actionStarGift = update.message.content?.action?.starGift;
if (actionStarGift?.type !== 'starGiftUnique' || !update.message.isOutgoing) { if (!update.message.isOutgoing && update.message.chatId !== SERVICE_NOTIFICATIONS_USER_ID) return undefined;
return undefined; if (actionStarGift?.type !== 'starGiftUnique') return undefined;
}
Object.values(global.byTabId).forEach(({ id: tabId }) => { Object.values(global.byTabId).forEach(({ id: tabId }) => {
const tabState = selectTabState(global, tabId); const tabState = selectTabState(global, tabId);
if (tabState.isWaitingForStarGiftUpgrade) { if (tabState.isWaitingForStarGiftUpgrade) {

View File

@ -76,7 +76,7 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
} }
const giftModalState = selectTabState(global, tabId).giftModal; const giftModalState = selectTabState(global, tabId).giftModal;
if (giftModalState && inputInvoice.userIds[0] === giftModalState.forUserId) { if (giftModalState && inputInvoice.userIds[0] === giftModalState.forPeerId) {
global = updateTabState(global, { global = updateTabState(global, {
giftModal: { giftModal: {
...giftModalState, ...giftModalState,

View File

@ -1,4 +1,4 @@
import type { ApiMessageActionStarGift, ApiUserStarGift } from '../../../api/types'; import type { ApiMessageActionStarGift, ApiSavedStarGift } from '../../../api/types';
import type { ActionReturnType } from '../../types'; import type { ActionReturnType } from '../../types';
import { getCurrentTabId } from '../../../util/establishMultitabRole'; import { getCurrentTabId } from '../../../util/establishMultitabRole';
@ -266,9 +266,10 @@ addActionHandler('openGiftInfoModalFromMessage', (global, actions, payload): Act
upgradeMsgId: starGift.upgradeMsgId, upgradeMsgId: starGift.upgradeMsgId,
canUpgrade: starGift.canUpgrade, canUpgrade: starGift.canUpgrade,
alreadyPaidUpgradeStars: starGift.alreadyPaidUpgradeStars, alreadyPaidUpgradeStars: starGift.alreadyPaidUpgradeStars,
} satisfies ApiUserStarGift; inputGift: starGift.inputSavedGift,
} satisfies ApiSavedStarGift;
actions.openGiftInfoModal({ userId: giftReceiverId, gift, tabId }); actions.openGiftInfoModal({ peerId: giftReceiverId, gift, tabId });
}); });
addActionHandler('openGiftInfoModal', (global, actions, payload): ActionReturnType => { addActionHandler('openGiftInfoModal', (global, actions, payload): ActionReturnType => {
@ -276,11 +277,11 @@ addActionHandler('openGiftInfoModal', (global, actions, payload): ActionReturnTy
gift, tabId = getCurrentTabId(), gift, tabId = getCurrentTabId(),
} = payload; } = payload;
const userId = 'userId' in payload ? payload.userId : undefined; const peerId = 'peerId' in payload ? payload.peerId : undefined;
return updateTabState(global, { return updateTabState(global, {
giftInfoModal: { giftInfoModal: {
userId, peerId,
gift, gift,
}, },
}, tabId); }, tabId);

View File

@ -4,10 +4,7 @@ import { addCallback, removeCallback } from '../lib/teact/teactn';
import type { import type {
ApiAvailableReaction, ApiAvailableReaction,
ApiBotPreviewMedia,
ApiMessage, ApiMessage,
ApiUserCommonChats,
ApiUserGifts,
} from '../api/types'; } from '../api/types';
import type { MessageList, ThreadId } from '../types'; import type { MessageList, ThreadId } from '../types';
import type { ActionReturnType, GlobalState } from './types'; import type { ActionReturnType, GlobalState } from './types';
@ -276,6 +273,10 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) {
if (!cached.settings.botVerificationShownPeerIds) { if (!cached.settings.botVerificationShownPeerIds) {
cached.settings.botVerificationShownPeerIds = initialState.settings.botVerificationShownPeerIds; cached.settings.botVerificationShownPeerIds = initialState.settings.botVerificationShownPeerIds;
} }
if (!cached.peers) {
cached.peers = initialState.peers;
}
} }
function updateCache(force?: boolean) { function updateCache(force?: boolean) {
@ -386,15 +387,7 @@ function reduceCustomEmojis<T extends GlobalState>(global: T): GlobalState['cust
}; };
} }
function reduceUsers<T extends GlobalState>(global: T): { function reduceUsers<T extends GlobalState>(global: T): GlobalState['users'] {
commonChatsById: Record<string, ApiUserCommonChats>;
giftsById: Record<string, ApiUserGifts>;
botAppPermissionsById: any;
statusesById: any;
fullInfoById: any;
byId: any;
previewMediaByBotId: Record<string, ApiBotPreviewMedia[]>;
} {
const { const {
users: { users: {
byId, statusesById, fullInfoById, botAppPermissionsById, byId, statusesById, fullInfoById, botAppPermissionsById,

View File

@ -34,7 +34,7 @@ import { getGlobal } from '../index';
import { import {
getChatTitle, getCleanPeerId, isPeerUser, isUserId, getChatTitle, getCleanPeerId, isPeerUser, isUserId,
} from './chats'; } from './chats';
import { getMainUsername, getUserFullName } from './users'; import { getMainUsername, getUserFirstOrLastName, getUserFullName } from './users';
const RE_LINK = new RegExp(RE_LINK_TEMPLATE, 'i'); const RE_LINK = new RegExp(RE_LINK_TEMPLATE, 'i');
@ -210,6 +210,16 @@ export function isAnonymousOwnMessage(message: ApiMessage) {
} }
export function getPeerTitle(lang: OldLangFn | LangFn, peer: ApiPeer | CustomPeer) { export function getPeerTitle(lang: OldLangFn | LangFn, peer: ApiPeer | CustomPeer) {
if (!peer) return undefined;
if ('isCustomPeer' in peer) {
// TODO: Remove any after full migration to new lang
return peer.titleKey ? lang(peer.titleKey as any) : peer.title;
}
return isPeerUser(peer) ? getUserFirstOrLastName(peer) : getChatTitle(lang, peer);
}
export function getPeerFullTitle(lang: OldLangFn | LangFn, peer: ApiPeer | CustomPeer) {
if (!peer) return undefined;
if ('isCustomPeer' in peer) { if ('isCustomPeer' in peer) {
// TODO: Remove any after full migration to new lang // TODO: Remove any after full migration to new lang
return peer.titleKey ? lang(peer.titleKey as any) : peer.title; return peer.titleKey ? lang(peer.titleKey as any) : peer.title;

View File

@ -1,7 +1,9 @@
import type { import type {
ApiInputInvoice, ApiInputInvoice,
ApiInputSavedStarGift,
ApiMessage, ApiMessage,
ApiRequestInputInvoice, ApiRequestInputInvoice,
ApiRequestInputSavedStarGift,
ApiStarsAmount, ApiStarsAmount,
ApiStarsTransaction, ApiStarsTransaction,
ApiStarsTransactionPeer, ApiStarsTransactionPeer,
@ -11,7 +13,8 @@ import type { CustomPeer } from '../../types';
import type { LangFn } from '../../util/localization'; import type { LangFn } from '../../util/localization';
import type { GlobalState } from '../types'; import type { GlobalState } from '../types';
import { selectChat, selectUser } from '../selectors'; import arePropsShallowEqual from '../../util/arePropsShallowEqual';
import { selectChat, selectPeer, selectUser } from '../selectors';
export function getRequestInputInvoice<T extends GlobalState>( export function getRequestInputInvoice<T extends GlobalState>(
global: T, inputInvoice: ApiInputInvoice, global: T, inputInvoice: ApiInputInvoice,
@ -20,15 +23,15 @@ export function getRequestInputInvoice<T extends GlobalState>(
if (inputInvoice.type === 'stargift') { if (inputInvoice.type === 'stargift') {
const { const {
userId, shouldHideName, giftId, message, shouldUpgrade, peerId, shouldHideName, giftId, message, shouldUpgrade,
} = inputInvoice; } = inputInvoice;
const user = selectUser(global, userId); const peer = selectPeer(global, peerId);
if (!user) return undefined; if (!peer) return undefined;
return { return {
type: 'stargift', type: 'stargift',
user, peer,
shouldHideName, shouldHideName,
giftId, giftId,
message, message,
@ -174,10 +177,13 @@ export function getRequestInputInvoice<T extends GlobalState>(
} }
if (inputInvoice.type === 'stargiftUpgrade') { if (inputInvoice.type === 'stargiftUpgrade') {
const { messageId, shouldKeepOriginalDetails } = inputInvoice; const { inputSavedGift, shouldKeepOriginalDetails } = inputInvoice;
const savedGift = getRequestInputSavedStarGift(global, inputSavedGift);
if (!savedGift) return undefined;
return { return {
type: 'stargiftUpgrade', type: 'stargiftUpgrade',
messageId, inputSavedGift: savedGift,
shouldKeepOriginalDetails, shouldKeepOriginalDetails,
}; };
} }
@ -185,6 +191,25 @@ export function getRequestInputInvoice<T extends GlobalState>(
return undefined; return undefined;
} }
export function getRequestInputSavedStarGift<T extends GlobalState>(
global: T, inputGift: ApiInputSavedStarGift,
): ApiRequestInputSavedStarGift | undefined {
if (inputGift.type === 'user') return inputGift;
if (inputGift.type === 'chat') {
const chat = selectChat(global, inputGift.chatId);
if (!chat) return undefined;
return {
type: 'chat',
chat,
savedId: inputGift.savedId,
};
}
return undefined;
}
export function buildStarsTransactionCustomPeer( export function buildStarsTransactionCustomPeer(
peer: Exclude<ApiStarsTransactionPeer, ApiStarsTransactionPeerPeer>, peer: Exclude<ApiStarsTransactionPeer, ApiStarsTransactionPeerPeer>,
): CustomPeer { ): CustomPeer {
@ -315,3 +340,7 @@ export function getPrizeStarsTransactionFromGiveaway(message: ApiMessage): ApiSt
giveawayPostId: message.id, giveawayPostId: message.id,
}; };
} }
export function areInputSavedGiftsEqual(one: ApiInputSavedStarGift, two: ApiInputSavedStarGift) {
return arePropsShallowEqual(one, two);
}

View File

@ -102,10 +102,14 @@ export const INITIAL_GLOBAL_STATE: GlobalState = {
fullInfoById: {}, fullInfoById: {},
previewMediaByBotId: {}, previewMediaByBotId: {},
commonChatsById: {}, commonChatsById: {},
giftsById: {},
botAppPermissionsById: {}, botAppPermissionsById: {},
}, },
peers: {
giftsById: {},
profilePhotosById: {},
},
chats: { chats: {
listIds: {}, listIds: {},
isFullyLoaded: {}, isFullyLoaded: {},
@ -310,7 +314,6 @@ export const INITIAL_GLOBAL_STATE: GlobalState = {
isHidden: false, isHidden: false,
}, },
profilePhotosById: {},
monetizationInfo: {}, monetizationInfo: {},
}; };

View File

@ -62,15 +62,21 @@ export function replacePeerPhotos<T extends GlobalState>(
if (!value) { if (!value) {
return { return {
...global, ...global,
profilePhotosById: omit(global.profilePhotosById, [peerId]), peers: {
...global.peers,
profilePhotosById: omit(global.peers.profilePhotosById, [peerId]),
},
}; };
} }
return { return {
...global, ...global,
profilePhotosById: { peers: {
...global.profilePhotosById, ...global.peers,
[peerId]: value, profilePhotosById: {
...global.peers.profilePhotosById,
[peerId]: value,
},
}, },
}; };
} }

View File

@ -1,9 +1,9 @@
import type { import type {
ApiMissingInvitedUser, ApiMissingInvitedUser,
ApiSavedStarGift,
ApiUser, ApiUser,
ApiUserCommonChats, ApiUserCommonChats,
ApiUserFullInfo, ApiUserFullInfo,
ApiUserStarGift,
ApiUserStatus, ApiUserStatus,
} from '../../api/types'; } from '../../api/types';
import type { BotAppPermissions } from '../../types'; import type { BotAppPermissions } from '../../types';
@ -324,19 +324,19 @@ export function updateBotAppPermissions<T extends GlobalState>(
}; };
} }
export function replaceUserGifts<T extends GlobalState>( export function replacePeerSavedGifts<T extends GlobalState>(
global: T, global: T,
userId: string, peerId: string,
gifts: ApiUserStarGift[], gifts: ApiSavedStarGift[],
nextOffset?: string, nextOffset?: string,
): T { ): T {
global = { global = {
...global, ...global,
users: { peers: {
...global.users, ...global.peers,
giftsById: { giftsById: {
...global.users.giftsById, ...global.peers.giftsById,
[userId]: { [peerId]: {
gifts, gifts,
nextOffset, nextOffset,
}, },

View File

@ -1,13 +1,25 @@
import type { ApiPeer } from '../../api/types'; import type { ApiPeer } from '../../api/types';
import type { GlobalState } from '../types'; import type { GlobalState } from '../types';
import { selectChat } from './chats'; import { SERVICE_NOTIFICATIONS_USER_ID } from '../../config';
import { selectUser } from './users'; import { selectChat, selectChatFullInfo } from './chats';
import { selectBot, selectIsPremiumPurchaseBlocked, selectUser } from './users';
export function selectPeer<T extends GlobalState>(global: T, peerId: string): ApiPeer | undefined { export function selectPeer<T extends GlobalState>(global: T, peerId: string): ApiPeer | undefined {
return selectUser(global, peerId) || selectChat(global, peerId); return selectUser(global, peerId) || selectChat(global, peerId);
} }
export function selectPeerPhotos<T extends GlobalState>(global: T, peerId: string) { export function selectPeerPhotos<T extends GlobalState>(global: T, peerId: string) {
return global.profilePhotosById[peerId]; return global.peers.profilePhotosById[peerId];
}
export function selectCanGift<T extends GlobalState>(global: T, peerId: string) {
const bot = selectBot(global, peerId);
const user = selectUser(global, peerId);
const chat = selectChat(global, peerId);
const areStarGiftsAvailable = chat ? selectChatFullInfo(global, peerId)?.areStarGiftsAvailable : user;
return Boolean(!selectIsPremiumPurchaseBlocked(global) && !bot && peerId !== SERVICE_NOTIFICATIONS_USER_ID
&& areStarGiftsAvailable);
} }

View File

@ -5,7 +5,6 @@ import type {
import type { BotAppPermissions } from '../../types'; import type { BotAppPermissions } from '../../types';
import type { GlobalState } from '../types'; import type { GlobalState } from '../types';
import { SERVICE_NOTIFICATIONS_USER_ID } from '../../config';
import { isUserBot } from '../helpers'; import { isUserBot } from '../helpers';
export function selectUser<T extends GlobalState>(global: T, userId: string): ApiUser | undefined { export function selectUser<T extends GlobalState>(global: T, userId: string): ApiUser | undefined {
@ -62,14 +61,6 @@ export function selectBot<T extends GlobalState>(global: T, userId: string): Api
return user; return user;
} }
export function selectCanGift<T extends GlobalState>(global: T, userId: string) {
const bot = selectBot(global, userId);
const user = selectUser(global, userId);
return !selectIsPremiumPurchaseBlocked(global) && user && !bot
&& !user.isSelf && userId !== SERVICE_NOTIFICATIONS_USER_ID;
}
export function selectBotAppPermissions<T extends GlobalState>( export function selectBotAppPermissions<T extends GlobalState>(
global: T, userId: string, global: T, userId: string,
): BotAppPermissions | undefined { ): BotAppPermissions | undefined {

View File

@ -17,6 +17,7 @@ import type {
ApiInputInvoice, ApiInputInvoice,
ApiInputInvoiceStarGift, ApiInputInvoiceStarGift,
ApiInputMessageReplyInfo, ApiInputMessageReplyInfo,
ApiInputSavedStarGift,
ApiKeyboardButton, ApiKeyboardButton,
ApiLimitTypeWithModal, ApiLimitTypeWithModal,
ApiMessage, ApiMessage,
@ -32,6 +33,7 @@ import type {
ApiReaction, ApiReaction,
ApiReactionWithPaid, ApiReactionWithPaid,
ApiReportReason, ApiReportReason,
ApiSavedStarGift,
ApiSendMessageAction, ApiSendMessageAction,
ApiSessionData, ApiSessionData,
ApiStarGift, ApiStarGift,
@ -44,7 +46,6 @@ import type {
ApiTypePrepaidGiveaway, ApiTypePrepaidGiveaway,
ApiUpdate, ApiUpdate,
ApiUser, ApiUser,
ApiUserStarGift,
ApiVideo, ApiVideo,
BotsPrivacyType, BotsPrivacyType,
PrivacyVisibility, PrivacyVisibility,
@ -2305,8 +2306,8 @@ export interface ActionPayloads {
messageId: number; messageId: number;
} & WithTabId; } & WithTabId;
openGiftInfoModal: ({ openGiftInfoModal: ({
userId: string; peerId: string;
gift: ApiUserStarGift; gift: ApiSavedStarGift;
} | { } | {
gift: ApiStarGift; gift: ApiStarGift;
}) & WithTabId; }) & WithTabId;
@ -2314,24 +2315,24 @@ export interface ActionPayloads {
openGiftUpgradeModal: { openGiftUpgradeModal: {
giftId: string; giftId: string;
peerId?: string; peerId?: string;
gift?: ApiUserStarGift; gift?: ApiSavedStarGift;
} & WithTabId; } & WithTabId;
closeGiftUpgradeModal: WithTabId | undefined; closeGiftUpgradeModal: WithTabId | undefined;
upgradeGift: { upgradeGift: {
messageId: number; gift: ApiInputSavedStarGift;
shouldKeepOriginalDetails?: boolean; shouldKeepOriginalDetails?: boolean;
upgradeStars?: number; upgradeStars?: number;
} & WithTabId; } & WithTabId;
loadUserGifts: { loadPeerSavedGifts: {
userId: string; peerId: string;
shouldRefresh?: boolean; shouldRefresh?: boolean;
}; };
changeGiftVisibility: { changeGiftVisibility: {
messageId: number; gift: ApiInputSavedStarGift;
shouldUnsave?: boolean; shouldUnsave?: boolean;
}; };
convertGiftToStars: { convertGiftToStars: {
messageId: number; gift: ApiInputSavedStarGift;
} & WithTabId; } & WithTabId;
openStarsGiftModal: ({ openStarsGiftModal: ({

View File

@ -24,6 +24,7 @@ import type {
ApiQuickReply, ApiQuickReply,
ApiReaction, ApiReaction,
ApiReactionKey, ApiReactionKey,
ApiSavedGifts,
ApiSavedReactionTag, ApiSavedReactionTag,
ApiSession, ApiSession,
ApiSponsoredMessage, ApiSponsoredMessage,
@ -40,7 +41,6 @@ import type {
ApiUser, ApiUser,
ApiUserCommonChats, ApiUserCommonChats,
ApiUserFullInfo, ApiUserFullInfo,
ApiUserGifts,
ApiUserStatus, ApiUserStatus,
ApiVideo, ApiVideo,
ApiWallpaper, ApiWallpaper,
@ -176,10 +176,13 @@ export type GlobalState = {
fullInfoById: Record<string, ApiUserFullInfo>; fullInfoById: Record<string, ApiUserFullInfo>;
previewMediaByBotId: Record<string, ApiBotPreviewMedia[]>; previewMediaByBotId: Record<string, ApiBotPreviewMedia[]>;
commonChatsById: Record<string, ApiUserCommonChats>; commonChatsById: Record<string, ApiUserCommonChats>;
giftsById: Record<string, ApiUserGifts>;
botAppPermissionsById: Record<string, BotAppPermissions>; botAppPermissionsById: Record<string, BotAppPermissions>;
}; };
profilePhotosById: Record<string, ApiPeerPhotos>;
peers: {
profilePhotosById: Record<string, ApiPeerPhotos>;
giftsById: Record<string, ApiSavedGifts>;
};
chats: { chats: {
// TODO Replace with `Partial<Record>` to properly handle missing keys // TODO Replace with `Partial<Record>` to properly handle missing keys

View File

@ -32,6 +32,7 @@ import type {
ApiPremiumSection, ApiPremiumSection,
ApiReactionWithPaid, ApiReactionWithPaid,
ApiReceiptRegular, ApiReceiptRegular,
ApiSavedStarGift,
ApiStarGift, ApiStarGift,
ApiStarGiftAttribute, ApiStarGiftAttribute,
ApiStarGiveawayOption, ApiStarGiveawayOption,
@ -42,7 +43,6 @@ import type {
ApiTypePrepaidGiveaway, ApiTypePrepaidGiveaway,
ApiTypeStoryView, ApiTypeStoryView,
ApiUser, ApiUser,
ApiUserStarGift,
ApiVideo, ApiVideo,
ApiWebPage, ApiWebPage,
} from '../../api/types'; } from '../../api/types';
@ -603,8 +603,8 @@ export type TabState = {
giftModal?: { giftModal?: {
isCompleted?: boolean; isCompleted?: boolean;
forUserId: string; forPeerId: string;
gifts: ApiPremiumGiftCodeOption[]; gifts?: ApiPremiumGiftCodeOption[];
}; };
limitReachedModal?: { limitReachedModal?: {
@ -710,14 +710,14 @@ export type TabState = {
}; };
giftInfoModal?: { giftInfoModal?: {
userId?: string; peerId?: string;
gift: ApiUserStarGift | ApiStarGift; gift: ApiSavedStarGift | ApiStarGift;
}; };
giftUpgradeModal?: { giftUpgradeModal?: {
sampleAttributes: ApiStarGiftAttribute[]; sampleAttributes: ApiStarGiftAttribute[];
recipientId?: string; recipientId?: string;
gift?: ApiUserStarGift; gift?: ApiSavedStarGift;
}; };
suggestedStatusModal?: { suggestedStatusModal?: {

View File

@ -12,5 +12,5 @@ for (const tl of Object.values(Api)) {
} }
} }
export const LAYER = 197; export const LAYER = 198;
export { tlobjects }; export { tlobjects };

File diff suppressed because one or more lines are too long

View File

@ -24,11 +24,11 @@ inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile sti
inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia; inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia; inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia; inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia; inputMediaUploadedDocument#37c9330 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> video_cover:flags.6?InputPhoto video_timestamp:flags.7?int ttl_seconds:flags.1?int = InputMedia;
inputMediaDocument#33473058 flags:# spoiler:flags.2?true id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia; inputMediaDocument#a8763ab5 flags:# spoiler:flags.2?true id:InputDocument video_cover:flags.3?InputPhoto video_timestamp:flags.4?int ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia; inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia; inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaDocumentExternal#fb52dc99 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia; inputMediaDocumentExternal#779600f9 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int video_cover:flags.2?InputPhoto video_timestamp:flags.3?int = InputMedia;
inputMediaGame#d33f43f3 id:InputGame = InputMedia; inputMediaGame#d33f43f3 id:InputGame = InputMedia;
inputMediaInvoice#405fef0d flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:flags.3?string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia; inputMediaInvoice#405fef0d flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:flags.3?string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia; inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
@ -83,7 +83,7 @@ chatForbidden#6592a1a7 id:long title:string = Chat;
channel#e00998b7 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector<Username> stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long = Chat; channel#e00998b7 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector<Username> stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long = Chat;
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull; chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull;
channelFull#9ff3b858 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification = ChatFull; channelFull#52d6806b flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
chatParticipantAdmin#a0933f5b user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantAdmin#a0933f5b user_id:long inviter_id:long date:int = ChatParticipant;
@ -99,7 +99,7 @@ messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia; messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia; messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia;
messageMediaUnsupported#9f84f49e = MessageMedia; messageMediaUnsupported#9f84f49e = MessageMedia;
messageMediaDocument#dd570bd5 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector<Document> ttl_seconds:flags.2?int = MessageMedia; messageMediaDocument#52d8ccd9 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector<Document> video_cover:flags.9?Photo video_timestamp:flags.10?int ttl_seconds:flags.2?int = MessageMedia;
messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia; messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia;
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia; messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
messageMediaGame#fdb19008 game:Game = MessageMedia; messageMediaGame#fdb19008 game:Game = MessageMedia;
@ -157,8 +157,8 @@ messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector<RequestedPe
messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction; messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction;
messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction; messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction;
messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction; messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction;
messageActionStarGift#d8f4f0a7 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long = MessageAction; messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
messageActionStarGiftUnique#26077b99 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long = MessageAction; messageActionStarGiftUnique#acdfcb81 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long = MessageAction;
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
photoEmpty#2331b22d id:long = Photo; photoEmpty#2331b22d id:long = Photo;
@ -1124,9 +1124,9 @@ inputInvoiceSlug#c326caef slug:string = InputInvoice;
inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice; inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice;
inputInvoiceStars#65f00ce3 purpose:InputStorePaymentPurpose = InputInvoice; inputInvoiceStars#65f00ce3 purpose:InputStorePaymentPurpose = InputInvoice;
inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice; inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice;
inputInvoiceStarGift#25d8c1d8 flags:# hide_name:flags.0?true include_upgrade:flags.2?true user_id:InputUser gift_id:long message:flags.1?TextWithEntities = InputInvoice; inputInvoiceStarGift#e8625e92 flags:# hide_name:flags.0?true include_upgrade:flags.2?true peer:InputPeer gift_id:long message:flags.1?TextWithEntities = InputInvoice;
inputInvoiceStarGiftUpgrade#5ebe7262 flags:# keep_original_details:flags.0?true msg_id:int = InputInvoice; inputInvoiceStarGiftUpgrade#4d818d5d flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = InputInvoice;
inputInvoiceStarGiftTransfer#ae3ba9ed msg_id:int to_id:InputUser = InputInvoice; inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPeer = InputInvoice;
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
messages.transcribedAudio#cfb9d957 flags:# pending:flags.0?true transcription_id:long text:string trial_remains_num:flags.1?int trial_remains_until_date:flags.1?int = messages.TranscribedAudio; messages.transcribedAudio#cfb9d957 flags:# pending:flags.0?true transcription_id:long text:string trial_remains_num:flags.1?int trial_remains_until_date:flags.1?int = messages.TranscribedAudio;
help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> period_options:Vector<PremiumSubscriptionOption> users:Vector<User> = help.PremiumPromo; help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> period_options:Vector<PremiumSubscriptionOption> users:Vector<User> = help.PremiumPromo;
@ -1140,8 +1140,9 @@ inputStorePaymentStarsGiveaway#751f08fa flags:# only_new_subscribers:flags.0?tru
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod; paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
emojiStatusEmpty#2de11aae = EmojiStatus; emojiStatusEmpty#2de11aae = EmojiStatus;
emojiStatus#929b619d document_id:long = EmojiStatus; emojiStatus#e7ff068a flags:# document_id:long until:flags.0?int = EmojiStatus;
emojiStatusUntil#fa30a8c7 document_id:long until:int = EmojiStatus; emojiStatusCollectible#7184603b flags:# collectible_id:long document_id:long title:string slug:string pattern_document_id:long center_color:int edge_color:int pattern_color:int text_color:int until:flags.0?int = EmojiStatus;
inputEmojiStatusCollectible#7141dbf flags:# collectible_id:long until:flags.0?int = EmojiStatus;
account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses; account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses;
account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses; account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses;
reactionEmpty#79f5d419 = Reaction; reactionEmpty#79f5d419 = Reaction;
@ -1366,11 +1367,9 @@ messageReactor#4ba3a95a flags:# top:flags.0?true my:flags.1?true anonymous:flags
starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true stars:long yearly_boosts:int store_product:flags.2?string currency:string amount:long winners:Vector<StarsGiveawayWinnersOption> = StarsGiveawayOption; starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true stars:long yearly_boosts:int store_product:flags.2?string currency:string amount:long winners:Vector<StarsGiveawayWinnersOption> = StarsGiveawayOption;
starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption; starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption;
starGift#2cc73c8 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long = StarGift; starGift#2cc73c8 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long = StarGift;
starGiftUnique#3482f322 flags:# id:long title:string slug:string num:int owner_id:flags.0?long owner_name:flags.1?string attributes:Vector<StarGiftAttribute> availability_issued:int availability_total:int = StarGift; starGiftUnique#f2fe7e4a flags:# id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector<StarGiftAttribute> availability_issued:int availability_total:int = StarGift;
payments.starGiftsNotModified#a388a368 = payments.StarGifts; payments.starGiftsNotModified#a388a368 = payments.StarGifts;
payments.starGifts#901689ea hash:int gifts:Vector<StarGift> = payments.StarGifts; payments.starGifts#901689ea hash:int gifts:Vector<StarGift> = payments.StarGifts;
userStarGift#325835e1 flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true from_id:flags.1?long date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long = UserStarGift;
payments.userStarGifts#6b65b517 flags:# count:int gifts:Vector<UserStarGift> next_offset:flags.0?string users:Vector<User> = payments.UserStarGifts;
messageReportOption#7903e3d9 text:string option:bytes = MessageReportOption; messageReportOption#7903e3d9 text:string option:bytes = MessageReportOption;
reportResultChooseOption#f0e4e0b6 title:string options:Vector<MessageReportOption> = ReportResult; reportResultChooseOption#f0e4e0b6 title:string options:Vector<MessageReportOption> = ReportResult;
reportResultAddComment#6f09ac31 flags:# optional:flags.0?true option:bytes = ReportResult; reportResultAddComment#6f09ac31 flags:# optional:flags.0?true option:bytes = ReportResult;
@ -1390,12 +1389,17 @@ botVerification#f93cd45c bot_id:long icon:long description:string = BotVerificat
starGiftAttributeModel#39d99013 name:string document:Document rarity_permille:int = StarGiftAttribute; starGiftAttributeModel#39d99013 name:string document:Document rarity_permille:int = StarGiftAttribute;
starGiftAttributePattern#13acff19 name:string document:Document rarity_permille:int = StarGiftAttribute; starGiftAttributePattern#13acff19 name:string document:Document rarity_permille:int = StarGiftAttribute;
starGiftAttributeBackdrop#94271762 name:string center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute; starGiftAttributeBackdrop#94271762 name:string center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute;
starGiftAttributeOriginalDetails#c02c4f4b flags:# sender_id:flags.0?long recipient_id:long date:int message:flags.1?TextWithEntities = StarGiftAttribute; starGiftAttributeOriginalDetails#e0bff26c flags:# sender_id:flags.0?Peer recipient_id:Peer date:int message:flags.1?TextWithEntities = StarGiftAttribute;
payments.starGiftUpgradePreview#167bd90b sample_attributes:Vector<StarGiftAttribute> = payments.StarGiftUpgradePreview; payments.starGiftUpgradePreview#167bd90b sample_attributes:Vector<StarGiftAttribute> = payments.StarGiftUpgradePreview;
users.users#62d706b8 users:Vector<User> = users.Users; users.users#62d706b8 users:Vector<User> = users.Users;
users.usersSlice#315a4974 count:int users:Vector<User> = users.Users; users.usersSlice#315a4974 count:int users:Vector<User> = users.Users;
payments.uniqueStarGift#caa2f60b gift:StarGift users:Vector<User> = payments.UniqueStarGift; payments.uniqueStarGift#caa2f60b gift:StarGift users:Vector<User> = payments.UniqueStarGift;
messages.webPagePreview#b53e8b21 media:MessageMedia users:Vector<User> = messages.WebPagePreview; messages.webPagePreview#b53e8b21 media:MessageMedia users:Vector<User> = messages.WebPagePreview;
savedStarGift#6056dba5 flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true from_id:flags.1?Peer date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int saved_id:flags.11?long convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long = SavedStarGift;
payments.savedStarGifts#95f389b1 flags:# count:int chat_notifications_enabled:flags.1?Bool gifts:Vector<SavedStarGift> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.SavedStarGifts;
inputSavedStarGiftUser#69279795 msg_id:int = InputSavedStarGift;
inputSavedStarGiftChat#f101aa7f peer:InputPeer saved_id:long = InputSavedStarGift;
payments.starGiftWithdrawalUrl#84aa3a9c url:string = payments.StarGiftWithdrawalUrl;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X; initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
@ -1483,7 +1487,7 @@ messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool; messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
messages.sendMessage#983f9745 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates; messages.sendMessage#983f9745 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates;
messages.sendMedia#7852834e flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates; messages.sendMedia#7852834e flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates;
messages.forwardMessages#d5039208 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut = Updates; messages.forwardMessages#6d74da08 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut video_timestamp:flags.20?int = Updates;
messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.reportSpam#cf1592db peer:InputPeer = Bool;
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings; messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult; messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult;
@ -1682,13 +1686,13 @@ channels.getChannelRecommendations#25a71742 flags:# channel:flags.0?InputChannel
channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
bots.setBotInfo#10cf3123 flags:# bot:flags.2?InputUser lang_code:string name:flags.3?string about:flags.0?string description:flags.1?string = Bool; bots.setBotInfo#10cf3123 flags:# bot:flags.2?InputUser lang_code:string name:flags.3?string about:flags.0?string description:flags.1?string = Bool;
bots.canSendMessage#1359f4e6 bot:InputUser = Bool; bots.canSendMessage#1359f4e6 bot:InputUser = Bool;
bots.getBotRecommendations#a1b70815 bot:InputUser = users.Users;
bots.allowSendMessage#f132e3ef bot:InputUser = Updates; bots.allowSendMessage#f132e3ef bot:InputUser = Updates;
bots.invokeWebViewCustomMethod#87fc5e7 bot:InputUser custom_method:string params:DataJSON = DataJSON; bots.invokeWebViewCustomMethod#87fc5e7 bot:InputUser custom_method:string params:DataJSON = DataJSON;
bots.getPopularAppBots#c2510192 offset:string limit:int = bots.PopularAppBots; bots.getPopularAppBots#c2510192 offset:string limit:int = bots.PopularAppBots;
bots.getPreviewMedias#a2a5594d bot:InputUser = Vector<BotPreviewMedia>; bots.getPreviewMedias#a2a5594d bot:InputUser = Vector<BotPreviewMedia>;
bots.toggleUserEmojiStatusPermission#6de6392 bot:InputUser enabled:Bool = Bool; bots.toggleUserEmojiStatusPermission#6de6392 bot:InputUser enabled:Bool = Bool;
bots.checkDownloadFileParams#50077589 bot:InputUser file_name:string url:string = Bool; bots.checkDownloadFileParams#50077589 bot:InputUser file_name:string url:string = Bool;
bots.getBotRecommendations#a1b70815 bot:InputUser = users.Users;
payments.getPaymentForm#37148dbb flags:# invoice:InputInvoice theme_params:flags.0?DataJSON = payments.PaymentForm; payments.getPaymentForm#37148dbb flags:# invoice:InputInvoice theme_params:flags.0?DataJSON = payments.PaymentForm;
payments.getPaymentReceipt#2478d1cc peer:InputPeer msg_id:int = payments.PaymentReceipt; payments.getPaymentReceipt#2478d1cc peer:InputPeer msg_id:int = payments.PaymentReceipt;
payments.validateRequestedInfo#b6c8f12b flags:# save:flags.0?true invoice:InputInvoice info:PaymentRequestedInfo = payments.ValidatedRequestedInfo; payments.validateRequestedInfo#b6c8f12b flags:# save:flags.0?true invoice:InputInvoice info:PaymentRequestedInfo = payments.ValidatedRequestedInfo;
@ -1711,14 +1715,13 @@ payments.changeStarsSubscription#c7770878 flags:# peer:InputPeer subscription_id
payments.fulfillStarsSubscription#cc5bebb3 peer:InputPeer subscription_id:string = Bool; payments.fulfillStarsSubscription#cc5bebb3 peer:InputPeer subscription_id:string = Bool;
payments.getStarsGiveawayOptions#bd1efd3e = Vector<StarsGiveawayOption>; payments.getStarsGiveawayOptions#bd1efd3e = Vector<StarsGiveawayOption>;
payments.getStarGifts#c4563590 hash:int = payments.StarGifts; payments.getStarGifts#c4563590 hash:int = payments.StarGifts;
payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts; payments.saveStarGift#2a2a697c flags:# unsave:flags.0?true stargift:InputSavedStarGift = Bool;
payments.saveStarGift#92fd2aae flags:# unsave:flags.0?true msg_id:int = Bool; payments.convertStarGift#74bf076b stargift:InputSavedStarGift = Bool;
payments.convertStarGift#72770c83 msg_id:int = Bool;
payments.getUniqueStarGift#a1974d72 slug:string = payments.UniqueStarGift;
payments.getStarGiftUpgradePreview#9c9abcb1 gift_id:long = payments.StarGiftUpgradePreview; payments.getStarGiftUpgradePreview#9c9abcb1 gift_id:long = payments.StarGiftUpgradePreview;
payments.upgradeStarGift#cf4f0781 flags:# keep_original_details:flags.0?true msg_id:int = Updates; payments.upgradeStarGift#aed6e4f5 flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = Updates;
payments.transferStarGift#333fb526 msg_id:int to_id:InputUser = Updates; payments.transferStarGift#7f18176a stargift:InputSavedStarGift to_id:InputPeer = Updates;
payments.getUniqueStarGift#a1974d72 slug:string = payments.UniqueStarGift; payments.getUniqueStarGift#a1974d72 slug:string = payments.UniqueStarGift;
payments.getSavedStarGifts#23830de9 flags:# exclude_unsaved:flags.0?true exclude_saved:flags.1?true exclude_unlimited:flags.2?true exclude_limited:flags.3?true exclude_unique:flags.4?true sort_by_value:flags.5?true peer:InputPeer offset:string limit:int = payments.SavedStarGifts;
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;

View File

@ -303,7 +303,7 @@
"payments.refundStarsCharge", "payments.refundStarsCharge",
"payments.getStarsGiftOptions", "payments.getStarsGiftOptions",
"payments.getStarGifts", "payments.getStarGifts",
"payments.getUserStarGifts", "payments.getSavedStarGifts",
"payments.saveStarGift", "payments.saveStarGift",
"payments.convertStarGift", "payments.convertStarGift",
"payments.getStarGiftUpgradePreview", "payments.getStarGiftUpgradePreview",

View File

@ -33,11 +33,11 @@ inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile sti
inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia; inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia; inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia; inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia; inputMediaUploadedDocument#37c9330 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> video_cover:flags.6?InputPhoto video_timestamp:flags.7?int ttl_seconds:flags.1?int = InputMedia;
inputMediaDocument#33473058 flags:# spoiler:flags.2?true id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia; inputMediaDocument#a8763ab5 flags:# spoiler:flags.2?true id:InputDocument video_cover:flags.3?InputPhoto video_timestamp:flags.4?int ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia; inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia; inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaDocumentExternal#fb52dc99 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia; inputMediaDocumentExternal#779600f9 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int video_cover:flags.2?InputPhoto video_timestamp:flags.3?int = InputMedia;
inputMediaGame#d33f43f3 id:InputGame = InputMedia; inputMediaGame#d33f43f3 id:InputGame = InputMedia;
inputMediaInvoice#405fef0d flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:flags.3?string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia; inputMediaInvoice#405fef0d flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:flags.3?string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia; inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
@ -103,7 +103,7 @@ channel#e00998b7 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull; chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull;
channelFull#9ff3b858 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification = ChatFull; channelFull#52d6806b flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
@ -124,7 +124,7 @@ messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia; messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia; messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia;
messageMediaUnsupported#9f84f49e = MessageMedia; messageMediaUnsupported#9f84f49e = MessageMedia;
messageMediaDocument#dd570bd5 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector<Document> ttl_seconds:flags.2?int = MessageMedia; messageMediaDocument#52d8ccd9 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector<Document> video_cover:flags.9?Photo video_timestamp:flags.10?int ttl_seconds:flags.2?int = MessageMedia;
messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia; messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia;
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia; messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
messageMediaGame#fdb19008 game:Game = MessageMedia; messageMediaGame#fdb19008 game:Game = MessageMedia;
@ -183,8 +183,8 @@ messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector<RequestedPe
messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction; messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction;
messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction; messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction;
messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction; messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction;
messageActionStarGift#d8f4f0a7 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long = MessageAction; messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
messageActionStarGiftUnique#26077b99 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long = MessageAction; messageActionStarGiftUnique#acdfcb81 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long = MessageAction;
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
@ -1475,9 +1475,9 @@ inputInvoiceSlug#c326caef slug:string = InputInvoice;
inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice; inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice;
inputInvoiceStars#65f00ce3 purpose:InputStorePaymentPurpose = InputInvoice; inputInvoiceStars#65f00ce3 purpose:InputStorePaymentPurpose = InputInvoice;
inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice; inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice;
inputInvoiceStarGift#25d8c1d8 flags:# hide_name:flags.0?true include_upgrade:flags.2?true user_id:InputUser gift_id:long message:flags.1?TextWithEntities = InputInvoice; inputInvoiceStarGift#e8625e92 flags:# hide_name:flags.0?true include_upgrade:flags.2?true peer:InputPeer gift_id:long message:flags.1?TextWithEntities = InputInvoice;
inputInvoiceStarGiftUpgrade#5ebe7262 flags:# keep_original_details:flags.0?true msg_id:int = InputInvoice; inputInvoiceStarGiftUpgrade#4d818d5d flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = InputInvoice;
inputInvoiceStarGiftTransfer#ae3ba9ed msg_id:int to_id:InputUser = InputInvoice; inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPeer = InputInvoice;
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
@ -1498,8 +1498,9 @@ premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_ur
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod; paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
emojiStatusEmpty#2de11aae = EmojiStatus; emojiStatusEmpty#2de11aae = EmojiStatus;
emojiStatus#929b619d document_id:long = EmojiStatus; emojiStatus#e7ff068a flags:# document_id:long until:flags.0?int = EmojiStatus;
emojiStatusUntil#fa30a8c7 document_id:long until:int = EmojiStatus; emojiStatusCollectible#7184603b flags:# collectible_id:long document_id:long title:string slug:string pattern_document_id:long center_color:int edge_color:int pattern_color:int text_color:int until:flags.0?int = EmojiStatus;
inputEmojiStatusCollectible#7141dbf flags:# collectible_id:long until:flags.0?int = EmojiStatus;
account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses; account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses;
account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses; account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses;
@ -1876,15 +1877,11 @@ starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true
starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption; starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption;
starGift#2cc73c8 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long = StarGift; starGift#2cc73c8 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long = StarGift;
starGiftUnique#3482f322 flags:# id:long title:string slug:string num:int owner_id:flags.0?long owner_name:flags.1?string attributes:Vector<StarGiftAttribute> availability_issued:int availability_total:int = StarGift; starGiftUnique#f2fe7e4a flags:# id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector<StarGiftAttribute> availability_issued:int availability_total:int = StarGift;
payments.starGiftsNotModified#a388a368 = payments.StarGifts; payments.starGiftsNotModified#a388a368 = payments.StarGifts;
payments.starGifts#901689ea hash:int gifts:Vector<StarGift> = payments.StarGifts; payments.starGifts#901689ea hash:int gifts:Vector<StarGift> = payments.StarGifts;
userStarGift#325835e1 flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true from_id:flags.1?long date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long = UserStarGift;
payments.userStarGifts#6b65b517 flags:# count:int gifts:Vector<UserStarGift> next_offset:flags.0?string users:Vector<User> = payments.UserStarGifts;
messageReportOption#7903e3d9 text:string option:bytes = MessageReportOption; messageReportOption#7903e3d9 text:string option:bytes = MessageReportOption;
reportResultChooseOption#f0e4e0b6 title:string options:Vector<MessageReportOption> = ReportResult; reportResultChooseOption#f0e4e0b6 title:string options:Vector<MessageReportOption> = ReportResult;
@ -1917,7 +1914,7 @@ botVerification#f93cd45c bot_id:long icon:long description:string = BotVerificat
starGiftAttributeModel#39d99013 name:string document:Document rarity_permille:int = StarGiftAttribute; starGiftAttributeModel#39d99013 name:string document:Document rarity_permille:int = StarGiftAttribute;
starGiftAttributePattern#13acff19 name:string document:Document rarity_permille:int = StarGiftAttribute; starGiftAttributePattern#13acff19 name:string document:Document rarity_permille:int = StarGiftAttribute;
starGiftAttributeBackdrop#94271762 name:string center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute; starGiftAttributeBackdrop#94271762 name:string center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute;
starGiftAttributeOriginalDetails#c02c4f4b flags:# sender_id:flags.0?long recipient_id:long date:int message:flags.1?TextWithEntities = StarGiftAttribute; starGiftAttributeOriginalDetails#e0bff26c flags:# sender_id:flags.0?Peer recipient_id:Peer date:int message:flags.1?TextWithEntities = StarGiftAttribute;
payments.starGiftUpgradePreview#167bd90b sample_attributes:Vector<StarGiftAttribute> = payments.StarGiftUpgradePreview; payments.starGiftUpgradePreview#167bd90b sample_attributes:Vector<StarGiftAttribute> = payments.StarGiftUpgradePreview;
@ -1928,6 +1925,15 @@ payments.uniqueStarGift#caa2f60b gift:StarGift users:Vector<User> = payments.Uni
messages.webPagePreview#b53e8b21 media:MessageMedia users:Vector<User> = messages.WebPagePreview; messages.webPagePreview#b53e8b21 media:MessageMedia users:Vector<User> = messages.WebPagePreview;
savedStarGift#6056dba5 flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true from_id:flags.1?Peer date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int saved_id:flags.11?long convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long = SavedStarGift;
payments.savedStarGifts#95f389b1 flags:# count:int chat_notifications_enabled:flags.1?Bool gifts:Vector<SavedStarGift> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.SavedStarGifts;
inputSavedStarGiftUser#69279795 msg_id:int = InputSavedStarGift;
inputSavedStarGiftChat#f101aa7f peer:InputPeer saved_id:long = InputSavedStarGift;
payments.starGiftWithdrawalUrl#84aa3a9c url:string = payments.StarGiftWithdrawalUrl;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -2077,6 +2083,7 @@ account.updatePersonalChannel#d94305e0 channel:InputChannel = Bool;
account.toggleSponsoredMessages#b9d9a38d enabled:Bool = Bool; account.toggleSponsoredMessages#b9d9a38d enabled:Bool = Bool;
account.getReactionsNotifySettings#6dd654c = ReactionsNotifySettings; account.getReactionsNotifySettings#6dd654c = ReactionsNotifySettings;
account.setReactionsNotifySettings#316ce548 settings:ReactionsNotifySettings = ReactionsNotifySettings; account.setReactionsNotifySettings#316ce548 settings:ReactionsNotifySettings = ReactionsNotifySettings;
account.getCollectibleEmojiStatuses#2e7b4543 hash:long = account.EmojiStatuses;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>; users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#b60f5918 id:InputUser = users.UserFull; users.getFullUser#b60f5918 id:InputUser = users.UserFull;
@ -2121,7 +2128,7 @@ messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool; messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
messages.sendMessage#983f9745 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates; messages.sendMessage#983f9745 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates;
messages.sendMedia#7852834e flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates; messages.sendMedia#7852834e flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates;
messages.forwardMessages#d5039208 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut = Updates; messages.forwardMessages#6d74da08 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut video_timestamp:flags.20?int = Updates;
messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.reportSpam#cf1592db peer:InputPeer = Bool;
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings; messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult; messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult;
@ -2505,10 +2512,8 @@ payments.changeStarsSubscription#c7770878 flags:# peer:InputPeer subscription_id
payments.fulfillStarsSubscription#cc5bebb3 peer:InputPeer subscription_id:string = Bool; payments.fulfillStarsSubscription#cc5bebb3 peer:InputPeer subscription_id:string = Bool;
payments.getStarsGiveawayOptions#bd1efd3e = Vector<StarsGiveawayOption>; payments.getStarsGiveawayOptions#bd1efd3e = Vector<StarsGiveawayOption>;
payments.getStarGifts#c4563590 hash:int = payments.StarGifts; payments.getStarGifts#c4563590 hash:int = payments.StarGifts;
payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts; payments.saveStarGift#2a2a697c flags:# unsave:flags.0?true stargift:InputSavedStarGift = Bool;
payments.saveStarGift#92fd2aae flags:# unsave:flags.0?true msg_id:int = Bool; payments.convertStarGift#74bf076b stargift:InputSavedStarGift = 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;
@ -2516,10 +2521,13 @@ payments.getSuggestedStarRefBots#d6b48f7 flags:# order_by_revenue:flags.0?true o
payments.connectStarRefBot#7ed5348a peer:InputPeer bot:InputUser = payments.ConnectedStarRefBots; payments.connectStarRefBot#7ed5348a peer:InputPeer bot:InputUser = payments.ConnectedStarRefBots;
payments.editConnectedStarRefBot#e4fca4a3 flags:# revoked:flags.0?true peer:InputPeer link:string = payments.ConnectedStarRefBots; payments.editConnectedStarRefBot#e4fca4a3 flags:# revoked:flags.0?true peer:InputPeer link:string = payments.ConnectedStarRefBots;
payments.getStarGiftUpgradePreview#9c9abcb1 gift_id:long = payments.StarGiftUpgradePreview; payments.getStarGiftUpgradePreview#9c9abcb1 gift_id:long = payments.StarGiftUpgradePreview;
payments.upgradeStarGift#cf4f0781 flags:# keep_original_details:flags.0?true msg_id:int = Updates; payments.upgradeStarGift#aed6e4f5 flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = Updates;
payments.transferStarGift#333fb526 msg_id:int to_id:InputUser = Updates; payments.transferStarGift#7f18176a stargift:InputSavedStarGift to_id:InputPeer = Updates;
payments.getUserStarGift#b502e4a5 msg_id:Vector<int> = payments.UserStarGifts;
payments.getUniqueStarGift#a1974d72 slug:string = payments.UniqueStarGift; payments.getUniqueStarGift#a1974d72 slug:string = payments.UniqueStarGift;
payments.getSavedStarGifts#23830de9 flags:# exclude_unsaved:flags.0?true exclude_saved:flags.1?true exclude_unlimited:flags.2?true exclude_limited:flags.3?true exclude_unique:flags.4?true sort_by_value:flags.5?true peer:InputPeer offset:string limit:int = payments.SavedStarGifts;
payments.getSavedStarGift#b455a106 stargift:Vector<InputSavedStarGift> = payments.SavedStarGifts;
payments.getStarGiftWithdrawalUrl#d06e93a8 stargift:InputSavedStarGift password:InputCheckPasswordSRP = payments.StarGiftWithdrawalUrl;
payments.toggleChatStarGiftNotifications#60eaefa1 flags:# enabled:flags.0?true peer:InputPeer = Bool;
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet; stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet; stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
@ -2638,4 +2646,4 @@ smsjobs.getStatus#10a698e8 = smsjobs.Status;
smsjobs.getSmsJob#778d902f job_id:string = SmsJob; smsjobs.getSmsJob#778d902f job_id:string = SmsJob;
smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool;
fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo;

View File

@ -561,7 +561,7 @@ export type StarsSubscriptions = {
export type ConfettiStyle = 'poppers' | 'top-down'; export type ConfettiStyle = 'poppers' | 'top-down';
export type StarGiftInfo = { export type StarGiftInfo = {
userId: string; peerId: string;
gift: ApiStarGiftRegular; gift: ApiStarGiftRegular;
shouldHideName?: boolean; shouldHideName?: boolean;
message?: ApiFormattedText; message?: ApiFormattedText;

View File

@ -218,6 +218,7 @@ export interface LangPair {
'SavedMessagesInfo': undefined; 'SavedMessagesInfo': undefined;
'BlockedListNotFound': undefined; 'BlockedListNotFound': undefined;
'TextCopied': undefined; 'TextCopied': undefined;
'WalletAddressCopied': undefined;
'Copy': undefined; 'Copy': undefined;
'DeleteAndStop': undefined; 'DeleteAndStop': undefined;
'DeleteForAll': undefined; 'DeleteForAll': undefined;
@ -1161,6 +1162,7 @@ export interface LangPair {
'GiftSoldOut': undefined; 'GiftSoldOut': undefined;
'GiftMessagePlaceholder': undefined; 'GiftMessagePlaceholder': undefined;
'GiftHideMyName': undefined; 'GiftHideMyName': undefined;
'GiftHideNameDescriptionChannel': undefined;
'GiftInfoSent': undefined; 'GiftInfoSent': undefined;
'GiftInfoReceived': undefined; 'GiftInfoReceived': undefined;
'GiftInfoTitle': undefined; 'GiftInfoTitle': undefined;
@ -1208,6 +1210,7 @@ export interface LangPair {
'StarsReactionLinkText': undefined; 'StarsReactionLinkText': undefined;
'StarsReactionLink': undefined; 'StarsReactionLink': undefined;
'ActionStarGiftDisplaying': undefined; 'ActionStarGiftDisplaying': undefined;
'ActionStarGiftChannelDisplaying': undefined;
'ActionStarGiftDescriptionUpgrade': undefined; 'ActionStarGiftDescriptionUpgrade': undefined;
'ActionStarGiftUpgraded': undefined; 'ActionStarGiftUpgraded': undefined;
'ActionStarGiftUnpack': undefined; 'ActionStarGiftUnpack': undefined;
@ -1622,6 +1625,9 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'StarGiftDescription': { 'StarGiftDescription': {
'user': V; 'user': V;
}; };
'StarGiftDescriptionChannel': {
'peer': V;
};
'GiftDiscount': { 'GiftDiscount': {
'percent': V; 'percent': V;
}; };
@ -1632,17 +1638,16 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'count': V; 'count': V;
}; };
'GiftHideNameDescription': { 'GiftHideNameDescription': {
'profile': V;
'receiver': V; 'receiver': V;
}; };
'GiftSend': { 'GiftSend': {
'amount': V; 'amount': V;
}; };
'GiftInfoDescriptionFreeUpgradeOut': { 'GiftInfoPeerDescriptionFreeUpgradeOut': {
'user': V; 'peer': V;
}; };
'GiftInfoConvertDescription1': { 'GiftInfoPeerConvertDescription': {
'user': V; 'peer': V;
'amount': V; 'amount': V;
}; };
'GiftInfoSaved': { 'GiftInfoSaved': {
@ -1651,6 +1656,12 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'GiftInfoHidden': { 'GiftInfoHidden': {
'link': V; 'link': V;
}; };
'GiftInfoChannelSaved': {
'link': V;
};
'GiftInfoChannelHidden': {
'link': V;
};
'GiftInfoIssued': { 'GiftInfoIssued': {
'issued': V; 'issued': V;
'total': V; 'total': V;
@ -1658,27 +1669,27 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'GiftInfoCollectible': { 'GiftInfoCollectible': {
'number': V; 'number': V;
}; };
'GiftInfoOriginalInfo': { 'GiftInfoPeerOriginalInfo': {
'user': V; 'peer': V;
'date': V; 'date': V;
}; };
'GiftInfoOriginalInfoSender': { 'GiftInfoPeerOriginalInfoSender': {
'sender': V; 'sender': V;
'user': V; 'peer': V;
'date': V; 'date': V;
}; };
'GiftInfoOriginalInfoText': { 'GiftInfoPeerOriginalInfoText': {
'user': V; 'peer': V;
'date': V; 'date': V;
'text': V; 'text': V;
}; };
'GiftInfoOriginalInfoTextSender': { 'GiftInfoPeerOriginalInfoTextSender': {
'sender': V; 'sender': V;
'user': V; 'peer': V;
'date': V; 'date': V;
'text': V; 'text': V;
}; };
'GiftUpgradeText': { 'GiftPeerUpgradeText': {
'peer': V; 'peer': V;
}; };
'GiftUpgradeButton': { 'GiftUpgradeButton': {
@ -1691,6 +1702,10 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'user': V; 'user': V;
'link': V; 'link': V;
}; };
'GiftMakeUniqueDescriptionChannel': {
'peer': V;
'link': V;
};
'StarsAmount': { 'StarsAmount': {
'amount': V; 'amount': V;
}; };
@ -1703,15 +1718,15 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'StarsReactionTerms': { 'StarsReactionTerms': {
'link': V; 'link': V;
}; };
'ActionStarGiftTitle': { 'ActionStarGiftPeerTitle': {
'user': V; 'peer': V;
'count': V; 'count': V;
}; };
'ActionStarGiftOutTitle': { 'ActionStarGiftOutTitle': {
'count': V; 'count': V;
}; };
'ActionStarGiftOutDescriptionUpgrade': { 'ActionStarGiftPeerOutDescriptionUpgrade': {
'user': V; 'peer': V;
}; };
'StarsSubscribeInfo': { 'StarsSubscribeInfo': {
'link': V; 'link': V;
@ -1918,8 +1933,8 @@ export interface LangPairPluralWithVariables<V extends unknown = LangVariable> {
'GiftInfoDescription': { 'GiftInfoDescription': {
'amount': V; 'amount': V;
}; };
'GiftInfoDescriptionOut': { 'GiftInfoPeerDescriptionOut': {
'user': V; 'peer': V;
'amount': V; 'amount': V;
}; };
'GiftInfoDescriptionUpgrade': { 'GiftInfoDescriptionUpgrade': {
@ -1928,8 +1943,8 @@ export interface LangPairPluralWithVariables<V extends unknown = LangVariable> {
'GiftInfoDescriptionConverted': { 'GiftInfoDescriptionConverted': {
'amount': V; 'amount': V;
}; };
'GiftInfoDescriptionOutConverted': { 'GiftInfoPeerDescriptionOutConverted': {
'user': V; 'peer': V;
'amount': V; 'amount': V;
}; };
'GiftInfoConvert': { 'GiftInfoConvert': {
@ -1952,8 +1967,8 @@ export interface LangPairPluralWithVariables<V extends unknown = LangVariable> {
'PrizeCredits2': { 'PrizeCredits2': {
'count': V; 'count': V;
}; };
'ActionStarGiftOutDescription2': { 'ActionStarGiftPeerOutDescription': {
'user': V; 'peer': V;
'count': V; 'count': V;
}; };
'ActionStarGiftDescription2': { 'ActionStarGiftDescription2': {