This commit is contained in:
zubiden 2024-12-20 11:37:16 +01:00 committed by Alexander Zinchuk
parent 99c3c62f6c
commit 50621e91d3
36 changed files with 428 additions and 133 deletions

View File

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

View File

@ -21,6 +21,7 @@ import type {
ApiReceipt, ApiReceipt,
ApiStarGift, ApiStarGift,
ApiStarGiveawayOption, ApiStarGiveawayOption,
ApiStarsAmount,
ApiStarsGiveawayWinnerOption, ApiStarsGiveawayWinnerOption,
ApiStarsSubscription, ApiStarsSubscription,
ApiStarsTransaction, ApiStarsTransaction,
@ -461,6 +462,13 @@ export function buildApiStarsGiftOptions(option: GramJs.StarsGiftOption): ApiSta
}; };
} }
export function buildApiStarsAmount(amount: GramJs.StarsAmount): ApiStarsAmount {
return {
amount: amount.amount.toJSNumber(),
nanos: amount.nanos,
};
}
export function buildApiStarsGiveawayWinnersOption( export function buildApiStarsGiveawayWinnersOption(
option: GramJs.StarsGiveawayWinnersOption, option: GramJs.StarsGiveawayWinnersOption,
): ApiStarsGiveawayWinnerOption { ): ApiStarsGiveawayWinnerOption {
@ -528,7 +536,7 @@ export function buildApiStarsTransactionPeer(peer: GramJs.TypeStarsTransactionPe
export function buildApiStarsTransaction(transaction: GramJs.StarsTransaction): ApiStarsTransaction { export function buildApiStarsTransaction(transaction: GramJs.StarsTransaction): ApiStarsTransaction {
const { const {
date, id, peer, stars, description, photo, title, refund, extendedMedia, failed, msgId, pending, gift, reaction, date, id, peer, stars, description, photo, title, refund, extendedMedia, failed, msgId, pending, gift, reaction,
subscriptionPeriod, stargift, giveawayPostId, subscriptionPeriod, stargift, giveawayPostId, starrefCommissionPermille,
} = transaction; } = transaction;
if (photo) { if (photo) {
@ -538,11 +546,13 @@ export function buildApiStarsTransaction(transaction: GramJs.StarsTransaction):
const boughtExtendedMedia = extendedMedia?.map((m) => buildMessageMediaContent(m)) const boughtExtendedMedia = extendedMedia?.map((m) => buildMessageMediaContent(m))
.filter(Boolean) as BoughtPaidMedia[]; .filter(Boolean) as BoughtPaidMedia[];
const starRefCommision = starrefCommissionPermille ? starrefCommissionPermille / 10 : undefined;
return { return {
id, id,
date, date,
peer: buildApiStarsTransactionPeer(peer), peer: buildApiStarsTransactionPeer(peer),
stars: stars.toJSNumber(), stars: buildApiStarsAmount(stars),
title, title,
description, description,
photo: photo && buildApiWebDocument(photo), photo: photo && buildApiWebDocument(photo),
@ -556,6 +566,7 @@ export function buildApiStarsTransaction(transaction: GramJs.StarsTransaction):
isReaction: reaction, isReaction: reaction,
starGift: stargift && buildApiStarGift(stargift), starGift: stargift && buildApiStarGift(stargift),
giveawayPostId, giveawayPostId,
starRefCommision,
}; };
} }

View File

@ -1131,9 +1131,10 @@ export async function getChatByPhoneNumber(phoneNumber: string) {
return processResolvedPeer(result); return processResolvedPeer(result);
} }
export async function getChatByUsername(username: string) { export async function getChatByUsername(username: string, referrer?: string) {
const result = await invokeRequest(new GramJs.contacts.ResolveUsername({ const result = await invokeRequest(new GramJs.contacts.ResolveUsername({
username, username,
referer: referrer,
})); }));
return processResolvedPeer(result); return processResolvedPeer(result);

View File

@ -19,6 +19,7 @@ import {
buildApiPremiumPromo, buildApiPremiumPromo,
buildApiReceipt, buildApiReceipt,
buildApiStarGift, buildApiStarGift,
buildApiStarsAmount,
buildApiStarsGiftOptions, buildApiStarsGiftOptions,
buildApiStarsGiveawayOptions, buildApiStarsGiveawayOptions,
buildApiStarsSubscription, buildApiStarsSubscription,
@ -534,7 +535,7 @@ export async function fetchStarsStatus() {
history: result.history?.map(buildApiStarsTransaction), history: result.history?.map(buildApiStarsTransaction),
nextSubscriptionOffset: result.subscriptionsNextOffset, nextSubscriptionOffset: result.subscriptionsNextOffset,
subscriptions: result.subscriptions?.map(buildApiStarsSubscription), subscriptions: result.subscriptions?.map(buildApiStarsSubscription),
balance: result.balance.toJSNumber(), balance: buildApiStarsAmount(result.balance),
}; };
} }
@ -564,7 +565,7 @@ export async function fetchStarsTransactions({
return { return {
nextOffset: result.nextOffset, nextOffset: result.nextOffset,
history: result.history?.map(buildApiStarsTransaction), history: result.history?.map(buildApiStarsTransaction),
balance: result.balance.toJSNumber(), balance: buildApiStarsAmount(result.balance),
}; };
} }
@ -610,7 +611,7 @@ export async function fetchStarsSubscriptions({
return { return {
nextOffset: result.subscriptionsNextOffset, nextOffset: result.subscriptionsNextOffset,
subscriptions: result.subscriptions.map(buildApiStarsSubscription), subscriptions: result.subscriptions.map(buildApiStarsSubscription),
balance: result.balance.toJSNumber(), balance: buildApiStarsAmount(result.balance),
}; };
} }

View File

@ -51,6 +51,7 @@ import {
buildLangStrings, buildLangStrings,
buildPrivacyKey, buildPrivacyKey,
} from '../apiBuilders/misc'; } from '../apiBuilders/misc';
import { buildApiStarsAmount } from '../apiBuilders/payments';
import { buildApiEmojiStatus, buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers'; import { buildApiEmojiStatus, buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
import { import {
buildApiReaction, buildApiReaction,
@ -1059,7 +1060,7 @@ export function updater(update: Update) {
} else if (update instanceof GramJs.UpdateStarsBalance) { } else if (update instanceof GramJs.UpdateStarsBalance) {
sendApiUpdate({ sendApiUpdate({
'@type': 'updateStarsBalance', '@type': 'updateStarsBalance',
balance: update.balance.toJSNumber(), balance: buildApiStarsAmount(update.balance),
}); });
} else if (update instanceof GramJs.UpdatePaidReactionPrivacy) { } else if (update instanceof GramJs.UpdatePaidReactionPrivacy) {
sendApiUpdate({ sendApiUpdate({

View File

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

View File

@ -302,6 +302,11 @@ export type ApiCheckedGiftCode = {
usedAt?: number; usedAt?: number;
}; };
export interface ApiStarsAmount {
amount: number;
nanos: number;
}
export interface ApiStarsTransactionPeerUnsupported { export interface ApiStarsTransactionPeerUnsupported {
type: 'unsupported'; type: 'unsupported';
} }
@ -349,7 +354,7 @@ export interface ApiStarsTransaction {
id?: string; id?: string;
peer: ApiStarsTransactionPeer; peer: ApiStarsTransactionPeer;
messageId?: number; messageId?: number;
stars: number; stars: ApiStarsAmount;
isRefund?: true; isRefund?: true;
isGift?: true; isGift?: true;
starGift?: ApiStarGift; starGift?: ApiStarGift;
@ -364,6 +369,7 @@ export interface ApiStarsTransaction {
photo?: ApiWebDocument; photo?: ApiWebDocument;
extendedMedia?: BoughtPaidMedia[]; extendedMedia?: BoughtPaidMedia[];
subscriptionPeriod?: number; subscriptionPeriod?: number;
starRefCommision?: number;
} }
export interface ApiStarsSubscription { export interface ApiStarsSubscription {

View File

@ -34,6 +34,7 @@ import type {
import type { import type {
ApiEmojiInteraction, ApiError, ApiNotifyException, ApiSessionData, ApiEmojiInteraction, ApiError, ApiNotifyException, ApiSessionData,
} from './misc'; } from './misc';
import type { ApiStarsAmount } from './payments';
import type { LangPackStringValue } from './settings'; import type { LangPackStringValue } from './settings';
import type { ApiStealthMode, ApiStory, ApiStorySkipped } from './stories'; import type { ApiStealthMode, ApiStory, ApiStorySkipped } from './stories';
import type { import type {
@ -760,7 +761,7 @@ export type ApiUpdatePremiumFloodWait = {
export type ApiUpdateStarsBalance = { export type ApiUpdateStarsBalance = {
'@type': 'updateStarsBalance'; '@type': 'updateStarsBalance';
balance: number; balance: ApiStarsAmount;
}; };
export type ApiUpdateDeleteProfilePhoto = { export type ApiUpdateDeleteProfilePhoto = {

View File

@ -1377,6 +1377,7 @@
"StarsSubscribeInfoLinkText" = "Terms of Service"; "StarsSubscribeInfoLinkText" = "Terms of Service";
"StarsSubscribeInfoLink" = "https://telegram.org/tos/stars"; "StarsSubscribeInfoLink" = "https://telegram.org/tos/stars";
"StarsPerMonth" = "⭐️{amount}/month"; "StarsPerMonth" = "⭐️{amount}/month";
"StarsBalance" = "Balance";
"OpenApp" = "Open App"; "OpenApp" = "Open App";
"PopularApps" = "Popular Apps"; "PopularApps" = "Popular Apps";
"SearchApps" = "Search Apps"; "SearchApps" = "Search Apps";

View File

@ -95,7 +95,7 @@
width: 1.125rem; width: 1.125rem;
height: 1.125rem; height: 1.125rem;
background-size: 1.125rem; background-size: 1.125rem;
vertical-align: -2px; vertical-align: -4px;
} }
} }

View File

@ -2,17 +2,19 @@ import type { FC } from '../../../lib/teact/teact';
import React, { memo, useEffect } from '../../../lib/teact/teact'; import React, { memo, useEffect } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { ApiStarsAmount } from '../../../api/types';
import { SettingsScreens } from '../../../types'; import { SettingsScreens } from '../../../types';
import { FAQ_URL, PRIVACY_URL } from '../../../config'; import { FAQ_URL, PRIVACY_URL } from '../../../config';
import { formatStarsAmount } from '../../../global/helpers/payments';
import { import {
selectIsGiveawayGiftsPurchaseAvailable, selectIsGiveawayGiftsPurchaseAvailable,
selectIsPremiumPurchaseBlocked, selectIsPremiumPurchaseBlocked,
} from '../../../global/selectors'; } from '../../../global/selectors';
import { formatInteger } from '../../../util/textFormat';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import useHistoryBack from '../../../hooks/useHistoryBack'; import useHistoryBack from '../../../hooks/useHistoryBack';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
@ -33,7 +35,7 @@ type StateProps = {
currentUserId?: string; currentUserId?: string;
canBuyPremium?: boolean; canBuyPremium?: boolean;
isGiveawayAvailable?: boolean; isGiveawayAvailable?: boolean;
starsBalance?: number; starsBalance?: ApiStarsAmount;
shouldDisplayStars?: boolean; shouldDisplayStars?: boolean;
}; };
@ -59,6 +61,7 @@ const SettingsMain: FC<OwnProps & StateProps> = ({
const [isSupportDialogOpen, openSupportDialog, closeSupportDialog] = useFlag(false); const [isSupportDialogOpen, openSupportDialog, closeSupportDialog] = useFlag(false);
const lang = useLang();
const oldLang = useOldLang(); const oldLang = useOldLang();
useEffect(() => { useEffect(() => {
@ -188,7 +191,9 @@ const SettingsMain: FC<OwnProps & StateProps> = ({
> >
{oldLang('MenuTelegramStars')} {oldLang('MenuTelegramStars')}
{Boolean(starsBalance) && ( {Boolean(starsBalance) && (
<span className="settings-item__current-value">{formatInteger(starsBalance)}</span> <span className="settings-item__current-value">
{formatStarsAmount(lang, starsBalance)}
</span>
)} )}
</ListItem> </ListItem>
)} )}

View File

@ -296,7 +296,6 @@ type StateProps = {
canTranscribeVoice?: boolean; canTranscribeVoice?: boolean;
viaBusinessBot?: ApiUser; viaBusinessBot?: ApiUser;
effect?: ApiAvailableEffect; effect?: ApiAvailableEffect;
availableStars?: number;
poll?: ApiPoll; poll?: ApiPoll;
}; };
@ -418,7 +417,6 @@ const Message: FC<OwnProps & StateProps> = ({
canTranscribeVoice, canTranscribeVoice,
viaBusinessBot, viaBusinessBot,
effect, effect,
availableStars,
poll, poll,
onIntersectPinnedMessage, onIntersectPinnedMessage,
}) => { }) => {
@ -1062,7 +1060,6 @@ const Message: FC<OwnProps & StateProps> = ({
noRecentReactors={isChannel} noRecentReactors={isChannel}
tags={tags} tags={tags}
isCurrentUserPremium={isPremium} isCurrentUserPremium={isPremium}
availableStars={availableStars}
/> />
); );
} }
@ -1701,7 +1698,6 @@ const Message: FC<OwnProps & StateProps> = ({
observeIntersection={observeIntersectionForPlaying} observeIntersection={observeIntersectionForPlaying}
noRecentReactors={isChannel} noRecentReactors={isChannel}
tags={tags} tags={tags}
availableStars={availableStars}
/> />
)} )}
</div> </div>
@ -1852,7 +1848,6 @@ export default memo(withGlobal<OwnProps>(
const effect = effectId ? global.availableEffectById[effectId] : undefined; const effect = effectId ? global.availableEffectById[effectId] : undefined;
const { balance: availableStars } = global.stars || {};
const poll = selectPollFromMessage(global, message); const poll = selectPollFromMessage(global, message);
return { return {
@ -1941,7 +1936,6 @@ export default memo(withGlobal<OwnProps>(
canTranscribeVoice, canTranscribeVoice,
viaBusinessBot, viaBusinessBot,
effect, effect,
availableStars,
poll, poll,
}; };
}, },

View File

@ -40,14 +40,13 @@ type OwnProps = {
recentReactors?: ApiPeer[]; recentReactors?: ApiPeer[];
className?: string; className?: string;
chosenClassName?: string; chosenClassName?: string;
availableStars?: number;
observeIntersection?: ObserveFn; observeIntersection?: ObserveFn;
onClick?: (reaction: ApiReaction) => void; onClick?: (reaction: ApiReaction) => void;
onPaidClick?: (count: number) => void; onPaidClick?: (count: number) => void;
}; };
function selectAreStarsLoaded(global: GlobalState) { function selectStarsState(global: GlobalState) {
return Boolean(global.stars); return global.stars;
} }
const ReactionButton = ({ const ReactionButton = ({
@ -57,7 +56,6 @@ const ReactionButton = ({
recentReactors, recentReactors,
className, className,
chosenClassName, chosenClassName,
availableStars,
chatId, chatId,
messageId, messageId,
observeIntersection, observeIntersection,
@ -78,7 +76,8 @@ const ReactionButton = ({
const isPaid = reaction.reaction.type === 'paid'; const isPaid = reaction.reaction.type === 'paid';
const areStarsLoaded = useSelector(selectAreStarsLoaded); const starsState = useSelector(selectStarsState);
const areStarsLoaded = Boolean(starsState);
const handlePaidClick = useLastCallback((count = 1) => { const handlePaidClick = useLastCallback((count = 1) => {
onPaidClick?.(count); onPaidClick?.(count);
@ -120,7 +119,7 @@ const ReactionButton = ({
const button = ref.current; const button = ref.current;
if (!amount || !button || amount === prevReaction?.localAmount) return; if (!amount || !button || amount === prevReaction?.localAmount) return;
if (areStarsLoaded && (!availableStars || amount > availableStars)) { if (areStarsLoaded && amount > starsState.balance.amount) {
openStarsBalanceModal({ openStarsBalanceModal({
originReaction: { originReaction: {
chatId, chatId,
@ -153,7 +152,7 @@ const ReactionButton = ({
duration: 500 * currentScale, duration: 500 * currentScale,
easing: 'ease-out', easing: 'ease-out',
}); });
}, [reaction, availableStars, areStarsLoaded, chatId, messageId]); }, [reaction, starsState?.balance, areStarsLoaded, chatId, messageId]);
const prevAmount = usePrevious(reaction.localAmount); const prevAmount = usePrevious(reaction.localAmount);

View File

@ -36,7 +36,6 @@ type OwnProps = {
isCurrentUserPremium?: boolean; isCurrentUserPremium?: boolean;
observeIntersection?: ObserveFn; observeIntersection?: ObserveFn;
noRecentReactors?: boolean; noRecentReactors?: boolean;
availableStars?: number;
}; };
const MAX_RECENT_AVATARS = 3; const MAX_RECENT_AVATARS = 3;
@ -52,7 +51,6 @@ const Reactions: FC<OwnProps> = ({
noRecentReactors, noRecentReactors,
isCurrentUserPremium, isCurrentUserPremium,
tags, tags,
availableStars,
}) => { }) => {
const { const {
toggleReaction, toggleReaction,
@ -216,7 +214,6 @@ const Reactions: FC<OwnProps> = ({
onClick={handleClick} onClick={handleClick}
onPaidClick={handlePaidClick} onPaidClick={handlePaidClick}
observeIntersection={observeIntersection} observeIntersection={observeIntersection}
availableStars={availableStars}
/> />
) )
))} ))}

View File

@ -7,6 +7,7 @@ import { getActions, withGlobal } from '../../../global';
import type { import type {
ApiPremiumGiftCodeOption, ApiPremiumGiftCodeOption,
ApiStarGift, ApiStarGift,
ApiStarsAmount,
ApiUser, ApiUser,
} from '../../../api/types'; } from '../../../api/types';
import type { StarGiftCategory, TabState } from '../../../global/types'; import type { StarGiftCategory, TabState } from '../../../global/types';
@ -45,7 +46,7 @@ type StateProps = {
boostPerSentGift?: number; boostPerSentGift?: number;
starGiftsById?: Record<string, ApiStarGift>; starGiftsById?: Record<string, ApiStarGift>;
starGiftCategoriesByName: Record<StarGiftCategory, string[]>; starGiftCategoriesByName: Record<StarGiftCategory, string[]>;
starBalance?: number; starBalance?: ApiStarsAmount;
user?: ApiUser; user?: ApiUser;
}; };

View File

@ -3,7 +3,9 @@ import React, {
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../global'; import { getActions, getGlobal, withGlobal } from '../../../global';
import type { ApiChat, ApiMessage, ApiUser } from '../../../api/types'; import type {
ApiChat, ApiMessage, ApiStarsAmount, ApiUser,
} from '../../../api/types';
import type { TabState } from '../../../global/types'; import type { TabState } from '../../../global/types';
import type { CustomPeer } from '../../../types'; import type { CustomPeer } from '../../../types';
@ -38,7 +40,7 @@ type StateProps = {
message?: ApiMessage; message?: ApiMessage;
chat?: ApiChat; chat?: ApiChat;
maxAmount: number; maxAmount: number;
starBalance?: number; starBalance?: ApiStarsAmount;
defaultPrivacy?: boolean; defaultPrivacy?: boolean;
}; };

View File

@ -1,28 +1,30 @@
import React, { memo } from '../../../lib/teact/teact'; import React, { memo } from '../../../lib/teact/teact';
import buildClassName from '../../../util/buildClassName'; import type { ApiStarsAmount } from '../../../api/types';
import { formatInteger } from '../../../util/textFormat';
import useOldLang from '../../../hooks/useOldLang'; import { formatStarsAmount } from '../../../global/helpers/payments';
import buildClassName from '../../../util/buildClassName';
import useLang from '../../../hooks/useLang';
import StarIcon from '../../common/icons/StarIcon'; import StarIcon from '../../common/icons/StarIcon';
import styles from './StarsBalanceModal.module.scss'; import styles from './StarsBalanceModal.module.scss';
type OwnProps = { type OwnProps = {
balance?: number; balance?: ApiStarsAmount;
className?: string; className?: string;
}; };
const BalanceBlock = ({ balance, className }: OwnProps) => { const BalanceBlock = ({ balance, className }: OwnProps) => {
const lang = useOldLang(); const lang = useLang();
return ( return (
<div className={buildClassName(styles.balance, className)}> <div className={buildClassName(styles.balance, className)}>
<span className={styles.smallerText}>{lang('StarsBalance')}</span> <span className={styles.smallerText}>{lang('StarsBalance')}</span>
<div className={styles.balanceBottom}> <div className={styles.balanceBottom}>
<StarIcon type="gold" size="middle" /> <StarIcon type="gold" size="middle" />
{balance !== undefined ? formatInteger(balance) : '…'} {balance !== undefined ? formatStarsAmount(lang, balance) : '…'}
</div> </div>
</div> </div>
); );

View File

@ -81,7 +81,7 @@ const StarsBalanceModal = ({
|| originReaction?.amount || originReaction?.amount
|| originGift?.gift.stars || originGift?.gift.stars
|| topup?.balanceNeeded; || topup?.balanceNeeded;
const starsNeeded = ongoingTransactionAmount ? ongoingTransactionAmount - (balance || 0) : undefined; const starsNeeded = ongoingTransactionAmount ? ongoingTransactionAmount - (balance?.amount || 0) : undefined;
const starsNeededText = useMemo(() => { const starsNeededText = useMemo(() => {
const global = getGlobal(); const global = getGlobal();

View File

@ -150,7 +150,7 @@ const StarPaymentModal = ({
return; return;
} }
if (amount > balance) { if (amount > balance.amount) {
openStarsBalanceModal({ openStarsBalanceModal({
originStarsPayment: modal, originStarsPayment: modal,
}); });

View File

@ -1,9 +1,13 @@
import type { ApiStarsTransaction } from '../../../../api/types'; import type { ApiStarsAmount, ApiStarsTransaction } from '../../../../api/types';
import type { OldLangFn } from '../../../../hooks/useOldLang'; import type { OldLangFn } from '../../../../hooks/useOldLang';
import { buildStarsTransactionCustomPeer } from '../../../../global/helpers/payments'; import { buildStarsTransactionCustomPeer } from '../../../../global/helpers/payments';
import { formatPercent } from '../../../../util/textFormat';
export function getTransactionTitle(lang: OldLangFn, transaction: ApiStarsTransaction) { export function getTransactionTitle(lang: OldLangFn, transaction: ApiStarsTransaction) {
if (transaction.starRefCommision) {
return lang('StarTransactionCommission', formatPercent(transaction.starRefCommision));
}
if (transaction.extendedMedia) return lang('StarMediaPurchase'); if (transaction.extendedMedia) return lang('StarMediaPurchase');
if (transaction.subscriptionPeriod) return transaction.title || lang('StarSubscriptionPurchase'); if (transaction.subscriptionPeriod) return transaction.title || lang('StarSubscriptionPurchase');
if (transaction.isReaction) return lang('StarsReactionsSent'); if (transaction.isReaction) return lang('StarsReactionsSent');
@ -11,7 +15,7 @@ export function getTransactionTitle(lang: OldLangFn, transaction: ApiStarsTransa
if (transaction.isMyGift) return lang('StarsGiftSent'); if (transaction.isMyGift) return lang('StarsGiftSent');
if (transaction.isGift) return lang('StarsGiftReceived'); if (transaction.isGift) return lang('StarsGiftReceived');
if (transaction.starGift) { if (transaction.starGift) {
return transaction.stars < 0 ? lang('Gift2TransactionSent') : lang('Gift2ConvertedTitle'); return isNegativeStarsAmount(transaction.stars) ? lang('Gift2TransactionSent') : lang('Gift2ConvertedTitle');
} }
const customPeer = (transaction.peer && transaction.peer.type !== 'peer' const customPeer = (transaction.peer && transaction.peer.type !== 'peer'
@ -21,3 +25,8 @@ export function getTransactionTitle(lang: OldLangFn, transaction: ApiStarsTransa
return transaction.title; return transaction.title;
} }
export function isNegativeStarsAmount(starsAmount: ApiStarsAmount) {
if (starsAmount.amount) return starsAmount.amount < 0;
return starsAmount.nanos < 0;
}

View File

@ -14,9 +14,11 @@ import { selectPeer } from '../../../../global/selectors';
import buildClassName from '../../../../util/buildClassName'; import buildClassName from '../../../../util/buildClassName';
import { formatDateTimeToString } from '../../../../util/dates/dateFormat'; import { formatDateTimeToString } from '../../../../util/dates/dateFormat';
import { CUSTOM_PEER_PREMIUM } from '../../../../util/objects/customPeer'; import { CUSTOM_PEER_PREMIUM } from '../../../../util/objects/customPeer';
import { getTransactionTitle } from '../helpers/transaction'; import renderText from '../../../common/helpers/renderText';
import { getTransactionTitle, isNegativeStarsAmount } from '../helpers/transaction';
import useSelector from '../../../../hooks/data/useSelector'; import useSelector from '../../../../hooks/data/useSelector';
import useLang from '../../../../hooks/useLang';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang'; import useOldLang from '../../../../hooks/useOldLang';
@ -47,24 +49,25 @@ const StarsTransactionItem = ({ transaction, className }: OwnProps) => {
extendedMedia, extendedMedia,
subscriptionPeriod, subscriptionPeriod,
} = transaction; } = transaction;
const lang = useOldLang(); const lang = useLang();
const oldLang = useOldLang();
const peerId = transactionPeer.type === 'peer' ? transactionPeer.id : undefined; const peerId = transactionPeer.type === 'peer' ? transactionPeer.id : undefined;
const peer = useSelector(selectOptionalPeer(peerId)); const peer = useSelector(selectOptionalPeer(peerId));
const data = useMemo(() => { const data = useMemo(() => {
let title = getTransactionTitle(lang, transaction); let title = getTransactionTitle(oldLang, transaction);
let description; let description;
let status: string | undefined; let status: string | undefined;
let avatarPeer: ApiPeer | CustomPeer | undefined; let avatarPeer: ApiPeer | CustomPeer | undefined;
if (transaction.peer.type === 'peer') { if (transaction.peer.type === 'peer') {
description = peer && getSenderTitle(lang, peer); description = peer && getSenderTitle(oldLang, peer);
avatarPeer = peer || CUSTOM_PEER_PREMIUM; avatarPeer = peer || CUSTOM_PEER_PREMIUM;
} else { } else {
const customPeer = buildStarsTransactionCustomPeer(transaction.peer); const customPeer = buildStarsTransactionCustomPeer(transaction.peer);
title = customPeer.title || lang(customPeer.titleKey!); title = customPeer.title || oldLang(customPeer.titleKey!);
description = lang(customPeer.subtitleKey!); description = oldLang(customPeer.subtitleKey!);
avatarPeer = customPeer; avatarPeer = customPeer;
} }
@ -73,15 +76,15 @@ const StarsTransactionItem = ({ transaction, className }: OwnProps) => {
} }
if (transaction.isRefund) { if (transaction.isRefund) {
status = lang('StarsRefunded'); status = oldLang('StarsRefunded');
} }
if (transaction.hasFailed) { if (transaction.hasFailed) {
status = lang('StarsFailed'); status = oldLang('StarsFailed');
} }
if (transaction.isPending) { if (transaction.isPending) {
status = lang('StarsPending'); status = oldLang('StarsPending');
} }
return { return {
@ -90,7 +93,7 @@ const StarsTransactionItem = ({ transaction, className }: OwnProps) => {
avatarPeer, avatarPeer,
status, status,
}; };
}, [lang, peer, transaction]); }, [oldLang, peer, transaction]);
const handleClick = useLastCallback(() => { const handleClick = useLastCallback(() => {
openStarsTransactionModal({ transaction }); openStarsTransactionModal({ transaction });
@ -107,15 +110,19 @@ const StarsTransactionItem = ({ transaction, className }: OwnProps) => {
</div> </div>
<div className={styles.info}> <div className={styles.info}>
<h3 className={styles.title}>{data.title}</h3> <h3 className={styles.title}>{data.title}</h3>
<p className={styles.description}>{data.description}</p> {data.description && (
<p className={styles.description}>{renderText(data.description)}</p>
)}
<p className={styles.date}> <p className={styles.date}>
{formatDateTimeToString(date * 1000, lang.code, true)} {formatDateTimeToString(date * 1000, oldLang.code, true)}
{data.status && ` — (${data.status})`} {data.status && ` — (${data.status})`}
</p> </p>
</div> </div>
<div className={styles.stars}> <div className={styles.stars}>
<span className={buildClassName(styles.amount, stars < 0 ? styles.negative : styles.positive)}> <span
{formatStarsTransactionAmount(stars)} className={buildClassName(styles.amount, isNegativeStarsAmount(stars) ? styles.negative : styles.positive)}
>
{formatStarsTransactionAmount(lang, stars)}
</span> </span>
<StarIcon className={styles.star} type="gold" size="adaptive" /> <StarIcon className={styles.star} type="gold" size="adaptive" />
</div> </div>

View File

@ -19,8 +19,9 @@ import {
import buildClassName from '../../../../util/buildClassName'; import buildClassName from '../../../../util/buildClassName';
import { copyTextToClipboard } from '../../../../util/clipboard'; import { copyTextToClipboard } from '../../../../util/clipboard';
import { formatDateTimeToString } from '../../../../util/dates/dateFormat'; import { formatDateTimeToString } from '../../../../util/dates/dateFormat';
import { getTransactionTitle } from '../helpers/transaction'; import { getTransactionTitle, isNegativeStarsAmount } from '../helpers/transaction';
import useLang from '../../../../hooks/useLang';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang'; import useOldLang from '../../../../hooks/useOldLang';
import usePrevious from '../../../../hooks/usePrevious'; import usePrevious from '../../../../hooks/usePrevious';
@ -51,6 +52,8 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
modal, peer, canPlayAnimatedEmojis, topSticker, modal, peer, canPlayAnimatedEmojis, topSticker,
}) => { }) => {
const { showNotification, openMediaViewer, closeStarsTransactionModal } = getActions(); const { showNotification, openMediaViewer, closeStarsTransactionModal } = getActions();
const lang = useLang();
const oldLang = useOldLang(); const oldLang = useOldLang();
const { transaction } = modal || {}; const { transaction } = modal || {};
@ -70,7 +73,7 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
} }
const { const {
giveawayPostId, photo, giveawayPostId, photo, stars,
} = transaction; } = transaction;
const customPeer = (transaction.peer && transaction.peer.type !== 'peer' const customPeer = (transaction.peer && transaction.peer.type !== 'peer'
@ -130,8 +133,10 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
{title && <h1 className={styles.title}>{title}</h1>} {title && <h1 className={styles.title}>{title}</h1>}
<p className={styles.description}>{description}</p> <p className={styles.description}>{description}</p>
<p className={styles.amount}> <p className={styles.amount}>
<span className={buildClassName(styles.amount, transaction.stars < 0 ? styles.negative : styles.positive)}> <span
{formatStarsTransactionAmount(transaction.stars)} className={buildClassName(styles.amount, isNegativeStarsAmount(stars) ? styles.negative : styles.positive)}
>
{formatStarsTransactionAmount(lang, stars)}
</span> </span>
<StarIcon type="gold" size="middle" /> <StarIcon type="gold" size="middle" />
</p> </p>
@ -140,9 +145,26 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
const tableData: TableData = []; const tableData: TableData = [];
if (transaction.starRefCommision) {
tableData.push([
oldLang('StarsTransaction.StarRefReason.Title'),
oldLang('StarsTransaction.StarRefReason.Program'),
]);
}
let peerLabel;
if (isNegativeStarsAmount(stars) || transaction.isMyGift) {
peerLabel = oldLang('Stars.Transaction.To');
} else if (transaction.starRefCommision) {
peerLabel = oldLang('StarsTransaction.StarRefReason.Miniapp');
} else if (peerId) {
peerLabel = oldLang('Star.Transaction.From');
} else {
peerLabel = oldLang('Stars.Transaction.Via');
}
tableData.push([ tableData.push([
oldLang(transaction.stars < 0 || transaction.isMyGift ? 'Stars.Transaction.To' peerLabel,
: peerId ? 'Star.Transaction.From' : 'Stars.Transaction.Via'),
peerId ? { chatId: peerId } : toName || '', peerId ? { chatId: peerId } : toName || '',
]); ]);
@ -198,7 +220,7 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
tableData, tableData,
footer, footer,
}; };
}, [transaction, oldLang, peer, topSticker, canPlayAnimatedEmojis]); }, [transaction, oldLang, lang, peer, topSticker, canPlayAnimatedEmojis]);
const prevModalData = usePrevious(starModalData); const prevModalData = usePrevious(starModalData);
const renderingModalData = prevModalData || starModalData; const renderingModalData = prevModalData || starModalData;
@ -222,7 +244,7 @@ export default memo(withGlobal<OwnProps>(
const peer = peerId ? selectPeer(global, peerId) : undefined; const peer = peerId ? selectPeer(global, peerId) : undefined;
const starCount = modal?.transaction.stars; const starCount = modal?.transaction.stars;
const starsGiftSticker = modal?.transaction.isGift && selectGiftStickerForStars(global, starCount); const starsGiftSticker = modal?.transaction.isGift && selectGiftStickerForStars(global, starCount?.amount);
const starGiftStickerId = modal?.transaction.starGift?.stickerId; const starGiftStickerId = modal?.transaction.starGift?.stickerId;
const starGiftSticker = starGiftStickerId && selectStarGiftSticker(global, starGiftStickerId); const starGiftSticker = starGiftStickerId && selectStarGiftSticker(global, starGiftStickerId);

View File

@ -51,7 +51,7 @@ export const MEDIA_PROGRESSIVE_CACHE_DISABLED = false;
export const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive'; export const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive';
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg'; export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
export const LANG_CACHE_NAME = 'tt-lang-packs-v45'; export const LANG_CACHE_NAME = 'tt-lang-packs-v46';
export const ASSET_CACHE_NAME = 'tt-assets'; export const ASSET_CACHE_NAME = 'tt-assets';
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500]; export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global'; export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global';

View File

@ -2912,14 +2912,15 @@ export async function migrateChat<T extends GlobalState>(
export async function fetchChatByUsername<T extends GlobalState>( export async function fetchChatByUsername<T extends GlobalState>(
global: T, global: T,
username: string, username: string,
referrer?: string,
) { ) {
global = getGlobal(); global = getGlobal();
const localChat = selectChatByUsername(global, username); const localChat = !referrer ? selectChatByUsername(global, username) : undefined;
if (localChat && !localChat.isMin) { if (localChat && !localChat.isMin) {
return localChat; return localChat;
} }
const { chat, user } = await callApi('getChatByUsername', username) || {}; const { chat, user } = await callApi('getChatByUsername', username, referrer) || {};
if (!chat) { if (!chat) {
return undefined; return undefined;
} }
@ -3047,7 +3048,16 @@ async function openChatByUsername<T extends GlobalState>(
actions.openChat({ id: TMP_CHAT_ID, tabId }); actions.openChat({ id: TMP_CHAT_ID, tabId });
} }
const chat = await fetchChatByUsername(global, username); const starRefStartPrefixes = global.appConfig?.starRefStartPrefixes;
let referrer = '';
if (startParam && starRefStartPrefixes?.length) {
const prefix = starRefStartPrefixes.find((p) => startParam.startsWith(p));
if (prefix) {
referrer = startParam.slice(prefix.length);
}
}
const chat = await fetchChatByUsername(global, username, referrer);
if (!chat) { if (!chat) {
if (!isCurrentChat) { if (!isCurrentChat) {
actions.openPreviousChat({ tabId }); actions.openPreviousChat({ tabId });

View File

@ -126,7 +126,7 @@ addActionHandler('sendStarGift', async (global, actions, payload): Promise<void>
if (balance === undefined) return; if (balance === undefined) return;
if (balance < gift.stars) { if (balance.amount < gift.stars) {
actions.openStarsBalanceModal({ tabId }); actions.openStarsBalanceModal({ tabId });
return; return;
} }

View File

@ -119,7 +119,7 @@ addActionHandler('openStarsBalanceModal', (global, actions, payload): ActionRetu
const starBalance = global.stars?.balance; const starBalance = global.stars?.balance;
if (!shouldIgnoreBalance && starBalance && topup && topup.balanceNeeded <= starBalance) { if (!shouldIgnoreBalance && starBalance && topup && topup.balanceNeeded <= starBalance.amount) {
actions.showNotification({ actions.showNotification({
message: langProvider.oldTranslate('StarsTopupLinkEnough'), message: langProvider.oldTranslate('StarsTopupLinkEnough'),
actionText: langProvider.oldTranslate('StarsTopupLinkTopupAnyway'), actionText: langProvider.oldTranslate('StarsTopupLinkTopupAnyway'),

View File

@ -2,14 +2,15 @@ import type {
ApiInputInvoice, ApiInputInvoice,
ApiMessage, ApiMessage,
ApiRequestInputInvoice, ApiRequestInputInvoice,
ApiStarsAmount,
ApiStarsTransaction, ApiStarsTransaction,
ApiStarsTransactionPeer, ApiStarsTransactionPeer,
ApiStarsTransactionPeerPeer, ApiStarsTransactionPeerPeer,
} from '../../api/types'; } from '../../api/types';
import type { CustomPeer } from '../../types'; import type { CustomPeer } from '../../types';
import type { LangFn } from '../../util/localization';
import type { GlobalState } from '../types'; import type { GlobalState } from '../types';
import { formatInteger } from '../../util/textFormat';
import { selectChat, selectUser } from '../selectors'; import { selectChat, selectUser } from '../selectors';
export function getRequestInputInvoice<T extends GlobalState>( export function getRequestInputInvoice<T extends GlobalState>(
@ -247,12 +248,17 @@ export function buildStarsTransactionCustomPeer(
}; };
} }
export function formatStarsTransactionAmount(amount: number) { export function formatStarsTransactionAmount(lang: LangFn, starsAmount: ApiStarsAmount) {
const amount = starsAmount.amount + starsAmount.nanos / 1e9;
if (amount < 0) { if (amount < 0) {
return `- ${formatInteger(Math.abs(amount))}`; return `- ${lang.number(Math.abs(amount))}`;
} }
return `+ ${formatInteger(amount)}`; return `+ ${lang.number(amount)}`;
}
export function formatStarsAmount(lang: LangFn, starsAmount: ApiStarsAmount) {
return lang.number(starsAmount.amount + starsAmount.nanos / 1e9);
} }
export function getStarsTransactionFromGift(message: ApiMessage): ApiStarsTransaction | undefined { export function getStarsTransactionFromGift(message: ApiMessage): ApiStarsTransaction | undefined {
@ -264,7 +270,10 @@ export function getStarsTransactionFromGift(message: ApiMessage): ApiStarsTransa
return { return {
id: transactionId!, id: transactionId!,
stars: stars!, stars: {
amount: stars!,
nanos: 0,
},
peer: { peer: {
type: 'peer', type: 'peer',
id: message.isOutgoing ? message.chatId : (message.senderId || message.chatId), id: message.isOutgoing ? message.chatId : (message.senderId || message.chatId),
@ -284,7 +293,10 @@ export function getPrizeStarsTransactionFromGiveaway(message: ApiMessage): ApiSt
return { return {
id: transactionId!, id: transactionId!,
stars: stars!, stars: {
amount: stars!,
nanos: 0,
},
peer: { peer: {
type: 'peer', type: 'peer',
id: targetChatId!, id: targetChatId!,

View File

@ -1,6 +1,7 @@
import type { import type {
ApiReceiptRegular, ApiReceiptRegular,
ApiReceiptStars, ApiReceiptStars,
ApiStarsAmount,
ApiStarsSubscription, ApiStarsSubscription,
ApiStarsTransaction, ApiStarsTransaction,
} from '../../api/types'; } from '../../api/types';
@ -131,7 +132,7 @@ export function closeInvoice<T extends GlobalState>(
} }
export function updateStarsBalance<T extends GlobalState>( export function updateStarsBalance<T extends GlobalState>(
global: T, balance: number, global: T, balance: ApiStarsAmount,
): T { ): T {
return { return {
...global, ...global,
@ -232,7 +233,10 @@ export function openStarsTransactionFromReceipt<T extends GlobalState>(
type: 'peer', type: 'peer',
id: receipt.botId, id: receipt.botId,
}, },
stars: receipt.totalAmount, stars: {
amount: receipt.totalAmount,
nanos: 0,
},
date: receipt.date, date: receipt.date,
title: receipt.title, title: receipt.title,
description: receipt.description, description: receipt.description,

View File

@ -68,6 +68,7 @@ import type {
ApiSponsoredMessage, ApiSponsoredMessage,
ApiStarGift, ApiStarGift,
ApiStarGiveawayOption, ApiStarGiveawayOption,
ApiStarsAmount,
ApiStarsSubscription, ApiStarsSubscription,
ApiStarsTransaction, ApiStarsTransaction,
ApiStarTopupOption, ApiStarTopupOption,
@ -1290,7 +1291,7 @@ export type GlobalState = {
stars?: { stars?: {
topupOptions: ApiStarTopupOption[]; topupOptions: ApiStarTopupOption[];
balance: number; balance: ApiStarsAmount;
history: StarsTransactionHistory; history: StarsTransactionHistory;
subscriptions?: StarsSubscriptions; subscriptions?: StarsSubscriptions;
}; };

View File

@ -1,6 +1,6 @@
const api = require('./api'); const api = require('./api');
const LAYER = 193; const LAYER = 195;
const tlobjects = {}; const tlobjects = {};
for (const tl of Object.values(api)) { for (const tl of Object.values(api)) {

File diff suppressed because one or more lines are too long

View File

@ -125,8 +125,8 @@ messageActionChannelMigrateFrom#ea3948e9 title:string chat_id:long = MessageActi
messageActionPinMessage#94bd38ed = MessageAction; messageActionPinMessage#94bd38ed = MessageAction;
messageActionHistoryClear#9fbab604 = MessageAction; messageActionHistoryClear#9fbab604 = MessageAction;
messageActionGameScore#92a72876 game_id:long score:int = MessageAction; messageActionGameScore#92a72876 game_id:long score:int = MessageAction;
messageActionPaymentSentMe#8f31b327 flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction; messageActionPaymentSentMe#ffa00ccc flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge subscription_until_date:flags.4?int = MessageAction;
messageActionPaymentSent#96163f56 flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long invoice_slug:flags.0?string = MessageAction; messageActionPaymentSent#c624b16e flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long invoice_slug:flags.0?string subscription_until_date:flags.4?int = MessageAction;
messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction; messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
messageActionScreenshotTaken#4792929b = MessageAction; messageActionScreenshotTaken#4792929b = MessageAction;
messageActionCustomAction#fae69f56 message:string = MessageAction; messageActionCustomAction#fae69f56 message:string = MessageAction;
@ -195,7 +195,7 @@ inputReportReasonGeoIrrelevant#dbd4feed = ReportReason;
inputReportReasonFake#f5ddd6e7 = ReportReason; inputReportReasonFake#f5ddd6e7 = ReportReason;
inputReportReasonIllegalDrugs#a8eb2be = ReportReason; inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
inputReportReasonPersonalDetails#9ec7863d = ReportReason; inputReportReasonPersonalDetails#9ec7863d = ReportReason;
userFull#1f58e369 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int = UserFull; userFull#979d2376 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram = UserFull;
contact#145ade0b user_id:long mutual:Bool = Contact; contact#145ade0b user_id:long mutual:Bool = Contact;
importedContact#c13e3c50 user_id:long client_id:long = ImportedContact; importedContact#c13e3c50 user_id:long client_id:long = ImportedContact;
contactStatus#16d9703b user_id:long status:UserStatus = ContactStatus; contactStatus#16d9703b user_id:long status:UserStatus = ContactStatus;
@ -368,12 +368,11 @@ updateBotEditBusinessMessage#7df587c flags:# connection_id:string message:Messag
updateBotDeleteBusinessMessage#a02a982e connection_id:string peer:Peer messages:Vector<int> qts:int = Update; updateBotDeleteBusinessMessage#a02a982e connection_id:string peer:Peer messages:Vector<int> qts:int = Update;
updateNewStoryReaction#1824e40b story_id:int peer:Peer reaction:Reaction = Update; updateNewStoryReaction#1824e40b story_id:int peer:Peer reaction:Reaction = Update;
updateBroadcastRevenueTransactions#dfd961f5 peer:Peer balances:BroadcastRevenueBalances = Update; updateBroadcastRevenueTransactions#dfd961f5 peer:Peer balances:BroadcastRevenueBalances = Update;
updateStarsBalance#fb85198 balance:long = Update; updateStarsBalance#4e80a379 balance:StarsAmount = Update;
updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long connection_id:string message:Message reply_to_message:flags.2?Message chat_instance:long data:flags.0?bytes = Update; updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long connection_id:string message:Message reply_to_message:flags.2?Message chat_instance:long data:flags.0?bytes = Update;
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update; updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update;
updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update; updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update;
updatePaidReactionPrivacy#51ca7aec private:Bool = Update; updatePaidReactionPrivacy#51ca7aec private:Bool = Update;
updateBotSubscriptionExpire#2d13c6ee user_id:long payload:string invoice_slug:string until_date:int qts:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference; updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference; updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
@ -1341,12 +1340,12 @@ starsTransactionPeer#d80da15d peer:Peer = StarsTransactionPeer;
starsTransactionPeerAds#60682812 = StarsTransactionPeer; starsTransactionPeerAds#60682812 = StarsTransactionPeer;
starsTransactionPeerAPI#f9677aad = StarsTransactionPeer; starsTransactionPeerAPI#f9677aad = StarsTransactionPeer;
starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption; starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption;
starsTransaction#35d4f276 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int = StarsTransaction; starsTransaction#64dfc926 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:StarsAmount date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int starref_commission_permille:flags.16?int starref_peer:flags.17?Peer starref_amount:flags.17?StarsAmount = StarsTransaction;
payments.starsStatus#bbfa316c flags:# balance:long subscriptions:flags.1?Vector<StarsSubscription> subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector<StarsTransaction> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.StarsStatus; payments.starsStatus#6c9ce8ed flags:# balance:StarsAmount subscriptions:flags.1?Vector<StarsSubscription> subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector<StarsTransaction> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.StarsStatus;
foundStory#e87acbc0 peer:Peer story:StoryItem = FoundStory; foundStory#e87acbc0 peer:Peer story:StoryItem = FoundStory;
stories.foundStories#e2de7737 flags:# count:int stories:Vector<FoundStory> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = stories.FoundStories; stories.foundStories#e2de7737 flags:# count:int stories:Vector<FoundStory> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = stories.FoundStories;
geoPointAddress#de4c5d93 flags:# country_iso2:string state:flags.0?string city:flags.1?string street:flags.2?string = GeoPointAddress; geoPointAddress#de4c5d93 flags:# country_iso2:string state:flags.0?string city:flags.1?string street:flags.2?string = GeoPointAddress;
starsRevenueStatus#79342946 flags:# withdrawal_enabled:flags.0?true current_balance:long available_balance:long overall_revenue:long next_withdrawal_at:flags.1?int = StarsRevenueStatus; starsRevenueStatus#febe5491 flags:# withdrawal_enabled:flags.0?true current_balance:StarsAmount available_balance:StarsAmount overall_revenue:StarsAmount next_withdrawal_at:flags.1?int = StarsRevenueStatus;
payments.starsRevenueStats#c92bb73b revenue_graph:StatsGraph status:StarsRevenueStatus usd_rate:double = payments.StarsRevenueStats; payments.starsRevenueStats#c92bb73b revenue_graph:StatsGraph status:StarsRevenueStatus usd_rate:double = payments.StarsRevenueStats;
payments.starsRevenueWithdrawalUrl#1dab80b7 url:string = payments.StarsRevenueWithdrawalUrl; payments.starsRevenueWithdrawalUrl#1dab80b7 url:string = payments.StarsRevenueWithdrawalUrl;
payments.starsRevenueAdsAccountUrl#394e7f21 url:string = payments.StarsRevenueAdsAccountUrl; payments.starsRevenueAdsAccountUrl#394e7f21 url:string = payments.StarsRevenueAdsAccountUrl;
@ -1372,6 +1371,13 @@ reportResultReported#8db33c4b = ReportResult;
messages.botPreparedInlineMessage#8ecf0511 id:string expire_date:int = messages.BotPreparedInlineMessage; messages.botPreparedInlineMessage#8ecf0511 id:string expire_date:int = messages.BotPreparedInlineMessage;
messages.preparedInlineMessage#ff57708d query_id:long result:BotInlineResult peer_types:Vector<InlineQueryPeerType> cache_time:int users:Vector<User> = messages.PreparedInlineMessage; messages.preparedInlineMessage#ff57708d query_id:long result:BotInlineResult peer_types:Vector<InlineQueryPeerType> cache_time:int users:Vector<User> = messages.PreparedInlineMessage;
botAppSettings#c99b1950 flags:# placeholder_path:flags.0?bytes background_color:flags.1?int background_dark_color:flags.2?int header_color:flags.3?int header_dark_color:flags.4?int = BotAppSettings; botAppSettings#c99b1950 flags:# placeholder_path:flags.0?bytes background_color:flags.1?int background_dark_color:flags.2?int header_color:flags.3?int header_dark_color:flags.4?int = BotAppSettings;
starRefProgram#dd0c66f2 flags:# bot_id:long commission_permille:int duration_months:flags.0?int end_date:flags.1?int daily_revenue_per_user:flags.2?StarsAmount = StarRefProgram;
connectedBotStarRef#19a13f71 flags:# revoked:flags.1?true url:string date:int bot_id:long commission_permille:int duration_months:flags.0?int participants:long revenue:long = ConnectedBotStarRef;
payments.connectedStarRefBots#98d5ea1d count:int connected_bots:Vector<ConnectedBotStarRef> users:Vector<User> = payments.ConnectedStarRefBots;
payments.suggestedStarRefBots#b4d5d859 flags:# count:int suggested_bots:Vector<StarRefProgram> users:Vector<User> next_offset:flags.0?string = payments.SuggestedStarRefBots;
starsAmount#bbb6b4a3 amount:long nanos:int = StarsAmount;
messages.foundStickersNotModified#6010c534 flags:# next_offset:flags.0?int = messages.FoundStickers;
messages.foundStickers#82c9e290 flags:# next_offset:flags.0?int hash:long stickers:Vector<Document> = messages.FoundStickers;
---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;
@ -1443,7 +1449,7 @@ contacts.block#2e2e8734 flags:# my_stories_from:flags.0?true id:InputPeer = Bool
contacts.unblock#b550d328 flags:# my_stories_from:flags.0?true id:InputPeer = Bool; contacts.unblock#b550d328 flags:# my_stories_from:flags.0?true id:InputPeer = Bool;
contacts.getBlocked#9a868f80 flags:# my_stories_from:flags.0?true offset:int limit:int = contacts.Blocked; contacts.getBlocked#9a868f80 flags:# my_stories_from:flags.0?true offset:int limit:int = contacts.Blocked;
contacts.search#11f812d8 q:string limit:int = contacts.Found; contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer; contacts.resolveUsername#725afbbc flags:# username:string referer:flags.0?string = contacts.ResolvedPeer;
contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers; contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers;
contacts.addContact#e8f463d0 flags:# add_phone_privacy_exception:flags.0?true id:InputUser first_name:string last_name:string phone:string = Updates; contacts.addContact#e8f463d0 flags:# add_phone_privacy_exception:flags.0?true id:InputUser first_name:string last_name:string phone:string = Updates;
contacts.resolvePhone#8af94344 phone:string = contacts.ResolvedPeer; contacts.resolvePhone#8af94344 phone:string = contacts.ResolvedPeer;

View File

@ -151,8 +151,8 @@ messageActionChannelMigrateFrom#ea3948e9 title:string chat_id:long = MessageActi
messageActionPinMessage#94bd38ed = MessageAction; messageActionPinMessage#94bd38ed = MessageAction;
messageActionHistoryClear#9fbab604 = MessageAction; messageActionHistoryClear#9fbab604 = MessageAction;
messageActionGameScore#92a72876 game_id:long score:int = MessageAction; messageActionGameScore#92a72876 game_id:long score:int = MessageAction;
messageActionPaymentSentMe#8f31b327 flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction; messageActionPaymentSentMe#ffa00ccc flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge subscription_until_date:flags.4?int = MessageAction;
messageActionPaymentSent#96163f56 flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long invoice_slug:flags.0?string = MessageAction; messageActionPaymentSent#c624b16e flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long invoice_slug:flags.0?string subscription_until_date:flags.4?int = MessageAction;
messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction; messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
messageActionScreenshotTaken#4792929b = MessageAction; messageActionScreenshotTaken#4792929b = MessageAction;
messageActionCustomAction#fae69f56 message:string = MessageAction; messageActionCustomAction#fae69f56 message:string = MessageAction;
@ -235,7 +235,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason;
inputReportReasonIllegalDrugs#a8eb2be = ReportReason; inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
inputReportReasonPersonalDetails#9ec7863d = ReportReason; inputReportReasonPersonalDetails#9ec7863d = ReportReason;
userFull#1f58e369 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int = UserFull; userFull#979d2376 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram = UserFull;
contact#145ade0b user_id:long mutual:Bool = Contact; contact#145ade0b user_id:long mutual:Bool = Contact;
@ -421,12 +421,11 @@ updateBotEditBusinessMessage#7df587c flags:# connection_id:string message:Messag
updateBotDeleteBusinessMessage#a02a982e connection_id:string peer:Peer messages:Vector<int> qts:int = Update; updateBotDeleteBusinessMessage#a02a982e connection_id:string peer:Peer messages:Vector<int> qts:int = Update;
updateNewStoryReaction#1824e40b story_id:int peer:Peer reaction:Reaction = Update; updateNewStoryReaction#1824e40b story_id:int peer:Peer reaction:Reaction = Update;
updateBroadcastRevenueTransactions#dfd961f5 peer:Peer balances:BroadcastRevenueBalances = Update; updateBroadcastRevenueTransactions#dfd961f5 peer:Peer balances:BroadcastRevenueBalances = Update;
updateStarsBalance#fb85198 balance:long = Update; updateStarsBalance#4e80a379 balance:StarsAmount = Update;
updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long connection_id:string message:Message reply_to_message:flags.2?Message chat_instance:long data:flags.0?bytes = Update; updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long connection_id:string message:Message reply_to_message:flags.2?Message chat_instance:long data:flags.0?bytes = Update;
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update; updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update;
updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update; updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update;
updatePaidReactionPrivacy#51ca7aec private:Bool = Update; updatePaidReactionPrivacy#51ca7aec private:Bool = Update;
updateBotSubscriptionExpire#2d13c6ee user_id:long payload:string invoice_slug:string until_date:int qts:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -1832,9 +1831,9 @@ starsTransactionPeerAPI#f9677aad = StarsTransactionPeer;
starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption; starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption;
starsTransaction#35d4f276 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int = StarsTransaction; starsTransaction#64dfc926 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:StarsAmount date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int starref_commission_permille:flags.16?int starref_peer:flags.17?Peer starref_amount:flags.17?StarsAmount = StarsTransaction;
payments.starsStatus#bbfa316c flags:# balance:long subscriptions:flags.1?Vector<StarsSubscription> subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector<StarsTransaction> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.StarsStatus; payments.starsStatus#6c9ce8ed flags:# balance:StarsAmount subscriptions:flags.1?Vector<StarsSubscription> subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector<StarsTransaction> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.StarsStatus;
foundStory#e87acbc0 peer:Peer story:StoryItem = FoundStory; foundStory#e87acbc0 peer:Peer story:StoryItem = FoundStory;
@ -1842,7 +1841,7 @@ stories.foundStories#e2de7737 flags:# count:int stories:Vector<FoundStory> next_
geoPointAddress#de4c5d93 flags:# country_iso2:string state:flags.0?string city:flags.1?string street:flags.2?string = GeoPointAddress; geoPointAddress#de4c5d93 flags:# country_iso2:string state:flags.0?string city:flags.1?string street:flags.2?string = GeoPointAddress;
starsRevenueStatus#79342946 flags:# withdrawal_enabled:flags.0?true current_balance:long available_balance:long overall_revenue:long next_withdrawal_at:flags.1?int = StarsRevenueStatus; starsRevenueStatus#febe5491 flags:# withdrawal_enabled:flags.0?true current_balance:StarsAmount available_balance:StarsAmount overall_revenue:StarsAmount next_withdrawal_at:flags.1?int = StarsRevenueStatus;
payments.starsRevenueStats#c92bb73b revenue_graph:StatsGraph status:StarsRevenueStatus usd_rate:double = payments.StarsRevenueStats; payments.starsRevenueStats#c92bb73b revenue_graph:StatsGraph status:StarsRevenueStatus usd_rate:double = payments.StarsRevenueStats;
@ -1891,6 +1890,19 @@ messages.preparedInlineMessage#ff57708d query_id:long result:BotInlineResult pee
botAppSettings#c99b1950 flags:# placeholder_path:flags.0?bytes background_color:flags.1?int background_dark_color:flags.2?int header_color:flags.3?int header_dark_color:flags.4?int = BotAppSettings; botAppSettings#c99b1950 flags:# placeholder_path:flags.0?bytes background_color:flags.1?int background_dark_color:flags.2?int header_color:flags.3?int header_dark_color:flags.4?int = BotAppSettings;
starRefProgram#dd0c66f2 flags:# bot_id:long commission_permille:int duration_months:flags.0?int end_date:flags.1?int daily_revenue_per_user:flags.2?StarsAmount = StarRefProgram;
connectedBotStarRef#19a13f71 flags:# revoked:flags.1?true url:string date:int bot_id:long commission_permille:int duration_months:flags.0?int participants:long revenue:long = ConnectedBotStarRef;
payments.connectedStarRefBots#98d5ea1d count:int connected_bots:Vector<ConnectedBotStarRef> users:Vector<User> = payments.ConnectedStarRefBots;
payments.suggestedStarRefBots#b4d5d859 flags:# count:int suggested_bots:Vector<StarRefProgram> users:Vector<User> next_offset:flags.0?string = payments.SuggestedStarRefBots;
starsAmount#bbb6b4a3 amount:long nanos:int = StarsAmount;
messages.foundStickersNotModified#6010c534 flags:# next_offset:flags.0?int = messages.FoundStickers;
messages.foundStickers#82c9e290 flags:# next_offset:flags.0?int hash:long stickers:Vector<Document> = messages.FoundStickers;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -2056,7 +2068,7 @@ contacts.block#2e2e8734 flags:# my_stories_from:flags.0?true id:InputPeer = Bool
contacts.unblock#b550d328 flags:# my_stories_from:flags.0?true id:InputPeer = Bool; contacts.unblock#b550d328 flags:# my_stories_from:flags.0?true id:InputPeer = Bool;
contacts.getBlocked#9a868f80 flags:# my_stories_from:flags.0?true offset:int limit:int = contacts.Blocked; contacts.getBlocked#9a868f80 flags:# my_stories_from:flags.0?true offset:int limit:int = contacts.Blocked;
contacts.search#11f812d8 q:string limit:int = contacts.Found; contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer; contacts.resolveUsername#725afbbc flags:# username:string referer:flags.0?string = contacts.ResolvedPeer;
contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers; contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers;
contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool; contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool;
contacts.resetSaved#879537f1 = Bool; contacts.resetSaved#879537f1 = Bool;
@ -2296,6 +2308,7 @@ messages.reportSponsoredMessage#1af3dbb8 peer:InputPeer random_id:bytes option:b
messages.getSponsoredMessages#9bd2f439 peer:InputPeer = messages.SponsoredMessages; messages.getSponsoredMessages#9bd2f439 peer:InputPeer = messages.SponsoredMessages;
messages.savePreparedInlineMessage#f21f7f2f flags:# result:InputBotInlineResult user_id:InputUser peer_types:flags.0?Vector<InlineQueryPeerType> = messages.BotPreparedInlineMessage; messages.savePreparedInlineMessage#f21f7f2f flags:# result:InputBotInlineResult user_id:InputUser peer_types:flags.0?Vector<InlineQueryPeerType> = messages.BotPreparedInlineMessage;
messages.getPreparedInlineMessage#857ebdb8 bot:InputUser id:string = messages.PreparedInlineMessage; messages.getPreparedInlineMessage#857ebdb8 bot:InputUser id:string = messages.PreparedInlineMessage;
messages.searchStickers#29b1c66a flags:# emojis:flags.0?true q:string emoticon:string lang_code:Vector<string> offset:int limit:int hash:long = messages.FoundStickers;
updates.getState#edd4882a = updates.State; updates.getState#edd4882a = updates.State;
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference; updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
@ -2430,6 +2443,8 @@ bots.getPreviewMedias#a2a5594d bot:InputUser = Vector<BotPreviewMedia>;
bots.updateUserEmojiStatus#ed9f30c5 user_id:InputUser emoji_status:EmojiStatus = Bool; bots.updateUserEmojiStatus#ed9f30c5 user_id:InputUser emoji_status:EmojiStatus = Bool;
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.getAdminedBots#b0711d83 = Vector<User>;
bots.updateStarRefProgram#778b5ab3 flags:# bot:InputUser commission_permille:int duration_months:flags.0?int = StarRefProgram;
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;
@ -2465,7 +2480,12 @@ payments.getStarGifts#c4563590 hash:int = payments.StarGifts;
payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts; payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts;
payments.saveStarGift#87acf08e flags:# unsave:flags.0?true user_id:InputUser msg_id:int = Bool; payments.saveStarGift#87acf08e flags:# unsave:flags.0?true user_id:InputUser msg_id:int = Bool;
payments.convertStarGift#421e027 user_id:InputUser msg_id:int = Bool; payments.convertStarGift#421e027 user_id:InputUser msg_id:int = Bool;
payments.botCancelStarsSubscription#57f9ece6 flags:# restore:flags.0?true user_id:InputUser invoice_slug:flags.1?string charge_id:flags.2?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.getConnectedStarRefBot#b7d998f0 peer:InputPeer bot:InputUser = payments.ConnectedStarRefBots;
payments.getSuggestedStarRefBots#d6b48f7 flags:# order_by_revenue:flags.0?true order_by_date:flags.1?true peer:InputPeer offset:string limit:int = payments.SuggestedStarRefBots;
payments.connectStarRefBot#7ed5348a peer:InputPeer bot:InputUser = payments.ConnectedStarRefBots;
payments.editConnectedStarRefBot#e4fca4a3 flags:# revoked:flags.0?true peer:InputPeer link:string = payments.ConnectedStarRefBots;
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;

View File

@ -1145,6 +1145,7 @@ export interface LangPair {
'StarGiftAvailability': undefined; 'StarGiftAvailability': undefined;
'StarsSubscribeInfoLinkText': undefined; 'StarsSubscribeInfoLinkText': undefined;
'StarsSubscribeInfoLink': undefined; 'StarsSubscribeInfoLink': undefined;
'StarsBalance': undefined;
'OpenApp': undefined; 'OpenApp': undefined;
'PopularApps': undefined; 'PopularApps': undefined;
'SearchApps': undefined; 'SearchApps': undefined;

View File

@ -32,7 +32,7 @@ export function formatCurrencyAsString(
) { ) {
const price = totalPrice / 10 ** getCurrencyExp(currency); const price = totalPrice / 10 ** getCurrencyExp(currency);
if ((options?.shouldOmitFractions || currency === STARS_CURRENCY_CODE) && price % 1 === 0) { if ((options?.shouldOmitFractions || currency === STARS_CURRENCY_CODE) && Number.isInteger(price)) {
return new Intl.NumberFormat(locale, { return new Intl.NumberFormat(locale, {
style: 'currency', style: 'currency',
currency, currency,

View File

@ -29,6 +29,10 @@ export function formatIntegerCompact(views: number) {
return `${formatFixedNumber(views / 1e6)}M`; return `${formatFixedNumber(views / 1e6)}M`;
} }
export function formatPercent(value: number, fractionDigits = 1) {
return `${Number.isInteger(value) ? value : value.toFixed(fractionDigits)}%`;
}
export const getFirstLetters = withCache((phrase: string, count = 2) => { export const getFirstLetters = withCache((phrase: string, count = 2) => {
return phrase return phrase
.replace(/[.,!@#$%^&*()_+=\-`~[\]/\\{}:"|<>?]+/gi, '') .replace(/[.,!@#$%^&*()_+=\-`~[\]/\\{}:"|<>?]+/gi, '')