Paid Reactions: Support peers (#5581)

This commit is contained in:
Alexander Zinchuk 2025-03-01 17:58:56 +01:00
parent 47fcfd9e96
commit 8a2f067c9b
24 changed files with 417 additions and 75 deletions

View File

@ -4,6 +4,7 @@ import type {
ApiAvailableEffect, ApiAvailableEffect,
ApiAvailableReaction, ApiAvailableReaction,
ApiMessageReactor, ApiMessageReactor,
ApiPaidReactionPrivacyType,
ApiPeerReaction, ApiPeerReaction,
ApiReaction, ApiReaction,
ApiReactionCount, ApiReactionCount,
@ -66,7 +67,7 @@ export function buildApiMessageReactor(reactor: GramJs.MessageReactor): ApiMessa
return { return {
peerId: peerId && getApiChatIdFromMtpPeer(peerId), peerId: peerId && getApiChatIdFromMtpPeer(peerId),
count, count,
isMe: my, isMy: my,
isTop: top, isTop: top,
isAnonymous: anonymous, isAnonymous: anonymous,
}; };
@ -164,3 +165,18 @@ export function buildApiAvailableEffect(availableEffect: GramJs.AvailableEffect)
effectAnimationId: effectAnimationId?.toString(), effectAnimationId: effectAnimationId?.toString(),
}; };
} }
export function buildApiPaidReactionPrivacy(privacy: GramJs.TypePaidReactionPrivacy) : ApiPaidReactionPrivacyType {
if (privacy instanceof GramJs.PaidReactionPrivacyAnonymous) {
return { type: 'anonymous' };
}
if (privacy instanceof GramJs.PaidReactionPrivacyPeer) {
return {
type: 'peer',
peerId: getApiChatIdFromMtpPeer(privacy.peer),
};
}
return { type: 'default' };
}

View File

@ -93,6 +93,19 @@ export function buildInputPeer(chatOrUserId: string, accessHash?: string): GramJ
} }
} }
export function buildInputPaidReactionPrivacy(isPrivate?: boolean, peerId?: string): GramJs.TypeInputPeer {
if (isPrivate) return new GramJs.PaidReactionPrivacyAnonymous();
if (peerId) {
const peer = buildInputPeerFromLocalDb(peerId);
if (peer) {
return new GramJs.PaidReactionPrivacyPeer({
peer,
});
}
}
return new GramJs.PaidReactionPrivacyDefault();
}
export function buildInputPeerFromLocalDb(chatOrUserId: string): GramJs.TypeInputPeer | undefined { export function buildInputPeerFromLocalDb(chatOrUserId: string): GramJs.TypeInputPeer | undefined {
const type = getEntityTypeById(chatOrUserId); const type = getEntityTypeById(chatOrUserId);
let accessHash: BigInt.BigInteger | undefined; let accessHash: BigInt.BigInteger | undefined;

View File

@ -1719,10 +1719,13 @@ export async function fetchSeenBy({ chat, messageId }: { chat: ApiChat; messageI
export async function fetchSendAs({ export async function fetchSendAs({
chat, chat,
isForPaidReactions,
}: { }: {
isForPaidReactions?: true;
chat: ApiChat; chat: ApiChat;
}) { }) {
const result = await invokeRequest(new GramJs.channels.GetSendAs({ const result = await invokeRequest(new GramJs.channels.GetSendAs({
forPaidReactions: isForPaidReactions,
peer: buildInputPeer(chat.id, chat.accessHash), peer: buildInputPeer(chat.id, chat.accessHash),
}), { }), {
shouldIgnoreErrors: true, shouldIgnoreErrors: true,
@ -1733,9 +1736,7 @@ export async function fetchSendAs({
return undefined; return undefined;
} }
return { return result.peers.map(buildApiSendAsPeerId);
sendAs: result.peers.map(buildApiSendAsPeerId),
};
} }
export function saveDefaultSendAs({ export function saveDefaultSendAs({

View File

@ -20,7 +20,9 @@ import {
buildMessagePeerReaction, buildMessagePeerReaction,
} from '../apiBuilders/reactions'; } from '../apiBuilders/reactions';
import { buildStickerFromDocument } from '../apiBuilders/symbols'; import { buildStickerFromDocument } from '../apiBuilders/symbols';
import { buildInputPeer, buildInputReaction, generateRandomTimestampedBigInt } from '../gramjsBuilders'; import {
buildInputPaidReactionPrivacy, buildInputPeer, buildInputReaction, generateRandomTimestampedBigInt,
} from '../gramjsBuilders';
import localDb from '../localDb'; import localDb from '../localDb';
import { invokeRequest } from './client'; import { invokeRequest } from './client';
@ -155,18 +157,20 @@ export function sendPaidReaction({
messageId, messageId,
count, count,
isPrivate, isPrivate,
peerId,
}: { }: {
chat: ApiChat; chat: ApiChat;
messageId: number; messageId: number;
count: number; count: number;
isPrivate?: boolean; isPrivate?: boolean;
peerId?: string;
}) { }) {
return invokeRequest(new GramJs.messages.SendPaidReaction({ return invokeRequest(new GramJs.messages.SendPaidReaction({
peer: buildInputPeer(chat.id, chat.accessHash), peer: buildInputPeer(chat.id, chat.accessHash),
msgId: messageId, msgId: messageId,
randomId: generateRandomTimestampedBigInt(), randomId: generateRandomTimestampedBigInt(),
count, count,
private: isPrivate || undefined, private: buildInputPaidReactionPrivacy(isPrivate, peerId),
}), { }), {
shouldReturnTrue: true, shouldReturnTrue: true,
shouldThrow: true, shouldThrow: true,

View File

@ -55,6 +55,7 @@ import {
import { buildApiStarsAmount } from '../apiBuilders/payments'; import { buildApiStarsAmount } from '../apiBuilders/payments';
import { buildApiEmojiStatus, buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers'; import { buildApiEmojiStatus, buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
import { import {
buildApiPaidReactionPrivacy,
buildApiReaction, buildApiReaction,
buildMessageReactions, buildMessageReactions,
} from '../apiBuilders/reactions'; } from '../apiBuilders/reactions';
@ -1071,7 +1072,7 @@ export function updater(update: Update) {
} else if (update instanceof GramJs.UpdatePaidReactionPrivacy) { } else if (update instanceof GramJs.UpdatePaidReactionPrivacy) {
sendApiUpdate({ sendApiUpdate({
'@type': 'updatePaidReactionPrivacy', '@type': 'updatePaidReactionPrivacy',
isPrivate: update.private, private: buildApiPaidReactionPrivacy(update.private),
}); });
} else if (update instanceof GramJs.UpdateLangPackTooLong) { } else if (update instanceof GramJs.UpdateLangPackTooLong) {
sendApiUpdate({ sendApiUpdate({

View File

@ -77,6 +77,8 @@ export interface ApiChat {
isJoinToSend?: boolean; isJoinToSend?: boolean;
isJoinRequest?: boolean; isJoinRequest?: boolean;
sendAsPeerIds?: ApiSendAsPeerId[]; sendAsPeerIds?: ApiSendAsPeerId[];
sendPaidReactionsAsPeerIds?: ApiSendAsPeerId[];
sendPaidReactionsPeer?: ApiSendAsPeerId;
unreadReactions?: number[]; unreadReactions?: number[];
unreadMentions?: number[]; unreadMentions?: number[];

View File

@ -675,7 +675,7 @@ export interface ApiPeerReaction {
export interface ApiMessageReactor { export interface ApiMessageReactor {
isTop?: true; isTop?: true;
isMe?: true; isMy?: true;
count: number; count: number;
isAnonymous?: true; isAnonymous?: true;
peerId?: string; peerId?: string;
@ -687,6 +687,7 @@ export interface ApiReactionCount {
reaction: ApiReactionWithPaid; reaction: ApiReactionWithPaid;
localAmount?: number; localAmount?: number;
localIsPrivate?: boolean; localIsPrivate?: boolean;
localPeerId?: string;
localPreviousChosenOrder?: number; localPreviousChosenOrder?: number;
} }
@ -750,6 +751,22 @@ export type ApiSavedReactionTag = {
count: number; count: number;
}; };
export type ApiPaidReactionPrivacyType = ApiPaidReactionPrivacyDefault |
ApiPaidReactionPrivacyAnonymous | PaidReactionPrivacyPeer;
export type ApiPaidReactionPrivacyDefault = {
type: 'default';
};
export type ApiPaidReactionPrivacyAnonymous = {
type: 'anonymous';
};
export type PaidReactionPrivacyPeer = {
type: 'peer';
peerId: string;
};
interface ApiBaseThreadInfo { interface ApiBaseThreadInfo {
chatId: string; chatId: string;
messagesCount: number; messagesCount: number;

View File

@ -24,6 +24,7 @@ import type {
ApiFormattedText, ApiFormattedText,
ApiMediaExtendedPreview, ApiMediaExtendedPreview,
ApiMessage, ApiMessage,
ApiPaidReactionPrivacyType,
ApiPhoto, ApiPhoto,
ApiPoll, ApiPoll,
ApiQuickReply, ApiQuickReply,
@ -789,7 +790,7 @@ export type ApiUpdateEntities = {
export type ApiUpdatePaidReactionPrivacy = { export type ApiUpdatePaidReactionPrivacy = {
'@type': 'updatePaidReactionPrivacy'; '@type': 'updatePaidReactionPrivacy';
isPrivate: boolean; private: ApiPaidReactionPrivacyType;
}; };
export type ApiUpdateLangPackTooLong = { export type ApiUpdateLangPackTooLong = {

View File

@ -1633,3 +1633,5 @@
"UniqueStatusProofOfOwnershipDescription" = "Tapping the icon of this item next to your name will show its info and owner."; "UniqueStatusProofOfOwnershipDescription" = "Tapping the icon of this item next to your name will show its info and owner.";
"UniqueStatusWearButton" = "Start Wearing"; "UniqueStatusWearButton" = "Start Wearing";
"CollectibleStatusesCategory" = "Collectibles"; "CollectibleStatusesCategory" = "Collectibles";
"PeerPersonalAccount" = "personal account";
"PeerChannel" = "channel";

View File

@ -2,6 +2,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 0.25rem; gap: 0.25rem;
max-height: min(92vh, 38rem) !important;
} }
.title { .title {
@ -11,7 +12,7 @@
} }
.slider { .slider {
margin-top: 1.5rem; margin-top: 2rem;
flex-shrink: 0; flex-shrink: 0;
} }
@ -23,13 +24,75 @@
text-align: center; text-align: center;
} }
.modalBalance { .itemInfo {
flex-grow: 1;
overflow: hidden;
height: auto;
display: flex;
flex-direction: column;
margin-left: 0.5rem;
}
.itemTitle {
line-height: 1rem;
margin-bottom: 0.125rem;
}
.itemSubtitle {
font-size: 0.9375rem;
color: var(--color-text-secondary);
line-height: 1rem;
}
.itemIcon {
margin-left: 0.5rem;
margin-right: 0 !important;
}
.sendAsPeerMenuButton {
margin-right: 0.25rem;
border-radius: 1.5rem;
padding: 0.25rem !important;
width: auto;
height: auto !important;
background-color: var(--color-background-secondary) !important;
:active,
:hover {
background-color: var(--color-interactive-element-hover) !important;
}
}
.buttonDownIcon {
margin-left: 0.25rem;
margin-right: 0.125rem;
}
.sendAsPeerMenuBubble {
max-width: 16rem;
}
.sendAsPeerMenu {
margin-right: 0.25rem;
}
.headerControlPanel {
display: flex;
align-items: center;
position: absolute; position: absolute;
top: 0.75rem; top: 0.75rem;
right: 1.25rem; right: 1.25rem;
z-index: 3; z-index: 3;
} }
.separator {
margin-top: 1rem;
}
.checkBox {
margin-block: 0.25rem !important;
}
.topLabel { .topLabel {
background-image: var(--stars-gradient); background-image: var(--stars-gradient);
color: var(--color-white); color: var(--color-white);
@ -61,5 +124,6 @@
font-size: 0.875rem; font-size: 0.875rem;
align-self: center; align-self: center;
color: var(--color-text-secondary); color: var(--color-text-secondary);
margin-bottom: 0; margin-top: 0.5rem;
margin-bottom: 0.125rem;
} }

View File

@ -1,30 +1,43 @@
import type { FC } from '../../../lib/teact/teact';
import React, { import React, {
memo, useEffect, useMemo, useState, memo, useEffect, useMemo, useState,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../global'; import { getActions, getGlobal, withGlobal } from '../../../global';
import type { import type {
ApiChat, ApiMessage, ApiStarsAmount, ApiUser, ApiChat, ApiMessage, ApiPaidReactionPrivacyType,
ApiPeer,
ApiSendAsPeerId,
ApiStarsAmount, ApiUser,
} from '../../../api/types'; } 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';
import { STARS_ICON_PLACEHOLDER } from '../../../config'; import { STARS_ICON_PLACEHOLDER } from '../../../config';
import { getChatTitle, getUserFullName } from '../../../global/helpers'; import { getPeerTitle } from '../../../global/helpers';
import { selectChat, selectChatMessage, selectUser } from '../../../global/selectors'; import { isApiPeerUser } from '../../../global/helpers/peers';
import {
selectChat, selectChatMessage, selectPeer, selectUser,
} from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName';
import { formatInteger } from '../../../util/textFormat'; import { formatInteger } from '../../../util/textFormat';
import renderText from '../../common/helpers/renderText'; import renderText from '../../common/helpers/renderText';
import useAppLayout from '../../../hooks/useAppLayout';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import useLang from '../../../hooks/useLang'; 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 Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon'; import Icon from '../../common/icons/Icon';
import PeerBadge from '../../common/PeerBadge'; import PeerBadge from '../../common/PeerBadge';
import SafeLink from '../../common/SafeLink'; import SafeLink from '../../common/SafeLink';
import Button from '../../ui/Button'; import Button from '../../ui/Button';
import Checkbox from '../../ui/Checkbox'; import Checkbox from '../../ui/Checkbox';
import DropdownMenu from '../../ui/DropdownMenu';
import MenuItem from '../../ui/MenuItem';
import Modal from '../../ui/Modal'; import Modal from '../../ui/Modal';
import Separator from '../../ui/Separator'; import Separator from '../../ui/Separator';
import BalanceBlock from '../stars/BalanceBlock'; import BalanceBlock from '../stars/BalanceBlock';
@ -41,15 +54,18 @@ type StateProps = {
chat?: ApiChat; chat?: ApiChat;
maxAmount: number; maxAmount: number;
starBalance?: ApiStarsAmount; starBalance?: ApiStarsAmount;
defaultPrivacy?: boolean; defaultPrivacy?: ApiPaidReactionPrivacyType;
sendPaidReactionsAsPeerIds?: ApiSendAsPeerId[];
currentUserId: string;
currentUser: ApiUser;
}; };
type ReactorData = { type ReactorData = {
amount: number; amount: number;
localAmount: number; localAmount: number;
isMe?: boolean; isMy?: boolean;
isAnonymous?: boolean; isAnonymous?: boolean;
user?: ApiUser; user?: ApiPeer;
}; };
const MAX_TOP_REACTORS = 3; const MAX_TOP_REACTORS = 3;
@ -69,18 +85,27 @@ const PaidReactionModal = ({
maxAmount, maxAmount,
starBalance, starBalance,
defaultPrivacy, defaultPrivacy,
sendPaidReactionsAsPeerIds,
currentUserId,
currentUser,
}: OwnProps & StateProps) => { }: OwnProps & StateProps) => {
const { closePaidReactionModal, addLocalPaidReaction } = getActions(); const { closePaidReactionModal, addLocalPaidReaction, loadSendPaidReactionsAs } = getActions();
const [starsAmount, setStarsAmount] = useState(DEFAULT_STARS_AMOUNT); const [starsAmount, setStarsAmount] = useState(DEFAULT_STARS_AMOUNT);
const [isTouched, markTouched, unmarkTouched] = useFlag(); const [isTouched, markTouched, unmarkTouched] = useFlag();
const [shouldShowUp, setShouldShowUp] = useState(true); const [shouldSendAsAnonymous, setShouldSendAsAnonymous] = useState(true);
const [sendAsPeerId, setSendAsPeerId] = useState(currentUserId);
const chatId = chat?.id;
const senderPeer = sendAsPeerId ? (selectPeer(getGlobal(), sendAsPeerId)) : currentUser;
const oldLang = useOldLang(); const oldLang = useOldLang();
const { isMobile } = useAppLayout();
const lang = useLang(); const lang = useLang();
const handleAnonimityChange = useLastCallback((e: React.ChangeEvent<HTMLInputElement>) => { const handleShowInTopSendersChange = useLastCallback((e: React.ChangeEvent<HTMLInputElement>) => {
setShouldShowUp(e.target.checked); setShouldSendAsAnonymous(!e.target.checked);
}); });
const handleAmountChange = useLastCallback((value: number) => { const handleAmountChange = useLastCallback((value: number) => {
@ -88,6 +113,21 @@ const PaidReactionModal = ({
markTouched(); markTouched();
}); });
useEffect(() => {
if (chatId && !sendPaidReactionsAsPeerIds) {
loadSendPaidReactionsAs({ chatId });
}
}, [chatId, sendPaidReactionsAsPeerIds]);
const filteredMyReactorIds = useMemo(() => {
const result = sendPaidReactionsAsPeerIds?.map((peer) => peer.id)
.filter((id) => id !== chatId);
result?.unshift(currentUserId);
return result;
}, [sendPaidReactionsAsPeerIds, chatId, currentUserId]);
const canChangeSendAsPeer = filteredMyReactorIds && filteredMyReactorIds.length > 1;
useEffect(() => { useEffect(() => {
if (!modal) { if (!modal) {
unmarkTouched(); unmarkTouched();
@ -95,14 +135,23 @@ const PaidReactionModal = ({
}, [modal]); }, [modal]);
useEffect(() => { useEffect(() => {
const currentReactor = message?.reactions?.topReactors?.find((reactor) => reactor.isMe); const currentReactor = message?.reactions?.topReactors?.find((reactor) => reactor.isMy);
if (currentReactor) { if (currentReactor) {
setShouldShowUp(!currentReactor.isAnonymous); setShouldSendAsAnonymous(Boolean(currentReactor.isAnonymous));
if (currentReactor.peerId) {
setSendAsPeerId(currentReactor.peerId);
}
return; return;
} }
setShouldShowUp(defaultPrivacy || true); setShouldSendAsAnonymous(defaultPrivacy?.type === 'anonymous' || false);
}, [defaultPrivacy, message?.reactions?.topReactors]); if (defaultPrivacy?.type === 'peer' && filteredMyReactorIds?.includes(defaultPrivacy.peerId)) {
setSendAsPeerId(defaultPrivacy.peerId);
return;
}
setSendAsPeerId(currentUserId);
}, [defaultPrivacy, message?.reactions?.topReactors, filteredMyReactorIds, currentUserId]);
const handleSend = useLastCallback(() => { const handleSend = useLastCallback(() => {
if (!modal) return; if (!modal) return;
@ -111,11 +160,85 @@ const PaidReactionModal = ({
chatId: modal.chatId, chatId: modal.chatId,
messageId: modal.messageId, messageId: modal.messageId,
count: starsAmount, count: starsAmount,
isPrivate: !shouldShowUp, isPrivate: shouldSendAsAnonymous,
peerId: shouldSendAsAnonymous || sendAsPeerId === currentUserId ? undefined : sendAsPeerId,
shouldIgnoreDefaultPrivacy: true,
}); });
closePaidReactionModal(); closePaidReactionModal();
}); });
const handleSendAsPeerChange = useLastCallback((peerId: string) => {
setShouldSendAsAnonymous(false);
setSendAsPeerId(peerId);
});
const renderMenuItem = useLastCallback((peerId: string) => {
const peer = selectPeer(getGlobal(), peerId);
const isSelected = sendAsPeerId === peerId && !shouldSendAsAnonymous;
if (!peer) return undefined;
return (
<MenuItem
// eslint-disable-next-line react/jsx-no-bind
onClick={() => handleSendAsPeerChange(peerId)}
>
<Avatar
size="small"
peer={peer}
/>
<div className={buildClassName(styles.itemInfo)}>
<FullNameTitle className={styles.itemTitle} peer={peer} noFake noVerified />
<span className={styles.itemSubtitle}>
{isApiPeerUser(peer) ? lang('PeerPersonalAccount') : lang('PeerChannel')}
</span>
</div>
<Icon
className={styles.itemIcon}
name={isSelected ? 'check' : 'placeholder'}
/>
</MenuItem>
);
});
const SendAsPeerMenuButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => {
return ({ onTrigger, isOpen }) => (
<Button
ripple={!isMobile}
size="smaller"
color="translucent"
className={buildClassName(styles.sendAsPeerMenuButton, isOpen ? 'active' : '')}
onClick={onTrigger}
ariaLabel={lang('AccDescrOpenMenu2')}
>
<Avatar
size="mini"
peer={shouldSendAsAnonymous ? ANONYMOUS_PEER : senderPeer}
/>
<Icon
name="down"
className={styles.buttonDownIcon}
/>
</Button>
);
}, [isMobile, lang, senderPeer, shouldSendAsAnonymous]);
const sendAsPeersMenu = useMemo(() => {
if (!canChangeSendAsPeer) return undefined;
return (
<DropdownMenu
className={styles.sendAsPeerMenu}
bubbleClassName={styles.sendAsPeerMenuBubble}
trigger={SendAsPeerMenuButton}
positionX="right"
autoClose
>
{filteredMyReactorIds.map((id) => (
renderMenuItem(id)
))}
</DropdownMenu>
);
}, [SendAsPeerMenuButton, filteredMyReactorIds, canChangeSendAsPeer]);
const topReactors = useMemo(() => { const topReactors = useMemo(() => {
const global = getGlobal(); const global = getGlobal();
const all = message?.reactions?.topReactors; const all = message?.reactions?.topReactors;
@ -124,41 +247,49 @@ const PaidReactionModal = ({
} }
const result: ReactorData[] = []; const result: ReactorData[] = [];
let hasMe = false; let hasCurrentSender = false;
let myReactorAmount = 0;
all.forEach((reactor) => { all.forEach((reactor) => {
const user = reactor.peerId ? selectUser(global, reactor.peerId) : undefined; const peer = reactor.peerId ? selectPeer(global, reactor.peerId) : undefined;
if (!user && !reactor.isAnonymous && !reactor.isMe) return; if (!peer && !reactor.isAnonymous && !reactor.isMy) return;
if (reactor.isMy) {
myReactorAmount = reactor.count;
}
if (reactor.isMe) { if (reactor.isMy && (reactor.peerId !== sendAsPeerId || (reactor.isAnonymous && !shouldSendAsAnonymous))) return;
hasMe = true;
const isCurrentReactor = sendAsPeerId === reactor.peerId || (shouldSendAsAnonymous && reactor.isAnonymous);
if (isCurrentReactor) {
hasCurrentSender = true;
} }
result.push({ result.push({
amount: reactor.count, amount: reactor.count,
localAmount: reactor.isMe && isTouched ? starsAmount : 0, localAmount: isCurrentReactor && isTouched ? starsAmount : 0,
isMe: reactor.isMe, isMy: reactor.isMy,
isAnonymous: reactor.isAnonymous, isAnonymous: reactor.isAnonymous,
user, user: peer,
}); });
}); });
if (!hasMe && isTouched) { if (!hasCurrentSender) {
const me = selectUser(global, global.currentUserId!); const sender = selectPeer(global, sendAsPeerId);
result.push({ result.push({
amount: 0, amount: myReactorAmount,
localAmount: starsAmount, localAmount: isTouched ? starsAmount : 0,
isMe: true, isMy: true,
user: me, user: sender,
}); });
} }
result.sort((a, b) => (b.amount + b.localAmount) - (a.amount + a.localAmount)); result.sort((a, b) => (b.amount + b.localAmount) - (a.amount + a.localAmount));
return result.slice(0, MAX_TOP_REACTORS); return result.slice(0, MAX_TOP_REACTORS);
}, [isTouched, message?.reactions?.topReactors, starsAmount]); }, [isTouched, message?.reactions?.topReactors, starsAmount, sendAsPeerId, shouldSendAsAnonymous]);
const chatTitle = chat && getChatTitle(oldLang, chat); const chatTitle = chat && getPeerTitle(oldLang, chat);
return ( return (
<Modal <Modal
@ -168,7 +299,10 @@ const PaidReactionModal = ({
hasAbsoluteCloseButton hasAbsoluteCloseButton
contentClassName={styles.content} contentClassName={styles.content}
> >
<BalanceBlock balance={starBalance} className={styles.modalBalance} /> <div className={styles.headerControlPanel}>
{sendAsPeersMenu}
<BalanceBlock balance={starBalance} className={styles.modalBalance} />
</div>
<StarSlider <StarSlider
className={styles.slider} className={styles.slider}
defaultValue={DEFAULT_STARS_AMOUNT} defaultValue={DEFAULT_STARS_AMOUNT}
@ -186,9 +320,10 @@ const PaidReactionModal = ({
<div className={styles.top}> <div className={styles.top}>
{topReactors.map((reactor) => { {topReactors.map((reactor) => {
const countText = formatInteger(reactor.amount + reactor.localAmount); const countText = formatInteger(reactor.amount + reactor.localAmount);
const peer = (reactor.isAnonymous || !reactor.user || (reactor.isMe && !shouldShowUp)) const peer = (reactor.isAnonymous || !reactor.user || (reactor.isMy && shouldSendAsAnonymous))
? ANONYMOUS_PEER : reactor.user; ? ANONYMOUS_PEER : reactor.user;
const text = 'isCustomPeer' in peer ? oldLang(peer.titleKey) : getUserFullName(peer); const text = 'isCustomPeer' in peer ? oldLang(peer.titleKey)
: peer && getPeerTitle(oldLang, peer);
return ( return (
<PeerBadge <PeerBadge
className={styles.topPeer} className={styles.topPeer}
@ -203,10 +338,11 @@ const PaidReactionModal = ({
})} })}
</div> </div>
)} )}
{topReactors && (<Separator className={styles.separator} />) }
<Checkbox <Checkbox
className="dialog-checkbox" className={buildClassName(styles.checkBox, 'dialog-checkbox')}
checked={shouldShowUp} checked={!shouldSendAsAnonymous}
onChange={handleAnonimityChange} onChange={handleShowInTopSendersChange}
label={oldLang('StarsReactionShowMeInTopSenders')} label={oldLang('StarsReactionShowMeInTopSenders')}
/> />
<Button <Button
@ -238,6 +374,9 @@ export default memo(withGlobal<OwnProps>(
const starBalance = global.stars?.balance; const starBalance = global.stars?.balance;
const maxAmount = global.appConfig?.paidReactionMaxAmount || MAX_REACTION_AMOUNT; const maxAmount = global.appConfig?.paidReactionMaxAmount || MAX_REACTION_AMOUNT;
const defaultPrivacy = global.settings.paidReactionPrivacy; const defaultPrivacy = global.settings.paidReactionPrivacy;
const sendPaidReactionsAsPeerIds = chat?.sendPaidReactionsAsPeerIds;
const currentUserId = global.currentUserId!;
const currentUser = selectUser(global, currentUserId)!;
return { return {
chat, chat,
@ -245,6 +384,9 @@ export default memo(withGlobal<OwnProps>(
starBalance, starBalance,
maxAmount, maxAmount,
defaultPrivacy, defaultPrivacy,
sendPaidReactionsAsPeerIds,
currentUserId,
currentUser,
}; };
}, },
)(PaidReactionModal)); )(PaidReactionModal));

View File

@ -11,6 +11,7 @@ import './DropdownMenu.scss';
type OwnProps = { type OwnProps = {
className?: string; className?: string;
bubbleClassName?: string;
trigger?: FC<{ onTrigger: () => void; isOpen?: boolean }>; trigger?: FC<{ onTrigger: () => void; isOpen?: boolean }>;
transformOriginX?: number; transformOriginX?: number;
transformOriginY?: number; transformOriginY?: number;
@ -30,6 +31,7 @@ type OwnProps = {
const DropdownMenu: FC<OwnProps> = ({ const DropdownMenu: FC<OwnProps> = ({
trigger, trigger,
className, className,
bubbleClassName,
children, children,
transformOriginX, transformOriginX,
transformOriginY, transformOriginY,
@ -107,6 +109,7 @@ const DropdownMenu: FC<OwnProps> = ({
ref={menuRef} ref={menuRef}
isOpen={isOpen || Boolean(forceOpen)} isOpen={isOpen || Boolean(forceOpen)}
className={className || ''} className={className || ''}
bubbleClassName={bubbleClassName || ''}
transformOriginX={transformOriginX} transformOriginX={transformOriginX}
transformOriginY={transformOriginY} transformOriginY={transformOriginY}
positionX={positionX} positionX={positionX}

View File

@ -1646,7 +1646,30 @@ addActionHandler('loadSendAs', async (global, actions, payload): Promise<void> =
} }
global = getGlobal(); global = getGlobal();
global = updateChat(global, chatId, { sendAsPeerIds: result.sendAs }); global = updateChat(global, chatId, { sendAsPeerIds: result });
setGlobal(global);
});
addActionHandler('loadSendPaidReactionsAs', async (global, actions, payload): Promise<void> => {
const { chatId } = payload;
const chat = selectChat(global, chatId);
if (!chat) {
return;
}
const result = await callApi('fetchSendAs', { chat, isForPaidReactions: true });
if (!result) {
global = getGlobal();
global = updateChat(global, chatId, {
sendPaidReactionsAsPeerIds: [],
});
setGlobal(global);
return;
}
global = getGlobal();
global = updateChat(global, chatId, { sendPaidReactionsAsPeerIds: result });
setGlobal(global); setGlobal(global);
}); });

View File

@ -246,8 +246,13 @@ addActionHandler('toggleReaction', async (global, actions, payload): Promise<voi
addActionHandler('addLocalPaidReaction', (global, actions, payload): ActionReturnType => { addActionHandler('addLocalPaidReaction', (global, actions, payload): ActionReturnType => {
const { const {
chatId, messageId, count, isPrivate, tabId = getCurrentTabId(), chatId, messageId, count, shouldIgnoreDefaultPrivacy = false, tabId = getCurrentTabId(),
} = payload; } = payload;
const defaultPrivacy = global.settings.paidReactionPrivacy;
const isPrivate = !shouldIgnoreDefaultPrivacy ? defaultPrivacy?.type === 'anonymous' : payload.isPrivate;
const peerId = !shouldIgnoreDefaultPrivacy
? (defaultPrivacy?.type === 'peer' ? defaultPrivacy.peerId : undefined) : payload.peerId;
const chat = selectChat(global, chatId); const chat = selectChat(global, chatId);
const message = selectChatMessage(global, chatId, messageId); const message = selectChatMessage(global, chatId, messageId);
@ -256,7 +261,7 @@ addActionHandler('addLocalPaidReaction', (global, actions, payload): ActionRetur
} }
const currentReactions = message.reactions?.results || []; const currentReactions = message.reactions?.results || [];
const newReactions = addPaidReaction(currentReactions, count, isPrivate); const newReactions = addPaidReaction(currentReactions, count, isPrivate, peerId);
global = updateChatMessage(global, message.chatId, message.id, { global = updateChatMessage(global, message.chatId, message.id, {
reactions: { reactions: {
...currentReactions, ...currentReactions,
@ -301,6 +306,7 @@ addActionHandler('sendPaidReaction', async (global, actions, payload): Promise<v
messageId, messageId,
count, count,
isPrivate: paidReaction?.localIsPrivate, isPrivate: paidReaction?.localIsPrivate,
peerId: paidReaction?.localPeerId,
}); });
} catch (error) { } catch (error) {
if ((error as ApiError).message === 'BALANCE_TOO_LOW') { if ((error as ApiError).message === 'BALANCE_TOO_LOW') {

View File

@ -857,7 +857,8 @@ function updateReactions<T extends GlobalState>(
const localPaidReaction = currentReactions?.results.find((r) => r.localAmount); const localPaidReaction = currentReactions?.results.find((r) => r.localAmount);
// Save local count on update, but reset if we sent reaction // Save local count on update, but reset if we sent reaction
if (localPaidReaction?.localAmount) { if (localPaidReaction?.localAmount) {
reactions.results = addPaidReaction(reactions.results, localPaidReaction.localAmount); const { localIsPrivate: isPrivate, localAmount, localPeerId } = localPaidReaction;
reactions.results = addPaidReaction(reactions.results, localAmount, isPrivate, localPeerId);
} }
global = updateChatMessage(global, chatId, id, { reactions }); global = updateChatMessage(global, chatId, id, { reactions });

View File

@ -199,7 +199,7 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
...global, ...global,
settings: { settings: {
...global.settings, ...global.settings,
paidReactionPrivacy: update.isPrivate, paidReactionPrivacy: update.private,
}, },
}; };
setGlobal(global); setGlobal(global);

View File

@ -122,7 +122,7 @@ export function updateReactionCount(reactionCount: ApiReactionCount[], newReacti
} }
export function addPaidReaction( export function addPaidReaction(
reactionCount: ApiReactionCount[], count: number, isAnonymous?: boolean, reactionCount: ApiReactionCount[], count: number, isAnonymous?: boolean, peerId?: string,
): ApiReactionCount[] { ): ApiReactionCount[] {
const results: ApiReactionCount[] = []; const results: ApiReactionCount[] = [];
const hasPaid = reactionCount.some((current) => current.reaction.type === 'paid'); const hasPaid = reactionCount.some((current) => current.reaction.type === 'paid');
@ -134,6 +134,7 @@ export function addPaidReaction(
localAmount: (current.localAmount || 0) + count, localAmount: (current.localAmount || 0) + count,
chosenOrder: -1, chosenOrder: -1,
localIsPrivate: isAnonymous !== undefined ? isAnonymous : current.localIsPrivate, localIsPrivate: isAnonymous !== undefined ? isAnonymous : current.localIsPrivate,
localPeerId: peerId || current.localPeerId,
localPreviousChosenOrder: current.chosenOrder, localPreviousChosenOrder: current.chosenOrder,
}); });
return; return;
@ -152,6 +153,7 @@ export function addPaidReaction(
chosenOrder: -1, chosenOrder: -1,
localAmount: count, localAmount: count,
localIsPrivate: isAnonymous, localIsPrivate: isAnonymous,
localPeerId: peerId,
}, },
...reactionCount, ...reactionCount,
]; ];

View File

@ -536,6 +536,9 @@ export interface ActionPayloads {
loadSendAs: { loadSendAs: {
chatId: string; chatId: string;
}; };
loadSendPaidReactionsAs: {
chatId: string;
};
saveDefaultSendAs: { saveDefaultSendAs: {
chatId: string; chatId: string;
sendAsId: string; sendAsId: string;
@ -1384,7 +1387,9 @@ export interface ActionPayloads {
chatId: string; chatId: string;
messageId: number; messageId: number;
count: number; count: number;
peerId?: string;
isPrivate?: boolean; isPrivate?: boolean;
shouldIgnoreDefaultPrivacy?: boolean;
} & WithTabId; } & WithTabId;
resetLocalPaidReactions: { resetLocalPaidReactions: {
chatId: string; chatId: string;

View File

@ -15,6 +15,7 @@ import type {
ApiGroupCall, ApiGroupCall,
ApiLanguage, ApiLanguage,
ApiMessage, ApiMessage,
ApiPaidReactionPrivacyType,
ApiPeerColors, ApiPeerColors,
ApiPeerPhotos, ApiPeerPhotos,
ApiPeerStories, ApiPeerStories,
@ -408,7 +409,7 @@ export type GlobalState = {
privacy: Partial<Record<ApiPrivacyKey, ApiPrivacySettings>>; privacy: Partial<Record<ApiPrivacyKey, ApiPrivacySettings>>;
notifyExceptions?: Record<number, NotifyException>; notifyExceptions?: Record<number, NotifyException>;
lastPremiumBandwithNotificationDate?: number; lastPremiumBandwithNotificationDate?: number;
paidReactionPrivacy?: boolean; paidReactionPrivacy?: ApiPaidReactionPrivacyType;
languages?: ApiLanguage[]; languages?: ApiLanguage[];
botVerificationShownPeerIds: string[]; botVerificationShownPeerIds: string[];
miniAppsCachedPosition?: Point; miniAppsCachedPosition?: Point;

View File

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

View File

@ -388,6 +388,7 @@ namespace Api {
export type TypeStarGiftAttribute = StarGiftAttributeModel | StarGiftAttributePattern | StarGiftAttributeBackdrop | StarGiftAttributeOriginalDetails; export type TypeStarGiftAttribute = StarGiftAttributeModel | StarGiftAttributePattern | StarGiftAttributeBackdrop | StarGiftAttributeOriginalDetails;
export type TypeSavedStarGift = SavedStarGift; export type TypeSavedStarGift = SavedStarGift;
export type TypeInputSavedStarGift = InputSavedStarGiftUser | InputSavedStarGiftChat; export type TypeInputSavedStarGift = InputSavedStarGiftUser | InputSavedStarGiftChat;
export type TypePaidReactionPrivacy = PaidReactionPrivacyDefault | PaidReactionPrivacyAnonymous | PaidReactionPrivacyPeer;
export type TypeResPQ = ResPQ; export type TypeResPQ = ResPQ;
export type TypeP_Q_inner_data = PQInnerData | PQInnerDataDc | PQInnerDataTemp | PQInnerDataTempDc; export type TypeP_Q_inner_data = PQInnerData | PQInnerDataDc | PQInnerDataTemp | PQInnerDataTempDc;
export type TypeServer_DH_Params = ServerDHParamsFail | ServerDHParamsOk; export type TypeServer_DH_Params = ServerDHParamsFail | ServerDHParamsOk;
@ -4490,9 +4491,9 @@ namespace Api {
static fromReader(reader: Reader): UpdateBotPurchasedPaidMedia; static fromReader(reader: Reader): UpdateBotPurchasedPaidMedia;
} }
export class UpdatePaidReactionPrivacy extends VirtualClass<{ export class UpdatePaidReactionPrivacy extends VirtualClass<{
private: Bool; private: Api.TypePaidReactionPrivacy;
}> { }> {
private: Bool; private: Api.TypePaidReactionPrivacy;
static fromReader(reader: Reader): UpdatePaidReactionPrivacy; static fromReader(reader: Reader): UpdatePaidReactionPrivacy;
} }
export class UpdatesTooLong extends VirtualClass<void> { export class UpdatesTooLong extends VirtualClass<void> {
@ -5365,6 +5366,7 @@ namespace Api {
export class WebPage extends VirtualClass<{ export class WebPage extends VirtualClass<{
// flags: Api.Type; // flags: Api.Type;
hasLargeMedia?: true; hasLargeMedia?: true;
videoCoverPhoto?: true;
id: long; id: long;
url: string; url: string;
displayUrl: string; displayUrl: string;
@ -5386,6 +5388,7 @@ namespace Api {
}> { }> {
// flags: Api.Type; // flags: Api.Type;
hasLargeMedia?: true; hasLargeMedia?: true;
videoCoverPhoto?: true;
id: long; id: long;
url: string; url: string;
displayUrl: string; displayUrl: string;
@ -12070,6 +12073,7 @@ namespace Api {
attributes: Api.TypeStarGiftAttribute[]; attributes: Api.TypeStarGiftAttribute[];
availabilityIssued: int; availabilityIssued: int;
availabilityTotal: int; availabilityTotal: int;
giftAddress?: string;
}> { }> {
// flags: Api.Type; // flags: Api.Type;
id: long; id: long;
@ -12082,6 +12086,7 @@ namespace Api {
attributes: Api.TypeStarGiftAttribute[]; attributes: Api.TypeStarGiftAttribute[];
availabilityIssued: int; availabilityIssued: int;
availabilityTotal: int; availabilityTotal: int;
giftAddress?: string;
static fromReader(reader: Reader): StarGiftUnique; static fromReader(reader: Reader): StarGiftUnique;
} }
export class MessageReportOption extends VirtualClass<{ export class MessageReportOption extends VirtualClass<{
@ -12297,6 +12302,18 @@ namespace Api {
savedId: long; savedId: long;
static fromReader(reader: Reader): InputSavedStarGiftChat; static fromReader(reader: Reader): InputSavedStarGiftChat;
} }
export class PaidReactionPrivacyDefault extends VirtualClass<void> {
static fromReader(reader: Reader): PaidReactionPrivacyDefault;
}
export class PaidReactionPrivacyAnonymous extends VirtualClass<void> {
static fromReader(reader: Reader): PaidReactionPrivacyAnonymous;
}
export class PaidReactionPrivacyPeer extends VirtualClass<{
peer: Api.TypeInputPeer;
}> {
peer: Api.TypeInputPeer;
static fromReader(reader: Reader): PaidReactionPrivacyPeer;
}
export class ResPQ extends VirtualClass<{ export class ResPQ extends VirtualClass<{
nonce: int128; nonce: int128;
serverNonce: int128; serverNonce: int128;
@ -15711,6 +15728,13 @@ namespace Api {
secret: string; secret: string;
query: X; query: X;
} }
export class InvokeWithReCaptcha extends Request<Partial<{
token: string;
query: X;
}>, X> {
token: string;
query: X;
}
export class ReqPq extends Request<Partial<{ export class ReqPq extends Request<Partial<{
nonce: int128; nonce: int128;
}>, Api.TypeResPQ> { }>, Api.TypeResPQ> {
@ -19013,23 +19037,23 @@ namespace Api {
msgId: int; msgId: int;
count: int; count: int;
randomId: long; randomId: long;
private?: Bool; private?: Api.TypePaidReactionPrivacy;
}>, Api.TypeUpdates> { }>, Api.TypeUpdates> {
// flags: Api.Type; // flags: Api.Type;
peer: Api.TypeInputPeer; peer: Api.TypeInputPeer;
msgId: int; msgId: int;
count: int; count: int;
randomId: long; randomId: long;
private?: Bool; private?: Api.TypePaidReactionPrivacy;
} }
export class TogglePaidReactionPrivacy extends Request<Partial<{ export class TogglePaidReactionPrivacy extends Request<Partial<{
peer: Api.TypeInputPeer; peer: Api.TypeInputPeer;
msgId: int; msgId: int;
private: Bool; private: Api.TypePaidReactionPrivacy;
}>, Bool> { }>, Bool> {
peer: Api.TypeInputPeer; peer: Api.TypeInputPeer;
msgId: int; msgId: int;
private: Bool; private: Api.TypePaidReactionPrivacy;
} }
export class GetPaidReactionPrivacy extends Request<void, Api.TypeUpdates> {} export class GetPaidReactionPrivacy extends Request<void, Api.TypeUpdates> {}
export class ViewSponsoredMessage extends Request<Partial<{ export class ViewSponsoredMessage extends Request<Partial<{
@ -19682,8 +19706,12 @@ namespace Api {
channel: Api.TypeInputChannel; channel: Api.TypeInputChannel;
} }
export class GetSendAs extends Request<Partial<{ export class GetSendAs extends Request<Partial<{
// flags: Api.Type;
forPaidReactions?: true;
peer: Api.TypeInputPeer; peer: Api.TypeInputPeer;
}>, channels.TypeSendAsPeers> { }>, channels.TypeSendAsPeers> {
// flags: Api.Type;
forPaidReactions?: true;
peer: Api.TypeInputPeer; peer: Api.TypeInputPeer;
} }
export class DeleteParticipantHistory extends Request<Partial<{ export class DeleteParticipantHistory extends Request<Partial<{
@ -21465,7 +21493,7 @@ namespace Api {
} }
} }
export type AnyRequest = InvokeAfterMsg | InvokeAfterMsgs | InitConnection | InvokeWithLayer | InvokeWithoutUpdates | InvokeWithMessagesRange | InvokeWithTakeout | InvokeWithBusinessConnection | InvokeWithGooglePlayIntegrity | InvokeWithApnsSecret | ReqPq | ReqPqMulti | ReqPqMultiNew | ReqDHParams | SetClientDHParams | DestroyAuthKey | RpcDropAnswer | GetFutureSalts | Ping | PingDelayDisconnect | DestroySession export type AnyRequest = InvokeAfterMsg | InvokeAfterMsgs | InitConnection | InvokeWithLayer | InvokeWithoutUpdates | InvokeWithMessagesRange | InvokeWithTakeout | InvokeWithBusinessConnection | InvokeWithGooglePlayIntegrity | InvokeWithApnsSecret | InvokeWithReCaptcha | ReqPq | ReqPqMulti | ReqPqMultiNew | ReqDHParams | SetClientDHParams | DestroyAuthKey | RpcDropAnswer | GetFutureSalts | Ping | PingDelayDisconnect | DestroySession
| auth.SendCode | auth.SignUp | auth.SignIn | auth.LogOut | auth.ResetAuthorizations | auth.ExportAuthorization | auth.ImportAuthorization | auth.BindTempAuthKey | auth.ImportBotAuthorization | auth.CheckPassword | auth.RequestPasswordRecovery | auth.RecoverPassword | auth.ResendCode | auth.CancelCode | auth.DropTempAuthKeys | auth.ExportLoginToken | auth.ImportLoginToken | auth.AcceptLoginToken | auth.CheckRecoveryPassword | auth.ImportWebTokenAuthorization | auth.RequestFirebaseSms | auth.ResetLoginEmail | auth.ReportMissingCode | auth.SendCode | auth.SignUp | auth.SignIn | auth.LogOut | auth.ResetAuthorizations | auth.ExportAuthorization | auth.ImportAuthorization | auth.BindTempAuthKey | auth.ImportBotAuthorization | auth.CheckPassword | auth.RequestPasswordRecovery | auth.RecoverPassword | auth.ResendCode | auth.CancelCode | auth.DropTempAuthKeys | auth.ExportLoginToken | auth.ImportLoginToken | auth.AcceptLoginToken | auth.CheckRecoveryPassword | auth.ImportWebTokenAuthorization | auth.RequestFirebaseSms | auth.ResetLoginEmail | auth.ReportMissingCode
| account.RegisterDevice | account.UnregisterDevice | account.UpdateNotifySettings | account.GetNotifySettings | account.ResetNotifySettings | account.UpdateProfile | account.UpdateStatus | account.GetWallPapers | account.ReportPeer | account.CheckUsername | account.UpdateUsername | account.GetPrivacy | account.SetPrivacy | account.DeleteAccount | account.GetAccountTTL | account.SetAccountTTL | account.SendChangePhoneCode | account.ChangePhone | account.UpdateDeviceLocked | account.GetAuthorizations | account.ResetAuthorization | account.GetPassword | account.GetPasswordSettings | account.UpdatePasswordSettings | account.SendConfirmPhoneCode | account.ConfirmPhone | account.GetTmpPassword | account.GetWebAuthorizations | account.ResetWebAuthorization | account.ResetWebAuthorizations | account.GetAllSecureValues | account.GetSecureValue | account.SaveSecureValue | account.DeleteSecureValue | account.GetAuthorizationForm | account.AcceptAuthorization | account.SendVerifyPhoneCode | account.VerifyPhone | account.SendVerifyEmailCode | account.VerifyEmail | account.InitTakeoutSession | account.FinishTakeoutSession | account.ConfirmPasswordEmail | account.ResendPasswordEmail | account.CancelPasswordEmail | account.GetContactSignUpNotification | account.SetContactSignUpNotification | account.GetNotifyExceptions | account.GetWallPaper | account.UploadWallPaper | account.SaveWallPaper | account.InstallWallPaper | account.ResetWallPapers | account.GetAutoDownloadSettings | account.SaveAutoDownloadSettings | account.UploadTheme | account.CreateTheme | account.UpdateTheme | account.SaveTheme | account.InstallTheme | account.GetTheme | account.GetThemes | account.SetContentSettings | account.GetContentSettings | account.GetMultiWallPapers | account.GetGlobalPrivacySettings | account.SetGlobalPrivacySettings | account.ReportProfilePhoto | account.ResetPassword | account.DeclinePasswordReset | account.GetChatThemes | account.SetAuthorizationTTL | account.ChangeAuthorizationSettings | account.GetSavedRingtones | account.SaveRingtone | account.UploadRingtone | account.UpdateEmojiStatus | account.GetDefaultEmojiStatuses | account.GetRecentEmojiStatuses | account.ClearRecentEmojiStatuses | account.ReorderUsernames | account.ToggleUsername | account.GetDefaultProfilePhotoEmojis | account.GetDefaultGroupPhotoEmojis | account.GetAutoSaveSettings | account.SaveAutoSaveSettings | account.DeleteAutoSaveExceptions | account.InvalidateSignInCodes | account.UpdateColor | account.GetDefaultBackgroundEmojis | account.GetChannelDefaultEmojiStatuses | account.GetChannelRestrictedStatusEmojis | account.UpdateBusinessWorkHours | account.UpdateBusinessLocation | account.UpdateBusinessGreetingMessage | account.UpdateBusinessAwayMessage | account.UpdateConnectedBot | account.GetConnectedBots | account.GetBotBusinessConnection | account.UpdateBusinessIntro | account.ToggleConnectedBotPaused | account.DisablePeerConnectedBot | account.UpdateBirthday | account.CreateBusinessChatLink | account.EditBusinessChatLink | account.DeleteBusinessChatLink | account.GetBusinessChatLinks | account.ResolveBusinessChatLink | account.UpdatePersonalChannel | account.ToggleSponsoredMessages | account.GetReactionsNotifySettings | account.SetReactionsNotifySettings | account.GetCollectibleEmojiStatuses | account.RegisterDevice | account.UnregisterDevice | account.UpdateNotifySettings | account.GetNotifySettings | account.ResetNotifySettings | account.UpdateProfile | account.UpdateStatus | account.GetWallPapers | account.ReportPeer | account.CheckUsername | account.UpdateUsername | account.GetPrivacy | account.SetPrivacy | account.DeleteAccount | account.GetAccountTTL | account.SetAccountTTL | account.SendChangePhoneCode | account.ChangePhone | account.UpdateDeviceLocked | account.GetAuthorizations | account.ResetAuthorization | account.GetPassword | account.GetPasswordSettings | account.UpdatePasswordSettings | account.SendConfirmPhoneCode | account.ConfirmPhone | account.GetTmpPassword | account.GetWebAuthorizations | account.ResetWebAuthorization | account.ResetWebAuthorizations | account.GetAllSecureValues | account.GetSecureValue | account.SaveSecureValue | account.DeleteSecureValue | account.GetAuthorizationForm | account.AcceptAuthorization | account.SendVerifyPhoneCode | account.VerifyPhone | account.SendVerifyEmailCode | account.VerifyEmail | account.InitTakeoutSession | account.FinishTakeoutSession | account.ConfirmPasswordEmail | account.ResendPasswordEmail | account.CancelPasswordEmail | account.GetContactSignUpNotification | account.SetContactSignUpNotification | account.GetNotifyExceptions | account.GetWallPaper | account.UploadWallPaper | account.SaveWallPaper | account.InstallWallPaper | account.ResetWallPapers | account.GetAutoDownloadSettings | account.SaveAutoDownloadSettings | account.UploadTheme | account.CreateTheme | account.UpdateTheme | account.SaveTheme | account.InstallTheme | account.GetTheme | account.GetThemes | account.SetContentSettings | account.GetContentSettings | account.GetMultiWallPapers | account.GetGlobalPrivacySettings | account.SetGlobalPrivacySettings | account.ReportProfilePhoto | account.ResetPassword | account.DeclinePasswordReset | account.GetChatThemes | account.SetAuthorizationTTL | account.ChangeAuthorizationSettings | account.GetSavedRingtones | account.SaveRingtone | account.UploadRingtone | account.UpdateEmojiStatus | account.GetDefaultEmojiStatuses | account.GetRecentEmojiStatuses | account.ClearRecentEmojiStatuses | account.ReorderUsernames | account.ToggleUsername | account.GetDefaultProfilePhotoEmojis | account.GetDefaultGroupPhotoEmojis | account.GetAutoSaveSettings | account.SaveAutoSaveSettings | account.DeleteAutoSaveExceptions | account.InvalidateSignInCodes | account.UpdateColor | account.GetDefaultBackgroundEmojis | account.GetChannelDefaultEmojiStatuses | account.GetChannelRestrictedStatusEmojis | account.UpdateBusinessWorkHours | account.UpdateBusinessLocation | account.UpdateBusinessGreetingMessage | account.UpdateBusinessAwayMessage | account.UpdateConnectedBot | account.GetConnectedBots | account.GetBotBusinessConnection | account.UpdateBusinessIntro | account.ToggleConnectedBotPaused | account.DisablePeerConnectedBot | account.UpdateBirthday | account.CreateBusinessChatLink | account.EditBusinessChatLink | account.DeleteBusinessChatLink | account.GetBusinessChatLinks | account.ResolveBusinessChatLink | account.UpdatePersonalChannel | account.ToggleSponsoredMessages | account.GetReactionsNotifySettings | account.SetReactionsNotifySettings | account.GetCollectibleEmojiStatuses
| users.GetUsers | users.GetFullUser | users.SetSecureValueErrors | users.GetIsPremiumRequiredToContact | users.GetUsers | users.GetFullUser | users.SetSecureValueErrors | users.GetIsPremiumRequiredToContact

View File

@ -373,7 +373,7 @@ 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#8b725fce private:PaidReactionPrivacy = 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;
@ -510,7 +510,7 @@ messages.allStickers#cdbbcebb hash:long sets:Vector<StickerSet> = messages.AllSt
messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages; messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
webPageEmpty#211a1788 flags:# id:long url:flags.0?string = WebPage; webPageEmpty#211a1788 flags:# id:long url:flags.0?string = WebPage;
webPagePending#b0d13e47 flags:# id:long url:flags.0?string date:int = WebPage; webPagePending#b0d13e47 flags:# id:long url:flags.0?string date:int = WebPage;
webPage#e89c45b2 flags:# has_large_media:flags.13?true id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page attributes:flags.12?Vector<WebPageAttribute> = WebPage; webPage#e89c45b2 flags:# has_large_media:flags.13?true video_cover_photo:flags.14?true id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page attributes:flags.12?Vector<WebPageAttribute> = WebPage;
webPageNotModified#7311ca11 flags:# cached_page_views:flags.0?int = WebPage; webPageNotModified#7311ca11 flags:# cached_page_views:flags.0?int = WebPage;
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true encrypted_requests_disabled:flags.3?true call_requests_disabled:flags.4?true unconfirmed:flags.5?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization; authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true encrypted_requests_disabled:flags.3?true call_requests_disabled:flags.4?true unconfirmed:flags.5?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
account.authorizations#4bff8ea0 authorization_ttl_days:int authorizations:Vector<Authorization> = account.Authorizations; account.authorizations#4bff8ea0 authorization_ttl_days:int authorizations:Vector<Authorization> = account.Authorizations;
@ -1367,7 +1367,7 @@ 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#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; starGiftUnique#5c62d151 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 gift_address:flags.3?string = 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;
messageReportOption#7903e3d9 text:string option:bytes = MessageReportOption; messageReportOption#7903e3d9 text:string option:bytes = MessageReportOption;
@ -1400,6 +1400,9 @@ payments.savedStarGifts#95f389b1 flags:# count:int chat_notifications_enabled:fl
inputSavedStarGiftUser#69279795 msg_id:int = InputSavedStarGift; inputSavedStarGiftUser#69279795 msg_id:int = InputSavedStarGift;
inputSavedStarGiftChat#f101aa7f peer:InputPeer saved_id:long = InputSavedStarGift; inputSavedStarGiftChat#f101aa7f peer:InputPeer saved_id:long = InputSavedStarGift;
payments.starGiftWithdrawalUrl#84aa3a9c url:string = payments.StarGiftWithdrawalUrl; payments.starGiftWithdrawalUrl#84aa3a9c url:string = payments.StarGiftWithdrawalUrl;
paidReactionPrivacyDefault#206ad49e = PaidReactionPrivacy;
paidReactionPrivacyAnonymous#1f0c1ad9 = PaidReactionPrivacy;
paidReactionPrivacyPeer#dc6cfcf0 peer:InputPeer = PaidReactionPrivacy;
---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;
@ -1615,7 +1618,7 @@ messages.sendQuickReplyMessages#6c750de1 peer:InputPeer shortcut_id:int id:Vecto
messages.getAvailableEffects#dea20a39 hash:int = messages.AvailableEffects; messages.getAvailableEffects#dea20a39 hash:int = messages.AvailableEffects;
messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector<int> = Vector<FactCheck>; messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector<int> = Vector<FactCheck>;
messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true fullscreen:flags.8?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult; messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true fullscreen:flags.8?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult;
messages.sendPaidReaction#9dd6a67b flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?Bool = Updates; messages.sendPaidReaction#58bbcb50 flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?PaidReactionPrivacy = Updates;
messages.getPaidReactionPrivacy#472455aa = Updates; messages.getPaidReactionPrivacy#472455aa = Updates;
messages.viewSponsoredMessage#673ad8f1 peer:InputPeer random_id:bytes = Bool; messages.viewSponsoredMessage#673ad8f1 peer:InputPeer random_id:bytes = Bool;
messages.clickSponsoredMessage#f093465 flags:# media:flags.0?true fullscreen:flags.1?true peer:InputPeer random_id:bytes = Bool; messages.clickSponsoredMessage#f093465 flags:# media:flags.0?true fullscreen:flags.1?true peer:InputPeer random_id:bytes = Bool;
@ -1668,7 +1671,7 @@ channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool
channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates; channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates;
channels.getGroupsForDiscussion#f5dad378 = messages.Chats; channels.getGroupsForDiscussion#f5dad378 = messages.Chats;
channels.setDiscussionGroup#40582bb2 broadcast:InputChannel group:InputChannel = Bool; channels.setDiscussionGroup#40582bb2 broadcast:InputChannel group:InputChannel = Bool;
channels.getSendAs#dc770ee peer:InputPeer = channels.SendAsPeers; channels.getSendAs#e785a43f flags:# for_paid_reactions:flags.0?true peer:InputPeer = channels.SendAsPeers;
channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory; channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory;
channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates; channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates;
channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates; channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;

View File

@ -426,7 +426,7 @@ 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#8b725fce private:PaidReactionPrivacy = 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;
@ -599,7 +599,7 @@ messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMess
webPageEmpty#211a1788 flags:# id:long url:flags.0?string = WebPage; webPageEmpty#211a1788 flags:# id:long url:flags.0?string = WebPage;
webPagePending#b0d13e47 flags:# id:long url:flags.0?string date:int = WebPage; webPagePending#b0d13e47 flags:# id:long url:flags.0?string date:int = WebPage;
webPage#e89c45b2 flags:# has_large_media:flags.13?true id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page attributes:flags.12?Vector<WebPageAttribute> = WebPage; webPage#e89c45b2 flags:# has_large_media:flags.13?true video_cover_photo:flags.14?true id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page attributes:flags.12?Vector<WebPageAttribute> = WebPage;
webPageNotModified#7311ca11 flags:# cached_page_views:flags.0?int = WebPage; webPageNotModified#7311ca11 flags:# cached_page_views:flags.0?int = WebPage;
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true encrypted_requests_disabled:flags.3?true call_requests_disabled:flags.4?true unconfirmed:flags.5?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization; authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true encrypted_requests_disabled:flags.3?true call_requests_disabled:flags.4?true unconfirmed:flags.5?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
@ -1877,7 +1877,7 @@ 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#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; starGiftUnique#5c62d151 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 gift_address:flags.3?string = 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;
@ -1934,6 +1934,10 @@ inputSavedStarGiftChat#f101aa7f peer:InputPeer saved_id:long = InputSavedStarGif
payments.starGiftWithdrawalUrl#84aa3a9c url:string = payments.StarGiftWithdrawalUrl; payments.starGiftWithdrawalUrl#84aa3a9c url:string = payments.StarGiftWithdrawalUrl;
paidReactionPrivacyDefault#206ad49e = PaidReactionPrivacy;
paidReactionPrivacyAnonymous#1f0c1ad9 = PaidReactionPrivacy;
paidReactionPrivacyPeer#dc6cfcf0 peer:InputPeer = PaidReactionPrivacy;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1946,6 +1950,7 @@ invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
invokeWithBusinessConnection#dd289f8e {X:Type} connection_id:string query:!X = X; invokeWithBusinessConnection#dd289f8e {X:Type} connection_id:string query:!X = X;
invokeWithGooglePlayIntegrity#1df92984 {X:Type} nonce:string token:string query:!X = X; invokeWithGooglePlayIntegrity#1df92984 {X:Type} nonce:string token:string query:!X = X;
invokeWithApnsSecret#0dae54f8 {X:Type} nonce:string secret:string query:!X = X; invokeWithApnsSecret#0dae54f8 {X:Type} nonce:string secret:string query:!X = X;
invokeWithReCaptcha#adbb0f94 {X:Type} token:string query:!X = X;
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode; auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
auth.signUp#aac7b717 flags:# no_joined_notifications:flags.0?true phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization; auth.signUp#aac7b717 flags:# no_joined_notifications:flags.0?true phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization;
@ -2331,8 +2336,8 @@ messages.editFactCheck#589ee75 peer:InputPeer msg_id:int text:TextWithEntities =
messages.deleteFactCheck#d1da940c peer:InputPeer msg_id:int = Updates; messages.deleteFactCheck#d1da940c peer:InputPeer msg_id:int = Updates;
messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector<int> = Vector<FactCheck>; messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector<int> = Vector<FactCheck>;
messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true fullscreen:flags.8?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult; messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true fullscreen:flags.8?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult;
messages.sendPaidReaction#9dd6a67b flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?Bool = Updates; messages.sendPaidReaction#58bbcb50 flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?PaidReactionPrivacy = Updates;
messages.togglePaidReactionPrivacy#849ad397 peer:InputPeer msg_id:int private:Bool = Bool; messages.togglePaidReactionPrivacy#435885b5 peer:InputPeer msg_id:int private:PaidReactionPrivacy = Bool;
messages.getPaidReactionPrivacy#472455aa = Updates; messages.getPaidReactionPrivacy#472455aa = Updates;
messages.viewSponsoredMessage#673ad8f1 peer:InputPeer random_id:bytes = Bool; messages.viewSponsoredMessage#673ad8f1 peer:InputPeer random_id:bytes = Bool;
messages.clickSponsoredMessage#f093465 flags:# media:flags.0?true fullscreen:flags.1?true peer:InputPeer random_id:bytes = Bool; messages.clickSponsoredMessage#f093465 flags:# media:flags.0?true fullscreen:flags.1?true peer:InputPeer random_id:bytes = Bool;
@ -2423,7 +2428,7 @@ channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint addr
channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates; channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates;
channels.getInactiveChannels#11e831ee = messages.InactiveChats; channels.getInactiveChannels#11e831ee = messages.InactiveChats;
channels.convertToGigagroup#b290c69 channel:InputChannel = Updates; channels.convertToGigagroup#b290c69 channel:InputChannel = Updates;
channels.getSendAs#dc770ee peer:InputPeer = channels.SendAsPeers; channels.getSendAs#e785a43f flags:# for_paid_reactions:flags.0?true peer:InputPeer = channels.SendAsPeers;
channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory; channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory;
channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates; channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates;
channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates; channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;

View File

@ -1333,6 +1333,8 @@ export interface LangPair {
'UniqueStatusProofOfOwnershipDescription': undefined; 'UniqueStatusProofOfOwnershipDescription': undefined;
'UniqueStatusWearButton': undefined; 'UniqueStatusWearButton': undefined;
'CollectibleStatusesCategory': undefined; 'CollectibleStatusesCategory': undefined;
'PeerPersonalAccount': undefined;
'PeerChannel': undefined;
} }
export interface LangPairWithVariables<V extends unknown = LangVariable> { export interface LangPairWithVariables<V extends unknown = LangVariable> {