Paid Reactions: Support peers (#5581)
This commit is contained in:
parent
47fcfd9e96
commit
8a2f067c9b
@ -4,6 +4,7 @@ import type {
|
||||
ApiAvailableEffect,
|
||||
ApiAvailableReaction,
|
||||
ApiMessageReactor,
|
||||
ApiPaidReactionPrivacyType,
|
||||
ApiPeerReaction,
|
||||
ApiReaction,
|
||||
ApiReactionCount,
|
||||
@ -66,7 +67,7 @@ export function buildApiMessageReactor(reactor: GramJs.MessageReactor): ApiMessa
|
||||
return {
|
||||
peerId: peerId && getApiChatIdFromMtpPeer(peerId),
|
||||
count,
|
||||
isMe: my,
|
||||
isMy: my,
|
||||
isTop: top,
|
||||
isAnonymous: anonymous,
|
||||
};
|
||||
@ -164,3 +165,18 @@ export function buildApiAvailableEffect(availableEffect: GramJs.AvailableEffect)
|
||||
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' };
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
const type = getEntityTypeById(chatOrUserId);
|
||||
let accessHash: BigInt.BigInteger | undefined;
|
||||
|
||||
@ -1719,10 +1719,13 @@ export async function fetchSeenBy({ chat, messageId }: { chat: ApiChat; messageI
|
||||
|
||||
export async function fetchSendAs({
|
||||
chat,
|
||||
isForPaidReactions,
|
||||
}: {
|
||||
isForPaidReactions?: true;
|
||||
chat: ApiChat;
|
||||
}) {
|
||||
const result = await invokeRequest(new GramJs.channels.GetSendAs({
|
||||
forPaidReactions: isForPaidReactions,
|
||||
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||
}), {
|
||||
shouldIgnoreErrors: true,
|
||||
@ -1733,9 +1736,7 @@ export async function fetchSendAs({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
sendAs: result.peers.map(buildApiSendAsPeerId),
|
||||
};
|
||||
return result.peers.map(buildApiSendAsPeerId);
|
||||
}
|
||||
|
||||
export function saveDefaultSendAs({
|
||||
|
||||
@ -20,7 +20,9 @@ import {
|
||||
buildMessagePeerReaction,
|
||||
} from '../apiBuilders/reactions';
|
||||
import { buildStickerFromDocument } from '../apiBuilders/symbols';
|
||||
import { buildInputPeer, buildInputReaction, generateRandomTimestampedBigInt } from '../gramjsBuilders';
|
||||
import {
|
||||
buildInputPaidReactionPrivacy, buildInputPeer, buildInputReaction, generateRandomTimestampedBigInt,
|
||||
} from '../gramjsBuilders';
|
||||
import localDb from '../localDb';
|
||||
import { invokeRequest } from './client';
|
||||
|
||||
@ -155,18 +157,20 @@ export function sendPaidReaction({
|
||||
messageId,
|
||||
count,
|
||||
isPrivate,
|
||||
peerId,
|
||||
}: {
|
||||
chat: ApiChat;
|
||||
messageId: number;
|
||||
count: number;
|
||||
isPrivate?: boolean;
|
||||
peerId?: string;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.messages.SendPaidReaction({
|
||||
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||
msgId: messageId,
|
||||
randomId: generateRandomTimestampedBigInt(),
|
||||
count,
|
||||
private: isPrivate || undefined,
|
||||
private: buildInputPaidReactionPrivacy(isPrivate, peerId),
|
||||
}), {
|
||||
shouldReturnTrue: true,
|
||||
shouldThrow: true,
|
||||
|
||||
@ -55,6 +55,7 @@ import {
|
||||
import { buildApiStarsAmount } from '../apiBuilders/payments';
|
||||
import { buildApiEmojiStatus, buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
import {
|
||||
buildApiPaidReactionPrivacy,
|
||||
buildApiReaction,
|
||||
buildMessageReactions,
|
||||
} from '../apiBuilders/reactions';
|
||||
@ -1071,7 +1072,7 @@ export function updater(update: Update) {
|
||||
} else if (update instanceof GramJs.UpdatePaidReactionPrivacy) {
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePaidReactionPrivacy',
|
||||
isPrivate: update.private,
|
||||
private: buildApiPaidReactionPrivacy(update.private),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateLangPackTooLong) {
|
||||
sendApiUpdate({
|
||||
|
||||
@ -77,6 +77,8 @@ export interface ApiChat {
|
||||
isJoinToSend?: boolean;
|
||||
isJoinRequest?: boolean;
|
||||
sendAsPeerIds?: ApiSendAsPeerId[];
|
||||
sendPaidReactionsAsPeerIds?: ApiSendAsPeerId[];
|
||||
sendPaidReactionsPeer?: ApiSendAsPeerId;
|
||||
|
||||
unreadReactions?: number[];
|
||||
unreadMentions?: number[];
|
||||
|
||||
@ -675,7 +675,7 @@ export interface ApiPeerReaction {
|
||||
|
||||
export interface ApiMessageReactor {
|
||||
isTop?: true;
|
||||
isMe?: true;
|
||||
isMy?: true;
|
||||
count: number;
|
||||
isAnonymous?: true;
|
||||
peerId?: string;
|
||||
@ -687,6 +687,7 @@ export interface ApiReactionCount {
|
||||
reaction: ApiReactionWithPaid;
|
||||
localAmount?: number;
|
||||
localIsPrivate?: boolean;
|
||||
localPeerId?: string;
|
||||
localPreviousChosenOrder?: number;
|
||||
}
|
||||
|
||||
@ -750,6 +751,22 @@ export type ApiSavedReactionTag = {
|
||||
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 {
|
||||
chatId: string;
|
||||
messagesCount: number;
|
||||
|
||||
@ -24,6 +24,7 @@ import type {
|
||||
ApiFormattedText,
|
||||
ApiMediaExtendedPreview,
|
||||
ApiMessage,
|
||||
ApiPaidReactionPrivacyType,
|
||||
ApiPhoto,
|
||||
ApiPoll,
|
||||
ApiQuickReply,
|
||||
@ -789,7 +790,7 @@ export type ApiUpdateEntities = {
|
||||
|
||||
export type ApiUpdatePaidReactionPrivacy = {
|
||||
'@type': 'updatePaidReactionPrivacy';
|
||||
isPrivate: boolean;
|
||||
private: ApiPaidReactionPrivacyType;
|
||||
};
|
||||
|
||||
export type ApiUpdateLangPackTooLong = {
|
||||
|
||||
@ -1633,3 +1633,5 @@
|
||||
"UniqueStatusProofOfOwnershipDescription" = "Tapping the icon of this item next to your name will show its info and owner.";
|
||||
"UniqueStatusWearButton" = "Start Wearing";
|
||||
"CollectibleStatusesCategory" = "Collectibles";
|
||||
"PeerPersonalAccount" = "personal account";
|
||||
"PeerChannel" = "channel";
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
max-height: min(92vh, 38rem) !important;
|
||||
}
|
||||
|
||||
.title {
|
||||
@ -11,7 +12,7 @@
|
||||
}
|
||||
|
||||
.slider {
|
||||
margin-top: 1.5rem;
|
||||
margin-top: 2rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@ -23,13 +24,75 @@
|
||||
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;
|
||||
top: 0.75rem;
|
||||
right: 1.25rem;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.separator {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.checkBox {
|
||||
margin-block: 0.25rem !important;
|
||||
}
|
||||
|
||||
.topLabel {
|
||||
background-image: var(--stars-gradient);
|
||||
color: var(--color-white);
|
||||
@ -61,5 +124,6 @@
|
||||
font-size: 0.875rem;
|
||||
align-self: center;
|
||||
color: var(--color-text-secondary);
|
||||
margin-bottom: 0;
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
@ -1,30 +1,43 @@
|
||||
import type { FC } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
memo, useEffect, useMemo, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||
|
||||
import type {
|
||||
ApiChat, ApiMessage, ApiStarsAmount, ApiUser,
|
||||
ApiChat, ApiMessage, ApiPaidReactionPrivacyType,
|
||||
ApiPeer,
|
||||
ApiSendAsPeerId,
|
||||
ApiStarsAmount, ApiUser,
|
||||
} from '../../../api/types';
|
||||
import type { TabState } from '../../../global/types';
|
||||
import type { CustomPeer } from '../../../types';
|
||||
|
||||
import { STARS_ICON_PLACEHOLDER } from '../../../config';
|
||||
import { getChatTitle, getUserFullName } from '../../../global/helpers';
|
||||
import { selectChat, selectChatMessage, selectUser } from '../../../global/selectors';
|
||||
import { getPeerTitle } from '../../../global/helpers';
|
||||
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 renderText from '../../common/helpers/renderText';
|
||||
|
||||
import useAppLayout from '../../../hooks/useAppLayout';
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
|
||||
import Avatar from '../../common/Avatar';
|
||||
import FullNameTitle from '../../common/FullNameTitle';
|
||||
import Icon from '../../common/icons/Icon';
|
||||
import PeerBadge from '../../common/PeerBadge';
|
||||
import SafeLink from '../../common/SafeLink';
|
||||
import Button from '../../ui/Button';
|
||||
import Checkbox from '../../ui/Checkbox';
|
||||
import DropdownMenu from '../../ui/DropdownMenu';
|
||||
import MenuItem from '../../ui/MenuItem';
|
||||
import Modal from '../../ui/Modal';
|
||||
import Separator from '../../ui/Separator';
|
||||
import BalanceBlock from '../stars/BalanceBlock';
|
||||
@ -41,15 +54,18 @@ type StateProps = {
|
||||
chat?: ApiChat;
|
||||
maxAmount: number;
|
||||
starBalance?: ApiStarsAmount;
|
||||
defaultPrivacy?: boolean;
|
||||
defaultPrivacy?: ApiPaidReactionPrivacyType;
|
||||
sendPaidReactionsAsPeerIds?: ApiSendAsPeerId[];
|
||||
currentUserId: string;
|
||||
currentUser: ApiUser;
|
||||
};
|
||||
|
||||
type ReactorData = {
|
||||
amount: number;
|
||||
localAmount: number;
|
||||
isMe?: boolean;
|
||||
isMy?: boolean;
|
||||
isAnonymous?: boolean;
|
||||
user?: ApiUser;
|
||||
user?: ApiPeer;
|
||||
};
|
||||
|
||||
const MAX_TOP_REACTORS = 3;
|
||||
@ -69,18 +85,27 @@ const PaidReactionModal = ({
|
||||
maxAmount,
|
||||
starBalance,
|
||||
defaultPrivacy,
|
||||
sendPaidReactionsAsPeerIds,
|
||||
currentUserId,
|
||||
currentUser,
|
||||
}: OwnProps & StateProps) => {
|
||||
const { closePaidReactionModal, addLocalPaidReaction } = getActions();
|
||||
const { closePaidReactionModal, addLocalPaidReaction, loadSendPaidReactionsAs } = getActions();
|
||||
|
||||
const [starsAmount, setStarsAmount] = useState(DEFAULT_STARS_AMOUNT);
|
||||
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 { isMobile } = useAppLayout();
|
||||
const lang = useLang();
|
||||
|
||||
const handleAnonimityChange = useLastCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setShouldShowUp(e.target.checked);
|
||||
const handleShowInTopSendersChange = useLastCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setShouldSendAsAnonymous(!e.target.checked);
|
||||
});
|
||||
|
||||
const handleAmountChange = useLastCallback((value: number) => {
|
||||
@ -88,6 +113,21 @@ const PaidReactionModal = ({
|
||||
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(() => {
|
||||
if (!modal) {
|
||||
unmarkTouched();
|
||||
@ -95,14 +135,23 @@ const PaidReactionModal = ({
|
||||
}, [modal]);
|
||||
|
||||
useEffect(() => {
|
||||
const currentReactor = message?.reactions?.topReactors?.find((reactor) => reactor.isMe);
|
||||
const currentReactor = message?.reactions?.topReactors?.find((reactor) => reactor.isMy);
|
||||
if (currentReactor) {
|
||||
setShouldShowUp(!currentReactor.isAnonymous);
|
||||
setShouldSendAsAnonymous(Boolean(currentReactor.isAnonymous));
|
||||
if (currentReactor.peerId) {
|
||||
setSendAsPeerId(currentReactor.peerId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
setShouldShowUp(defaultPrivacy || true);
|
||||
}, [defaultPrivacy, message?.reactions?.topReactors]);
|
||||
setShouldSendAsAnonymous(defaultPrivacy?.type === 'anonymous' || false);
|
||||
if (defaultPrivacy?.type === 'peer' && filteredMyReactorIds?.includes(defaultPrivacy.peerId)) {
|
||||
setSendAsPeerId(defaultPrivacy.peerId);
|
||||
return;
|
||||
}
|
||||
|
||||
setSendAsPeerId(currentUserId);
|
||||
}, [defaultPrivacy, message?.reactions?.topReactors, filteredMyReactorIds, currentUserId]);
|
||||
|
||||
const handleSend = useLastCallback(() => {
|
||||
if (!modal) return;
|
||||
@ -111,11 +160,85 @@ const PaidReactionModal = ({
|
||||
chatId: modal.chatId,
|
||||
messageId: modal.messageId,
|
||||
count: starsAmount,
|
||||
isPrivate: !shouldShowUp,
|
||||
isPrivate: shouldSendAsAnonymous,
|
||||
peerId: shouldSendAsAnonymous || sendAsPeerId === currentUserId ? undefined : sendAsPeerId,
|
||||
shouldIgnoreDefaultPrivacy: true,
|
||||
});
|
||||
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 global = getGlobal();
|
||||
const all = message?.reactions?.topReactors;
|
||||
@ -124,41 +247,49 @@ const PaidReactionModal = ({
|
||||
}
|
||||
|
||||
const result: ReactorData[] = [];
|
||||
let hasMe = false;
|
||||
let hasCurrentSender = false;
|
||||
let myReactorAmount = 0;
|
||||
|
||||
all.forEach((reactor) => {
|
||||
const user = reactor.peerId ? selectUser(global, reactor.peerId) : undefined;
|
||||
if (!user && !reactor.isAnonymous && !reactor.isMe) return;
|
||||
const peer = reactor.peerId ? selectPeer(global, reactor.peerId) : undefined;
|
||||
if (!peer && !reactor.isAnonymous && !reactor.isMy) return;
|
||||
if (reactor.isMy) {
|
||||
myReactorAmount = reactor.count;
|
||||
}
|
||||
|
||||
if (reactor.isMe) {
|
||||
hasMe = true;
|
||||
if (reactor.isMy && (reactor.peerId !== sendAsPeerId || (reactor.isAnonymous && !shouldSendAsAnonymous))) return;
|
||||
|
||||
const isCurrentReactor = sendAsPeerId === reactor.peerId || (shouldSendAsAnonymous && reactor.isAnonymous);
|
||||
|
||||
if (isCurrentReactor) {
|
||||
hasCurrentSender = true;
|
||||
}
|
||||
|
||||
result.push({
|
||||
amount: reactor.count,
|
||||
localAmount: reactor.isMe && isTouched ? starsAmount : 0,
|
||||
isMe: reactor.isMe,
|
||||
localAmount: isCurrentReactor && isTouched ? starsAmount : 0,
|
||||
isMy: reactor.isMy,
|
||||
isAnonymous: reactor.isAnonymous,
|
||||
user,
|
||||
user: peer,
|
||||
});
|
||||
});
|
||||
|
||||
if (!hasMe && isTouched) {
|
||||
const me = selectUser(global, global.currentUserId!);
|
||||
if (!hasCurrentSender) {
|
||||
const sender = selectPeer(global, sendAsPeerId);
|
||||
result.push({
|
||||
amount: 0,
|
||||
localAmount: starsAmount,
|
||||
isMe: true,
|
||||
user: me,
|
||||
amount: myReactorAmount,
|
||||
localAmount: isTouched ? starsAmount : 0,
|
||||
isMy: true,
|
||||
user: sender,
|
||||
});
|
||||
}
|
||||
|
||||
result.sort((a, b) => (b.amount + b.localAmount) - (a.amount + a.localAmount));
|
||||
|
||||
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 (
|
||||
<Modal
|
||||
@ -168,7 +299,10 @@ const PaidReactionModal = ({
|
||||
hasAbsoluteCloseButton
|
||||
contentClassName={styles.content}
|
||||
>
|
||||
<BalanceBlock balance={starBalance} className={styles.modalBalance} />
|
||||
<div className={styles.headerControlPanel}>
|
||||
{sendAsPeersMenu}
|
||||
<BalanceBlock balance={starBalance} className={styles.modalBalance} />
|
||||
</div>
|
||||
<StarSlider
|
||||
className={styles.slider}
|
||||
defaultValue={DEFAULT_STARS_AMOUNT}
|
||||
@ -186,9 +320,10 @@ const PaidReactionModal = ({
|
||||
<div className={styles.top}>
|
||||
{topReactors.map((reactor) => {
|
||||
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;
|
||||
const text = 'isCustomPeer' in peer ? oldLang(peer.titleKey) : getUserFullName(peer);
|
||||
const text = 'isCustomPeer' in peer ? oldLang(peer.titleKey)
|
||||
: peer && getPeerTitle(oldLang, peer);
|
||||
return (
|
||||
<PeerBadge
|
||||
className={styles.topPeer}
|
||||
@ -203,10 +338,11 @@ const PaidReactionModal = ({
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{topReactors && (<Separator className={styles.separator} />) }
|
||||
<Checkbox
|
||||
className="dialog-checkbox"
|
||||
checked={shouldShowUp}
|
||||
onChange={handleAnonimityChange}
|
||||
className={buildClassName(styles.checkBox, 'dialog-checkbox')}
|
||||
checked={!shouldSendAsAnonymous}
|
||||
onChange={handleShowInTopSendersChange}
|
||||
label={oldLang('StarsReactionShowMeInTopSenders')}
|
||||
/>
|
||||
<Button
|
||||
@ -238,6 +374,9 @@ export default memo(withGlobal<OwnProps>(
|
||||
const starBalance = global.stars?.balance;
|
||||
const maxAmount = global.appConfig?.paidReactionMaxAmount || MAX_REACTION_AMOUNT;
|
||||
const defaultPrivacy = global.settings.paidReactionPrivacy;
|
||||
const sendPaidReactionsAsPeerIds = chat?.sendPaidReactionsAsPeerIds;
|
||||
const currentUserId = global.currentUserId!;
|
||||
const currentUser = selectUser(global, currentUserId)!;
|
||||
|
||||
return {
|
||||
chat,
|
||||
@ -245,6 +384,9 @@ export default memo(withGlobal<OwnProps>(
|
||||
starBalance,
|
||||
maxAmount,
|
||||
defaultPrivacy,
|
||||
sendPaidReactionsAsPeerIds,
|
||||
currentUserId,
|
||||
currentUser,
|
||||
};
|
||||
},
|
||||
)(PaidReactionModal));
|
||||
|
||||
@ -11,6 +11,7 @@ import './DropdownMenu.scss';
|
||||
|
||||
type OwnProps = {
|
||||
className?: string;
|
||||
bubbleClassName?: string;
|
||||
trigger?: FC<{ onTrigger: () => void; isOpen?: boolean }>;
|
||||
transformOriginX?: number;
|
||||
transformOriginY?: number;
|
||||
@ -30,6 +31,7 @@ type OwnProps = {
|
||||
const DropdownMenu: FC<OwnProps> = ({
|
||||
trigger,
|
||||
className,
|
||||
bubbleClassName,
|
||||
children,
|
||||
transformOriginX,
|
||||
transformOriginY,
|
||||
@ -107,6 +109,7 @@ const DropdownMenu: FC<OwnProps> = ({
|
||||
ref={menuRef}
|
||||
isOpen={isOpen || Boolean(forceOpen)}
|
||||
className={className || ''}
|
||||
bubbleClassName={bubbleClassName || ''}
|
||||
transformOriginX={transformOriginX}
|
||||
transformOriginY={transformOriginY}
|
||||
positionX={positionX}
|
||||
|
||||
@ -1646,7 +1646,30 @@ addActionHandler('loadSendAs', async (global, actions, payload): Promise<void> =
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
|
||||
@ -246,8 +246,13 @@ addActionHandler('toggleReaction', async (global, actions, payload): Promise<voi
|
||||
|
||||
addActionHandler('addLocalPaidReaction', (global, actions, payload): ActionReturnType => {
|
||||
const {
|
||||
chatId, messageId, count, isPrivate, tabId = getCurrentTabId(),
|
||||
chatId, messageId, count, shouldIgnoreDefaultPrivacy = false, tabId = getCurrentTabId(),
|
||||
} = 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 message = selectChatMessage(global, chatId, messageId);
|
||||
|
||||
@ -256,7 +261,7 @@ addActionHandler('addLocalPaidReaction', (global, actions, payload): ActionRetur
|
||||
}
|
||||
|
||||
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, {
|
||||
reactions: {
|
||||
...currentReactions,
|
||||
@ -301,6 +306,7 @@ addActionHandler('sendPaidReaction', async (global, actions, payload): Promise<v
|
||||
messageId,
|
||||
count,
|
||||
isPrivate: paidReaction?.localIsPrivate,
|
||||
peerId: paidReaction?.localPeerId,
|
||||
});
|
||||
} catch (error) {
|
||||
if ((error as ApiError).message === 'BALANCE_TOO_LOW') {
|
||||
|
||||
@ -857,7 +857,8 @@ function updateReactions<T extends GlobalState>(
|
||||
const localPaidReaction = currentReactions?.results.find((r) => r.localAmount);
|
||||
// Save local count on update, but reset if we sent reaction
|
||||
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 });
|
||||
|
||||
@ -199,7 +199,7 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
...global,
|
||||
settings: {
|
||||
...global.settings,
|
||||
paidReactionPrivacy: update.isPrivate,
|
||||
paidReactionPrivacy: update.private,
|
||||
},
|
||||
};
|
||||
setGlobal(global);
|
||||
|
||||
@ -122,7 +122,7 @@ export function updateReactionCount(reactionCount: ApiReactionCount[], newReacti
|
||||
}
|
||||
|
||||
export function addPaidReaction(
|
||||
reactionCount: ApiReactionCount[], count: number, isAnonymous?: boolean,
|
||||
reactionCount: ApiReactionCount[], count: number, isAnonymous?: boolean, peerId?: string,
|
||||
): ApiReactionCount[] {
|
||||
const results: ApiReactionCount[] = [];
|
||||
const hasPaid = reactionCount.some((current) => current.reaction.type === 'paid');
|
||||
@ -134,6 +134,7 @@ export function addPaidReaction(
|
||||
localAmount: (current.localAmount || 0) + count,
|
||||
chosenOrder: -1,
|
||||
localIsPrivate: isAnonymous !== undefined ? isAnonymous : current.localIsPrivate,
|
||||
localPeerId: peerId || current.localPeerId,
|
||||
localPreviousChosenOrder: current.chosenOrder,
|
||||
});
|
||||
return;
|
||||
@ -152,6 +153,7 @@ export function addPaidReaction(
|
||||
chosenOrder: -1,
|
||||
localAmount: count,
|
||||
localIsPrivate: isAnonymous,
|
||||
localPeerId: peerId,
|
||||
},
|
||||
...reactionCount,
|
||||
];
|
||||
|
||||
@ -536,6 +536,9 @@ export interface ActionPayloads {
|
||||
loadSendAs: {
|
||||
chatId: string;
|
||||
};
|
||||
loadSendPaidReactionsAs: {
|
||||
chatId: string;
|
||||
};
|
||||
saveDefaultSendAs: {
|
||||
chatId: string;
|
||||
sendAsId: string;
|
||||
@ -1384,7 +1387,9 @@ export interface ActionPayloads {
|
||||
chatId: string;
|
||||
messageId: number;
|
||||
count: number;
|
||||
peerId?: string;
|
||||
isPrivate?: boolean;
|
||||
shouldIgnoreDefaultPrivacy?: boolean;
|
||||
} & WithTabId;
|
||||
resetLocalPaidReactions: {
|
||||
chatId: string;
|
||||
|
||||
@ -15,6 +15,7 @@ import type {
|
||||
ApiGroupCall,
|
||||
ApiLanguage,
|
||||
ApiMessage,
|
||||
ApiPaidReactionPrivacyType,
|
||||
ApiPeerColors,
|
||||
ApiPeerPhotos,
|
||||
ApiPeerStories,
|
||||
@ -408,7 +409,7 @@ export type GlobalState = {
|
||||
privacy: Partial<Record<ApiPrivacyKey, ApiPrivacySettings>>;
|
||||
notifyExceptions?: Record<number, NotifyException>;
|
||||
lastPremiumBandwithNotificationDate?: number;
|
||||
paidReactionPrivacy?: boolean;
|
||||
paidReactionPrivacy?: ApiPaidReactionPrivacyType;
|
||||
languages?: ApiLanguage[];
|
||||
botVerificationShownPeerIds: string[];
|
||||
miniAppsCachedPosition?: Point;
|
||||
|
||||
@ -12,5 +12,5 @@ for (const tl of Object.values(Api)) {
|
||||
}
|
||||
}
|
||||
|
||||
export const LAYER = 198;
|
||||
export const LAYER = 199;
|
||||
export { tlobjects };
|
||||
|
||||
42
src/lib/gramjs/tl/api.d.ts
vendored
42
src/lib/gramjs/tl/api.d.ts
vendored
@ -388,6 +388,7 @@ namespace Api {
|
||||
export type TypeStarGiftAttribute = StarGiftAttributeModel | StarGiftAttributePattern | StarGiftAttributeBackdrop | StarGiftAttributeOriginalDetails;
|
||||
export type TypeSavedStarGift = SavedStarGift;
|
||||
export type TypeInputSavedStarGift = InputSavedStarGiftUser | InputSavedStarGiftChat;
|
||||
export type TypePaidReactionPrivacy = PaidReactionPrivacyDefault | PaidReactionPrivacyAnonymous | PaidReactionPrivacyPeer;
|
||||
export type TypeResPQ = ResPQ;
|
||||
export type TypeP_Q_inner_data = PQInnerData | PQInnerDataDc | PQInnerDataTemp | PQInnerDataTempDc;
|
||||
export type TypeServer_DH_Params = ServerDHParamsFail | ServerDHParamsOk;
|
||||
@ -4490,9 +4491,9 @@ namespace Api {
|
||||
static fromReader(reader: Reader): UpdateBotPurchasedPaidMedia;
|
||||
}
|
||||
export class UpdatePaidReactionPrivacy extends VirtualClass<{
|
||||
private: Bool;
|
||||
private: Api.TypePaidReactionPrivacy;
|
||||
}> {
|
||||
private: Bool;
|
||||
private: Api.TypePaidReactionPrivacy;
|
||||
static fromReader(reader: Reader): UpdatePaidReactionPrivacy;
|
||||
}
|
||||
export class UpdatesTooLong extends VirtualClass<void> {
|
||||
@ -5365,6 +5366,7 @@ namespace Api {
|
||||
export class WebPage extends VirtualClass<{
|
||||
// flags: Api.Type;
|
||||
hasLargeMedia?: true;
|
||||
videoCoverPhoto?: true;
|
||||
id: long;
|
||||
url: string;
|
||||
displayUrl: string;
|
||||
@ -5386,6 +5388,7 @@ namespace Api {
|
||||
}> {
|
||||
// flags: Api.Type;
|
||||
hasLargeMedia?: true;
|
||||
videoCoverPhoto?: true;
|
||||
id: long;
|
||||
url: string;
|
||||
displayUrl: string;
|
||||
@ -12070,6 +12073,7 @@ namespace Api {
|
||||
attributes: Api.TypeStarGiftAttribute[];
|
||||
availabilityIssued: int;
|
||||
availabilityTotal: int;
|
||||
giftAddress?: string;
|
||||
}> {
|
||||
// flags: Api.Type;
|
||||
id: long;
|
||||
@ -12082,6 +12086,7 @@ namespace Api {
|
||||
attributes: Api.TypeStarGiftAttribute[];
|
||||
availabilityIssued: int;
|
||||
availabilityTotal: int;
|
||||
giftAddress?: string;
|
||||
static fromReader(reader: Reader): StarGiftUnique;
|
||||
}
|
||||
export class MessageReportOption extends VirtualClass<{
|
||||
@ -12297,6 +12302,18 @@ namespace Api {
|
||||
savedId: long;
|
||||
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<{
|
||||
nonce: int128;
|
||||
serverNonce: int128;
|
||||
@ -15711,6 +15728,13 @@ namespace Api {
|
||||
secret: string;
|
||||
query: X;
|
||||
}
|
||||
export class InvokeWithReCaptcha extends Request<Partial<{
|
||||
token: string;
|
||||
query: X;
|
||||
}>, X> {
|
||||
token: string;
|
||||
query: X;
|
||||
}
|
||||
export class ReqPq extends Request<Partial<{
|
||||
nonce: int128;
|
||||
}>, Api.TypeResPQ> {
|
||||
@ -19013,23 +19037,23 @@ namespace Api {
|
||||
msgId: int;
|
||||
count: int;
|
||||
randomId: long;
|
||||
private?: Bool;
|
||||
private?: Api.TypePaidReactionPrivacy;
|
||||
}>, Api.TypeUpdates> {
|
||||
// flags: Api.Type;
|
||||
peer: Api.TypeInputPeer;
|
||||
msgId: int;
|
||||
count: int;
|
||||
randomId: long;
|
||||
private?: Bool;
|
||||
private?: Api.TypePaidReactionPrivacy;
|
||||
}
|
||||
export class TogglePaidReactionPrivacy extends Request<Partial<{
|
||||
peer: Api.TypeInputPeer;
|
||||
msgId: int;
|
||||
private: Bool;
|
||||
private: Api.TypePaidReactionPrivacy;
|
||||
}>, Bool> {
|
||||
peer: Api.TypeInputPeer;
|
||||
msgId: int;
|
||||
private: Bool;
|
||||
private: Api.TypePaidReactionPrivacy;
|
||||
}
|
||||
export class GetPaidReactionPrivacy extends Request<void, Api.TypeUpdates> {}
|
||||
export class ViewSponsoredMessage extends Request<Partial<{
|
||||
@ -19682,8 +19706,12 @@ namespace Api {
|
||||
channel: Api.TypeInputChannel;
|
||||
}
|
||||
export class GetSendAs extends Request<Partial<{
|
||||
// flags: Api.Type;
|
||||
forPaidReactions?: true;
|
||||
peer: Api.TypeInputPeer;
|
||||
}>, channels.TypeSendAsPeers> {
|
||||
// flags: Api.Type;
|
||||
forPaidReactions?: true;
|
||||
peer: Api.TypeInputPeer;
|
||||
}
|
||||
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
|
||||
| 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
|
||||
|
||||
@ -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;
|
||||
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = 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.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;
|
||||
@ -510,7 +510,7 @@ messages.allStickers#cdbbcebb hash:long sets:Vector<StickerSet> = messages.AllSt
|
||||
messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
|
||||
webPageEmpty#211a1788 flags:# id:long url:flags.0?string = 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;
|
||||
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;
|
||||
@ -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;
|
||||
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;
|
||||
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.starGifts#901689ea hash:int gifts:Vector<StarGift> = payments.StarGifts;
|
||||
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;
|
||||
inputSavedStarGiftChat#f101aa7f peer:InputPeer saved_id:long = InputSavedStarGift;
|
||||
payments.starGiftWithdrawalUrl#84aa3a9c url:string = payments.StarGiftWithdrawalUrl;
|
||||
paidReactionPrivacyDefault#206ad49e = PaidReactionPrivacy;
|
||||
paidReactionPrivacyAnonymous#1f0c1ad9 = PaidReactionPrivacy;
|
||||
paidReactionPrivacyPeer#dc6cfcf0 peer:InputPeer = PaidReactionPrivacy;
|
||||
---functions---
|
||||
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;
|
||||
@ -1615,7 +1618,7 @@ messages.sendQuickReplyMessages#6c750de1 peer:InputPeer shortcut_id:int id:Vecto
|
||||
messages.getAvailableEffects#dea20a39 hash:int = messages.AvailableEffects;
|
||||
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.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.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;
|
||||
@ -1668,7 +1671,7 @@ channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool
|
||||
channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates;
|
||||
channels.getGroupsForDiscussion#f5dad378 = messages.Chats;
|
||||
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.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;
|
||||
|
||||
@ -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;
|
||||
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = 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;
|
||||
|
||||
@ -599,7 +599,7 @@ messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMess
|
||||
|
||||
webPageEmpty#211a1788 flags:# id:long url:flags.0?string = 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;
|
||||
|
||||
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;
|
||||
|
||||
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.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;
|
||||
|
||||
paidReactionPrivacyDefault#206ad49e = PaidReactionPrivacy;
|
||||
paidReactionPrivacyAnonymous#1f0c1ad9 = PaidReactionPrivacy;
|
||||
paidReactionPrivacyPeer#dc6cfcf0 peer:InputPeer = PaidReactionPrivacy;
|
||||
|
||||
---functions---
|
||||
|
||||
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;
|
||||
invokeWithGooglePlayIntegrity#1df92984 {X:Type} nonce:string token: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.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.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.sendPaidReaction#9dd6a67b flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?Bool = Updates;
|
||||
messages.togglePaidReactionPrivacy#849ad397 peer:InputPeer msg_id:int private:Bool = Bool;
|
||||
messages.sendPaidReaction#58bbcb50 flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?PaidReactionPrivacy = Updates;
|
||||
messages.togglePaidReactionPrivacy#435885b5 peer:InputPeer msg_id:int private:PaidReactionPrivacy = Bool;
|
||||
messages.getPaidReactionPrivacy#472455aa = Updates;
|
||||
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;
|
||||
@ -2423,7 +2428,7 @@ channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint addr
|
||||
channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates;
|
||||
channels.getInactiveChannels#11e831ee = messages.InactiveChats;
|
||||
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.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;
|
||||
|
||||
2
src/types/language.d.ts
vendored
2
src/types/language.d.ts
vendored
@ -1333,6 +1333,8 @@ export interface LangPair {
|
||||
'UniqueStatusProofOfOwnershipDescription': undefined;
|
||||
'UniqueStatusWearButton': undefined;
|
||||
'CollectibleStatusesCategory': undefined;
|
||||
'PeerPersonalAccount': undefined;
|
||||
'PeerChannel': undefined;
|
||||
}
|
||||
|
||||
export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user