diff --git a/src/api/gramjs/apiBuilders/appConfig.ts b/src/api/gramjs/apiBuilders/appConfig.ts index e4842af1d..7a6a74d09 100644 --- a/src/api/gramjs/apiBuilders/appConfig.ts +++ b/src/api/gramjs/apiBuilders/appConfig.ts @@ -73,6 +73,7 @@ export function buildAppConfig(json: GramJs.TypeJSONValue): ApiAppConfig { urlAuthDomains: appConfig.url_auth_domains || [], premiumBotUsername: appConfig.premium_bot_username, premiumInvoiceSlug: appConfig.premium_invoice_slug, + premiumPromoOrder: appConfig.premium_promo_order, isPremiumPurchaseBlocked: appConfig.premium_purchase_blocked, limits: { uploadMaxFileparts: getLimit(appConfig, 'upload_max_fileparts', 'uploadMaxFileparts'), diff --git a/src/api/gramjs/apiBuilders/symbols.ts b/src/api/gramjs/apiBuilders/symbols.ts index c0a727ebe..82b28ba6d 100644 --- a/src/api/gramjs/apiBuilders/symbols.ts +++ b/src/api/gramjs/apiBuilders/symbols.ts @@ -106,12 +106,14 @@ export function buildStickerSet(set: GramJs.StickerSet): ApiStickerSet { thumbs, count, shortName, + emojis, } = set; return { archived, isLottie: animated, isVideos: videos, + isEmoji: emojis, installedDate, id: String(id), accessHash: String(accessHash), @@ -125,9 +127,9 @@ export function buildStickerSet(set: GramJs.StickerSet): ApiStickerSet { export function buildStickerSetCovered(coveredStickerSet: GramJs.TypeStickerSetCovered): ApiStickerSet { const stickerSet = buildStickerSet(coveredStickerSet.set); - const stickerSetCovers = (coveredStickerSet instanceof GramJs.StickerSetMultiCovered) - ? coveredStickerSet.covers - : [coveredStickerSet.cover]; + const stickerSetCovers = (coveredStickerSet instanceof GramJs.StickerSetCovered) ? [coveredStickerSet.cover] + : (coveredStickerSet instanceof GramJs.StickerSetMultiCovered) ? coveredStickerSet.covers + : coveredStickerSet.documents; stickerSet.covers = []; stickerSetCovers.forEach((cover) => { diff --git a/src/api/gramjs/apiBuilders/users.ts b/src/api/gramjs/apiBuilders/users.ts index 19697e3c7..99ca98192 100644 --- a/src/api/gramjs/apiBuilders/users.ts +++ b/src/api/gramjs/apiBuilders/users.ts @@ -1,5 +1,6 @@ import { Api as GramJs } from '../../../lib/gramjs'; import type { + ApiPremiumGiftOption, ApiUser, ApiUserStatus, ApiUserType, } from '../../types'; import { buildApiPeerId } from './peers'; @@ -10,7 +11,7 @@ export function buildApiUserFromFull(mtpUserFull: GramJs.users.UserFull): ApiUse const { fullUser: { about, commonChatsCount, pinnedMsgId, botInfo, blocked, - profilePhoto, + profilePhoto, voiceMessagesForbidden, premiumGifts, }, users, } = mtpUserFull; @@ -25,6 +26,8 @@ export function buildApiUserFromFull(mtpUserFull: GramJs.users.UserFull): ApiUse commonChatsCount, pinnedMessageId: pinnedMsgId, isBlocked: Boolean(blocked), + noVoiceMessages: voiceMessagesForbidden, + ...(premiumGifts && { premiumGifts: premiumGifts.map((gift) => buildApiPremiumGiftOption(gift)) }), ...(botInfo && { botInfo: buildApiBotInfo(botInfo, user.id) }), }, }; @@ -115,3 +118,16 @@ export function buildApiUsersAndStatuses(mtpUsers: GramJs.TypeUser[]) { return { users, userStatusesById }; } + +export function buildApiPremiumGiftOption(option: GramJs.TypePremiumGiftOption): ApiPremiumGiftOption { + const { + months, currency, amount, botUrl, + } = option; + + return { + months, + currency, + amount: amount.toJSNumber(), + botUrl, + }; +} diff --git a/src/api/types/messages.ts b/src/api/types/messages.ts index 7c189213a..4e043b3a7 100644 --- a/src/api/types/messages.ts +++ b/src/api/types/messages.ts @@ -48,6 +48,7 @@ export interface ApiStickerSet { archived?: true; isLottie?: true; isVideos?: true; + isEmoji?: true; installedDate?: number; id: string; accessHash: string; diff --git a/src/api/types/misc.ts b/src/api/types/misc.ts index 25b94aba0..39f4b402e 100644 --- a/src/api/types/misc.ts +++ b/src/api/types/misc.ts @@ -170,6 +170,7 @@ export interface ApiAppConfig { premiumInvoiceSlug: string; premiumBotUsername: string; isPremiumPurchaseBlocked: boolean; + premiumPromoOrder: string[]; limits: Record; } diff --git a/src/api/types/users.ts b/src/api/types/users.ts index 7ea24dcd8..e50e3e112 100644 --- a/src/api/types/users.ts +++ b/src/api/types/users.ts @@ -39,6 +39,8 @@ export interface ApiUserFullInfo { pinnedMessageId?: number; botInfo?: ApiBotInfo; profilePhoto?: ApiPhoto; + noVoiceMessages?: boolean; + premiumGifts?: ApiPremiumGiftOption[]; } export type ApiFakeType = 'fake' | 'scam'; @@ -68,3 +70,10 @@ export interface ApiAttachMenuBotIcon { name: string; document: ApiDocument; } + +export interface ApiPremiumGiftOption { + months: number; + currency: string; + amount: number; + botUrl: string; +} diff --git a/src/assets/premium/PremiumAds.svg b/src/assets/premium/PremiumAds.svg index 490a62c8c..9d9f3c7f9 100644 --- a/src/assets/premium/PremiumAds.svg +++ b/src/assets/premium/PremiumAds.svg @@ -1,5 +1,4 @@ - diff --git a/src/assets/premium/PremiumBadge.svg b/src/assets/premium/PremiumBadge.svg index 9284aaf79..db301fcf3 100644 --- a/src/assets/premium/PremiumBadge.svg +++ b/src/assets/premium/PremiumBadge.svg @@ -1,4 +1,3 @@ - diff --git a/src/assets/premium/PremiumChats.svg b/src/assets/premium/PremiumChats.svg index d9bfe816b..52398ddee 100644 --- a/src/assets/premium/PremiumChats.svg +++ b/src/assets/premium/PremiumChats.svg @@ -1,4 +1,3 @@ - diff --git a/src/assets/premium/PremiumEmoji.svg b/src/assets/premium/PremiumEmoji.svg new file mode 100644 index 000000000..e3180c42f --- /dev/null +++ b/src/assets/premium/PremiumEmoji.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/premium/PremiumFile.svg b/src/assets/premium/PremiumFile.svg index c7da3403b..a098d8c7c 100644 --- a/src/assets/premium/PremiumFile.svg +++ b/src/assets/premium/PremiumFile.svg @@ -1,4 +1,3 @@ - diff --git a/src/assets/premium/PremiumLimits.svg b/src/assets/premium/PremiumLimits.svg index e2e0da61b..2b7dd71f4 100644 --- a/src/assets/premium/PremiumLimits.svg +++ b/src/assets/premium/PremiumLimits.svg @@ -1,4 +1,3 @@ - diff --git a/src/assets/premium/PremiumReactions.svg b/src/assets/premium/PremiumReactions.svg index 48d307a30..0fe3a542a 100644 --- a/src/assets/premium/PremiumReactions.svg +++ b/src/assets/premium/PremiumReactions.svg @@ -1,4 +1,3 @@ - diff --git a/src/assets/premium/PremiumSpeed.svg b/src/assets/premium/PremiumSpeed.svg index 3b7ae10d7..0d2bc2db9 100644 --- a/src/assets/premium/PremiumSpeed.svg +++ b/src/assets/premium/PremiumSpeed.svg @@ -1,4 +1,3 @@ - diff --git a/src/assets/premium/PremiumStickers.svg b/src/assets/premium/PremiumStickers.svg index c9d4a8f62..b062247a2 100644 --- a/src/assets/premium/PremiumStickers.svg +++ b/src/assets/premium/PremiumStickers.svg @@ -1,4 +1,3 @@ - diff --git a/src/assets/premium/PremiumVideo.svg b/src/assets/premium/PremiumVideo.svg index 7f11bd99b..2f7ce8dbc 100644 --- a/src/assets/premium/PremiumVideo.svg +++ b/src/assets/premium/PremiumVideo.svg @@ -1,4 +1,3 @@ - diff --git a/src/assets/premium/PremiumVoice.svg b/src/assets/premium/PremiumVoice.svg index 1b95419c9..8e10aac12 100644 --- a/src/assets/premium/PremiumVoice.svg +++ b/src/assets/premium/PremiumVoice.svg @@ -1,4 +1,3 @@ - diff --git a/src/components/common/PremiumIcon.tsx b/src/components/common/PremiumIcon.tsx index 67396320d..02791ab1b 100644 --- a/src/components/common/PremiumIcon.tsx +++ b/src/components/common/PremiumIcon.tsx @@ -14,12 +14,14 @@ const store: Record = {}; type OwnProps = { withGradient?: boolean; big?: boolean; + className?: string; onClick?: VoidFunction; }; const PremiumIcon: FC = ({ withGradient, big, + className, onClick, }) => { const html = useMemo(() => { @@ -29,7 +31,9 @@ const PremiumIcon: FC = ({ return ( diff --git a/src/components/common/StickerButton.tsx b/src/components/common/StickerButton.tsx index 12261c287..8c6c5f797 100644 --- a/src/components/common/StickerButton.tsx +++ b/src/components/common/StickerButton.tsx @@ -145,7 +145,7 @@ const StickerButton = { if (isContextMenuOpen) return; if (isLocked) { - openPremiumModal({ initialSection: 'stickers' }); + openPremiumModal({ initialSection: 'premium_stickers' }); return; } onClick?.(clickArg); diff --git a/src/components/left/main/LeftMainHeader.tsx b/src/components/left/main/LeftMainHeader.tsx index 33684ebc5..951157ab0 100644 --- a/src/components/left/main/LeftMainHeader.tsx +++ b/src/components/left/main/LeftMainHeader.tsx @@ -25,7 +25,7 @@ import { formatDateToString } from '../../../util/dateFormat'; import switchTheme from '../../../util/switchTheme'; import { setPermanentWebVersion } from '../../../util/permanentWebVersion'; import { clearWebsync } from '../../../util/websync'; -import { selectCurrentMessageList, selectIsPremiumPurchaseBlocked, selectTheme } from '../../../global/selectors'; +import { selectCurrentMessageList, selectTheme } from '../../../global/selectors'; import { isChatArchived } from '../../../global/helpers'; import useLang from '../../../hooks/useLang'; import useConnectionStatus from '../../../hooks/useConnectionStatus'; @@ -38,7 +38,6 @@ import MenuItem from '../../ui/MenuItem'; import Button from '../../ui/Button'; import SearchInput from '../../ui/SearchInput'; import PickerSelectedItem from '../../common/PickerSelectedItem'; -import PremiumIcon from '../../common/PremiumIcon'; import Switcher from '../../ui/Switcher'; import ShowTransition from '../../ui/ShowTransition'; import ConnectionStatusOverlay from '../ConnectionStatusOverlay'; @@ -70,7 +69,6 @@ type StateProps = isConnectionStatusMinimized: ISettings['isConnectionStatusMinimized']; areChatsLoaded?: boolean; hasPasscode?: boolean; - isPremiumPurchaseBlocked?: boolean; } & Pick; @@ -101,7 +99,6 @@ const LeftMainHeader: FC = ({ areChatsLoaded, hasPasscode, canInstall, - isPremiumPurchaseBlocked, }) => { const { openChat, @@ -112,7 +109,6 @@ const LeftMainHeader: FC = ({ lockScreen, requestNextSettingsScreen, skipLockOnUnload, - openPremiumModal, } = getActions(); const lang = useLang(); @@ -197,10 +193,6 @@ const LeftMainHeader: FC = ({ openChat({ id: currentUserId, shouldReplaceHistory: true }); }, [currentUserId, openChat]); - const handleSelectPremium = useCallback(() => { - openPremiumModal(); - }, [openPremiumModal]); - const handleDarkModeToggle = useCallback((e: React.SyntheticEvent) => { e.stopPropagation(); const newTheme = theme === 'light' ? 'dark' : 'light'; @@ -292,15 +284,6 @@ const LeftMainHeader: FC = ({ noAnimation /> - {!isPremiumPurchaseBlocked && ( - } - onClick={handleSelectPremium} - > - {lang('TelegramPremium')} - {lang('New')} - - )} ( areChatsLoaded: Boolean(global.chats.listIds.active), hasPasscode: Boolean(global.passcode.hasPasscode), canInstall: Boolean(global.canInstall), - isPremiumPurchaseBlocked: selectIsPremiumPurchaseBlocked(global), }; }, )(LeftMainHeader)); diff --git a/src/components/left/settings/SettingsMain.tsx b/src/components/left/settings/SettingsMain.tsx index 36ca40505..dc2437109 100644 --- a/src/components/left/settings/SettingsMain.tsx +++ b/src/components/left/settings/SettingsMain.tsx @@ -112,16 +112,6 @@ const SettingsMain: FC = ({ > {lang('Filters')} - {canBuyPremium && ( - } - className="settings-main-menu-premium" - // eslint-disable-next-line react/jsx-no-bind - onClick={() => openPremiumModal()} - > - {lang('TelegramPremium')} - - )} = ({ {lang('Language')} {lang.langName} + {canBuyPremium && ( + } + className="settings-main-menu-premium" + // eslint-disable-next-line react/jsx-no-bind + onClick={() => openPremiumModal()} + > + {lang('TelegramPremium')} + + )} ); diff --git a/src/components/main/WebAppModal.scss b/src/components/main/WebAppModal.scss index 13d55a450..0149bfebb 100644 --- a/src/components/main/WebAppModal.scss +++ b/src/components/main/WebAppModal.scss @@ -106,3 +106,22 @@ } } } + +.web-app-popup { + .modal-dialog { + max-width: min(30rem, 100%); + } + + &.without-title .modal-content { + padding-top: 0; + } + + .modal-content { + padding-left: 2rem; + } + + .dialog-buttons { + justify-content: flex-end; + gap: 0.25rem; + } +} diff --git a/src/components/main/WebAppModal.tsx b/src/components/main/WebAppModal.tsx index ae826cf75..9874cb76d 100644 --- a/src/components/main/WebAppModal.tsx +++ b/src/components/main/WebAppModal.tsx @@ -1,12 +1,13 @@ -import type { FC } from '../../lib/teact/teact'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState, } from '../../lib/teact/teact'; import { getActions, withGlobal } from '../../global'; +import type { FC } from '../../lib/teact/teact'; import type { ApiAttachMenuBot, ApiChat, ApiUser } from '../../api/types'; import type { GlobalState } from '../../global/types'; import type { ThemeKey } from '../../types'; +import type { PopupOptions, WebAppInboundEvent } from './hooks/useWebAppFrame'; import windowSize from '../../util/windowSize'; import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment'; @@ -18,15 +19,16 @@ import { extractCurrentThemeParams, validateHexColor } from '../../util/themeSty import useInterval from '../../hooks/useInterval'; import useLang from '../../hooks/useLang'; import useOnChange from '../../hooks/useOnChange'; -import type { WebAppInboundEvent } from './hooks/useWebAppFrame'; import useWebAppFrame from './hooks/useWebAppFrame'; import usePrevious from '../../hooks/usePrevious'; +import useFlag from '../../hooks/useFlag'; import Modal from '../ui/Modal'; import Button from '../ui/Button'; import DropdownMenu from '../ui/DropdownMenu'; import MenuItem from '../ui/MenuItem'; import Spinner from '../ui/Spinner'; +import ConfirmDialog from '../ui/ConfirmDialog'; import './WebAppModal.scss'; @@ -52,6 +54,8 @@ type StateProps = { paymentStatus?: GlobalState['payment']['status']; }; +const NBSP = '\u00A0'; + const MAIN_BUTTON_ANIMATION_TIME = 250; const PROLONG_INTERVAL = 45000; // 45s const ANIMATION_WAIT = 400; @@ -64,6 +68,12 @@ const SANDBOX_ATTRIBUTES = [ 'allow-storage-access-by-user-activation', ].join(' '); +const DEFAULT_BUTTON_TEXT: Record = { + ok: 'OK', + cancel: 'Cancel', + close: 'Close', +}; + const WebAppModal: FC = ({ webApp, chat, @@ -87,6 +97,12 @@ const WebAppModal: FC = ({ const [isBackButtonVisible, setIsBackButtonVisible] = useState(false); const [backgroundColor, setBackgroundColor] = useState(extractCurrentThemeParams().bg_color); const [headerColor, setHeaderColor] = useState(extractCurrentThemeParams().bg_color); + const [confirmClose, setConfirmClose] = useState(false); + const [isCloseModalOpen, openCloseModal, closeCloseModal] = useFlag(false); + const [popupParams, setPopupParams] = useState(); + const prevPopupParams = usePrevious(popupParams); + const renderingPopupParams = popupParams || prevPopupParams; + const lang = useLang(); const { url, buttonText, queryId, @@ -160,6 +176,15 @@ const WebAppModal: FC = ({ isProgressVisible: eventData.is_progress_visible, }); } + + if (eventType === 'web_app_setup_closing_behavior') { + setConfirmClose(eventData.need_confirmation); + } + + if (eventType === 'web_app_open_popup') { + if (!eventData.message.trim().length || !eventData.buttons?.length || eventData.buttons.length > 3) return; + setPopupParams(eventData); + } }, [bot, buttonText, closeWebApp, openInvoice, openTelegramLink, sendWebViewData, setWebAppPaymentSlug]); const { @@ -192,6 +217,24 @@ const WebAppModal: FC = ({ reloadFrame(webApp!.url); }, [reloadFrame, webApp]); + const handleClose = useCallback(() => { + if (confirmClose) { + openCloseModal(); + } else { + closeWebApp(); + } + }, [confirmClose, openCloseModal, closeWebApp]); + + const handlePopupClose = useCallback((buttonId?: string) => { + setPopupParams(undefined); + sendEvent({ + eventType: 'popup_closed', + eventData: { + button_id: buttonId, + }, + }); + }, [sendEvent]); + // Notify view that height changed useOnChange(() => { setTimeout(() => { @@ -245,9 +288,9 @@ const WebAppModal: FC = ({ eventType: 'back_button_pressed', }); } else { - closeWebApp(); + handleClose(); } - }, [closeWebApp, isBackButtonVisible, sendEvent]); + }, [handleClose, isBackButtonVisible, sendEvent]); const openBotChat = useCallback(() => { openChat({ @@ -256,6 +299,14 @@ const WebAppModal: FC = ({ closeWebApp(); }, [bot, closeWebApp, openChat]); + useEffect(() => { + if (!isOpen) { + setConfirmClose(false); + closeCloseModal(); + setPopupParams(undefined); + } + }, [closeCloseModal, isOpen]); + const MoreMenuButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => { return ({ onTrigger, isOpen: isMenuOpen }) => ( )} + {confirmClose && ( + + )} + {renderingPopupParams && ( + + {renderingPopupParams.message} +
+ {renderingPopupParams.buttons.map((button) => ( + + ))} +
+
+ )} ); }; diff --git a/src/components/main/hooks/useWebAppFrame.ts b/src/components/main/hooks/useWebAppFrame.ts index 0a21f711f..c7ebea9d8 100644 --- a/src/components/main/hooks/useWebAppFrame.ts +++ b/src/components/main/hooks/useWebAppFrame.ts @@ -2,6 +2,16 @@ import useWindowSize from '../../../hooks/useWindowSize'; import { useCallback, useEffect, useRef } from '../../../lib/teact/teact'; import { extractCurrentThemeParams } from '../../../util/themeStyle'; +export type PopupOptions = { + title: string; + message: string; + buttons: { + id: string; + type: 'default' | 'ok' | 'close' | 'cancel' | 'destructive'; + text: string; + }[]; +}; + export type WebAppInboundEvent = { eventType: 'web_app_data_send'; eventData: { @@ -54,9 +64,17 @@ export type WebAppInboundEvent = { eventData: { color_key: 'bg_color' | 'secondary_bg_color'; }; +} | { + eventType: 'web_app_open_popup'; + eventData: PopupOptions; +} | { + eventType: 'web_app_setup_closing_behavior'; + eventData: { + need_confirmation: boolean; + }; } | { eventType: 'web_app_request_viewport' | 'web_app_request_theme' | 'web_app_ready' | 'web_app_expand' - | 'web_app_close' | 'iframe_ready'; + | 'web_app_request_phone' | 'web_app_close' | 'iframe_ready'; eventData: null; }; @@ -89,6 +107,16 @@ type WebAppOutboundEvent = { slug: string; status: 'paid' | 'cancelled' | 'pending' | 'failed'; }; +} | { + eventType: 'phone_requested'; + eventData: { + phone_number: string; + }; +} | { + eventType: 'popup_closed'; + eventData: { + button_id?: string; + }; } | { eventType: 'main_button_pressed' | 'back_button_pressed' | 'settings_button_pressed'; }; diff --git a/src/components/main/premium/PremiumFeatureItem.module.scss b/src/components/main/premium/PremiumFeatureItem.module.scss index 8eb5b1a88..4ab359ab5 100644 --- a/src/components/main/premium/PremiumFeatureItem.module.scss +++ b/src/components/main/premium/PremiumFeatureItem.module.scss @@ -23,4 +23,8 @@ .icon { min-width: 2rem; + height: 2rem; + align-self: center; + border-radius: 0.625rem; + background: var(--item-color, #000); } diff --git a/src/components/main/premium/PremiumFeatureItem.tsx b/src/components/main/premium/PremiumFeatureItem.tsx index 8ee76707a..1e8f611b5 100644 --- a/src/components/main/premium/PremiumFeatureItem.tsx +++ b/src/components/main/premium/PremiumFeatureItem.tsx @@ -12,17 +12,24 @@ type OwnProps = { title: string; text: string; onClick: VoidFunction; + index: number; }; +const COLORS = [ + '#F2862D', '#EB7B4D', '#E46D72', '#DD6091', '#CC5FBA', '#B464E7', + '#9873FF', '#768DFF', '#55A5FC', '#52B0C9', '#4FBC93', '#4CC663', +]; + const PremiumFeatureItem: FC = ({ icon, title, text, + index, onClick, }) => { return ( - +
{renderText(title, ['br'])}
{text}
diff --git a/src/components/main/premium/PremiumFeatureModal.tsx b/src/components/main/premium/PremiumFeatureModal.tsx index dd8a55388..2f8d279ed 100644 --- a/src/components/main/premium/PremiumFeatureModal.tsx +++ b/src/components/main/premium/PremiumFeatureModal.tsx @@ -24,9 +24,10 @@ import PremiumFeaturePreviewStickers from './previews/PremiumFeaturePreviewStick import styles from './PremiumFeatureModal.module.scss'; export const PREMIUM_FEATURE_TITLES: Record = { - limits: 'PremiumPreviewLimits', - reactions: 'PremiumPreviewReactions', - stickers: 'PremiumPreviewStickers', + double_limits: 'PremiumPreviewLimits', + unique_reactions: 'PremiumPreviewReactions', + premium_stickers: 'PremiumPreviewStickers', + animated_emoji: 'PremiumPreviewEmoji', no_ads: 'PremiumPreviewNoAds', voice_to_text: 'PremiumPreviewVoiceToText', profile_badge: 'PremiumPreviewProfileBadge', @@ -37,10 +38,11 @@ export const PREMIUM_FEATURE_TITLES: Record = { }; export const PREMIUM_FEATURE_DESCRIPTIONS: Record = { - limits: 'PremiumPreviewLimitsDescription', - reactions: 'PremiumPreviewReactionsDescription', - stickers: 'PremiumPreviewStickersDescription', + double_limits: 'PremiumPreviewLimitsDescription', + unique_reactions: 'PremiumPreviewReactionsDescription', + premium_stickers: 'PremiumPreviewStickersDescription', no_ads: 'PremiumPreviewNoAdsDescription', + animated_emoji: 'PremiumPreviewEmojiDescription', voice_to_text: 'PremiumPreviewVoiceToTextDescription', profile_badge: 'PremiumPreviewProfileBadgeDescription', faster_download: 'PremiumPreviewDownloadSpeedDescription', @@ -50,13 +52,14 @@ export const PREMIUM_FEATURE_DESCRIPTIONS: Record = { }; export const PREMIUM_FEATURE_SECTIONS = [ - 'limits', + 'double_limits', 'more_upload', 'faster_download', 'voice_to_text', 'no_ads', - 'reactions', - 'stickers', + 'unique_reactions', + 'premium_stickers', + 'animated_emoji', 'advanced_chat_management', 'profile_badge', 'animated_userpics', @@ -212,11 +215,11 @@ const PremiumFeatureModal: FC = ({
{PREMIUM_FEATURE_SECTIONS.map((section, index) => { - if (section === 'limits') { + if (section === 'double_limits') { return (

- {lang(PREMIUM_FEATURE_TITLES.limits)} + {lang(PREMIUM_FEATURE_TITLES.double_limits)}

{LIMITS_ORDER.map((limit, i) => { @@ -236,33 +239,33 @@ const PremiumFeatureModal: FC = ({
); } - if (section === 'reactions') { + if (section === 'unique_reactions') { return (

- {lang(PREMIUM_FEATURE_TITLES.reactions)} + {lang(PREMIUM_FEATURE_TITLES.unique_reactions)}

- {renderText(lang(PREMIUM_FEATURE_DESCRIPTIONS.reactions), ['br'])} + {renderText(lang(PREMIUM_FEATURE_DESCRIPTIONS.unique_reactions), ['br'])}
); } - if (section === 'stickers') { + if (section === 'premium_stickers') { return (

- {lang(PREMIUM_FEATURE_TITLES.stickers)} + {lang(PREMIUM_FEATURE_TITLES.premium_stickers)}

- {renderText(lang(PREMIUM_FEATURE_DESCRIPTIONS.stickers), ['br'])} + {renderText(lang(PREMIUM_FEATURE_DESCRIPTIONS.premium_stickers), ['br'])}
); diff --git a/src/components/main/premium/PremiumMainModal.tsx b/src/components/main/premium/PremiumMainModal.tsx index 8b50fc625..ddbed16f2 100644 --- a/src/components/main/premium/PremiumMainModal.tsx +++ b/src/components/main/premium/PremiumMainModal.tsx @@ -40,15 +40,17 @@ import PremiumStickers from '../../../assets/premium/PremiumStickers.svg'; import PremiumChats from '../../../assets/premium/PremiumChats.svg'; import PremiumBadge from '../../../assets/premium/PremiumBadge.svg'; import PremiumVideo from '../../../assets/premium/PremiumVideo.svg'; +import PremiumEmoji from '../../../assets/premium/PremiumEmoji.svg'; import styles from './PremiumMainModal.module.scss'; const LIMIT_ACCOUNTS = 4; const PREMIUM_FEATURE_COLOR_ICONS: Record = { - limits: PremiumLimits, - reactions: PremiumReactions, - stickers: PremiumStickers, + double_limits: PremiumLimits, + unique_reactions: PremiumReactions, + premium_stickers: PremiumStickers, + animated_emoji: PremiumEmoji, no_ads: PremiumAds, voice_to_text: PremiumVoice, profile_badge: PremiumBadge, @@ -76,6 +78,7 @@ type StateProps = { limits?: NonNullable['limits']; premiumSlug?: string; premiumBotUsername?: string; + premiumPromoOrder?: string[]; }; const PremiumMainModal: FC = ({ @@ -93,6 +96,7 @@ const PremiumMainModal: FC = ({ premiumBotUsername, isClosing, isSuccess, + premiumPromoOrder, }) => { // eslint-disable-next-line no-null/no-null const dialogRef = useRef(null); @@ -212,18 +216,22 @@ const PremiumMainModal: FC = ({
- {PREMIUM_FEATURE_SECTIONS.map((section) => ( - - ))} + {(premiumPromoOrder || PREMIUM_FEATURE_SECTIONS).map((section, index) => { + if (!PREMIUM_FEATURE_SECTIONS.includes(section)) return undefined; + return ( + + ); + })}

{renderText(lang('AboutPremiumDescription'), ['simple_markdown'])} @@ -285,5 +293,6 @@ export default memo(withGlobal((global): StateProps => { limits: global.appConfig?.limits, premiumSlug: global.appConfig?.premiumInvoiceSlug, premiumBotUsername: global.appConfig?.premiumBotUsername, + premiumPromoOrder: global.appConfig?.premiumPromoOrder, }; })(PremiumMainModal)); diff --git a/src/components/middle/message/Message.scss b/src/components/middle/message/Message.scss index 2ceb5b885..068e60b0d 100644 --- a/src/components/middle/message/Message.scss +++ b/src/components/middle/message/Message.scss @@ -70,6 +70,16 @@ } } + & > .chat-avatar-premium { + position: absolute; + bottom: 0.1875rem; + left: 1.25rem; + height: 0.75rem; + z-index: 1; + + --color-fill: white; + } + .quick-reaction { cursor: pointer; position: absolute; diff --git a/src/components/middle/message/Message.tsx b/src/components/middle/message/Message.tsx index 69d86447d..0b4ac3b7f 100644 --- a/src/components/middle/message/Message.tsx +++ b/src/components/middle/message/Message.tsx @@ -116,6 +116,7 @@ import CommentButton from './CommentButton'; import Reactions from './Reactions'; import ReactionStaticEmoji from '../../common/ReactionStaticEmoji'; import MessagePhoneCall from './MessagePhoneCall'; +import PremiumIcon from '../../common/PremiumIcon'; import DotAnimation from '../../common/DotAnimation'; import './Message.scss'; @@ -598,17 +599,21 @@ const Message: FC = ({ const avatarUser = (avatarPeer && isAvatarPeerUser) ? avatarPeer as ApiUser : undefined; const avatarChat = (avatarPeer && !isAvatarPeerUser) ? avatarPeer as ApiChat : undefined; const hiddenName = (!avatarPeer && forwardInfo) ? forwardInfo.hiddenUserName : undefined; + const isAvatarPremium = avatarUser?.isPremium; return ( - + <> + + {isAvatarPremium && } + ); } diff --git a/src/components/middle/message/ReactionSelector.tsx b/src/components/middle/message/ReactionSelector.tsx index 477c202f9..ac977c0ed 100644 --- a/src/components/middle/message/ReactionSelector.tsx +++ b/src/components/middle/message/ReactionSelector.tsx @@ -88,7 +88,7 @@ const ReactionSelector: FC = ({ className={cn('blocked-button')} // eslint-disable-next-line react/jsx-no-bind onClick={() => openPremiumModal({ - initialSection: 'reactions', + initialSection: 'unique_reactions', })} > diff --git a/src/config.ts b/src/config.ts index a097edc93..d265915c9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -40,7 +40,7 @@ export const MEDIA_PROGRESSIVE_CACHE_DISABLED = false; export const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive'; export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg'; -export const LANG_CACHE_NAME = 'tt-lang-packs-v12'; +export const LANG_CACHE_NAME = 'tt-lang-packs-v13'; export const ASSET_CACHE_NAME = 'tt-assets'; export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500]; diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index 5e557c136..d14b57a4c 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -614,7 +614,7 @@ addActionHandler('openTelegramLink', (global, actions, payload) => { return; } - if (part1 === 'addstickers') { + if (part1 === 'addstickers' || part1 === 'addemoji') { actions.openStickerSetShortName({ stickerSetShortName: part2, }); diff --git a/src/lib/gramjs/tl/AllTLObjects.js b/src/lib/gramjs/tl/AllTLObjects.js index fb41ddf65..9e0392453 100644 --- a/src/lib/gramjs/tl/AllTLObjects.js +++ b/src/lib/gramjs/tl/AllTLObjects.js @@ -1,6 +1,6 @@ const api = require('./api'); -const LAYER = 143; +const LAYER = 144; const tlobjects = {}; for (const tl of Object.values(api)) { diff --git a/src/lib/gramjs/tl/api.d.ts b/src/lib/gramjs/tl/api.d.ts index d3159b415..f2a9800e3 100644 --- a/src/lib/gramjs/tl/api.d.ts +++ b/src/lib/gramjs/tl/api.d.ts @@ -70,7 +70,7 @@ namespace Api { export type TypeChatPhoto = ChatPhotoEmpty | ChatPhoto; export type TypeMessage = MessageEmpty | Message | MessageService; export type TypeMessageMedia = MessageMediaEmpty | MessageMediaPhoto | MessageMediaGeo | MessageMediaContact | MessageMediaUnsupported | MessageMediaDocument | MessageMediaWebPage | MessageMediaVenue | MessageMediaGame | MessageMediaInvoice | MessageMediaGeoLive | MessageMediaPoll | MessageMediaDice; - export type TypeMessageAction = MessageActionEmpty | MessageActionChatCreate | MessageActionChatEditTitle | MessageActionChatEditPhoto | MessageActionChatDeletePhoto | MessageActionChatAddUser | MessageActionChatDeleteUser | MessageActionChatJoinedByLink | MessageActionChannelCreate | MessageActionChatMigrateTo | MessageActionChannelMigrateFrom | MessageActionPinMessage | MessageActionHistoryClear | MessageActionGameScore | MessageActionPaymentSentMe | MessageActionPaymentSent | MessageActionPhoneCall | MessageActionScreenshotTaken | MessageActionCustomAction | MessageActionBotAllowed | MessageActionSecureValuesSentMe | MessageActionSecureValuesSent | MessageActionContactSignUp | MessageActionGeoProximityReached | MessageActionGroupCall | MessageActionInviteToGroupCall | MessageActionSetMessagesTTL | MessageActionGroupCallScheduled | MessageActionSetChatTheme | MessageActionChatJoinedByRequest | MessageActionWebViewDataSentMe | MessageActionWebViewDataSent; + export type TypeMessageAction = MessageActionEmpty | MessageActionChatCreate | MessageActionChatEditTitle | MessageActionChatEditPhoto | MessageActionChatDeletePhoto | MessageActionChatAddUser | MessageActionChatDeleteUser | MessageActionChatJoinedByLink | MessageActionChannelCreate | MessageActionChatMigrateTo | MessageActionChannelMigrateFrom | MessageActionPinMessage | MessageActionHistoryClear | MessageActionGameScore | MessageActionPaymentSentMe | MessageActionPaymentSent | MessageActionPhoneCall | MessageActionScreenshotTaken | MessageActionCustomAction | MessageActionBotAllowed | MessageActionSecureValuesSentMe | MessageActionSecureValuesSent | MessageActionContactSignUp | MessageActionGeoProximityReached | MessageActionGroupCall | MessageActionInviteToGroupCall | MessageActionSetMessagesTTL | MessageActionGroupCallScheduled | MessageActionSetChatTheme | MessageActionChatJoinedByRequest | MessageActionWebViewDataSentMe | MessageActionWebViewDataSent | MessageActionGiftPremium; export type TypeDialog = Dialog | DialogFolder; export type TypePhoto = PhotoEmpty | Photo; export type TypePhotoSize = PhotoSizeEmpty | PhotoSize | PhotoCachedSize | PhotoStrippedSize | PhotoSizeProgressive | PhotoPathSize; @@ -86,7 +86,7 @@ namespace Api { export type TypeImportedContact = ImportedContact; export type TypeContactStatus = ContactStatus; export type TypeMessagesFilter = InputMessagesFilterEmpty | InputMessagesFilterPhotos | InputMessagesFilterVideo | InputMessagesFilterPhotoVideo | InputMessagesFilterDocument | InputMessagesFilterUrl | InputMessagesFilterGif | InputMessagesFilterVoice | InputMessagesFilterMusic | InputMessagesFilterChatPhotos | InputMessagesFilterPhoneCalls | InputMessagesFilterRoundVoice | InputMessagesFilterRoundVideo | InputMessagesFilterMyMentions | InputMessagesFilterGeo | InputMessagesFilterContacts | InputMessagesFilterPinned; - export type TypeUpdate = UpdateNewMessage | UpdateMessageID | UpdateDeleteMessages | UpdateUserTyping | UpdateChatUserTyping | UpdateChatParticipants | UpdateUserStatus | UpdateUserName | UpdateUserPhoto | UpdateNewEncryptedMessage | UpdateEncryptedChatTyping | UpdateEncryption | UpdateEncryptedMessagesRead | UpdateChatParticipantAdd | UpdateChatParticipantDelete | UpdateDcOptions | UpdateNotifySettings | UpdateServiceNotification | UpdatePrivacy | UpdateUserPhone | UpdateReadHistoryInbox | UpdateReadHistoryOutbox | UpdateWebPage | UpdateReadMessagesContents | UpdateChannelTooLong | UpdateChannel | UpdateNewChannelMessage | UpdateReadChannelInbox | UpdateDeleteChannelMessages | UpdateChannelMessageViews | UpdateChatParticipantAdmin | UpdateNewStickerSet | UpdateStickerSetsOrder | UpdateStickerSets | UpdateSavedGifs | UpdateBotInlineQuery | UpdateBotInlineSend | UpdateEditChannelMessage | UpdateBotCallbackQuery | UpdateEditMessage | UpdateInlineBotCallbackQuery | UpdateReadChannelOutbox | UpdateDraftMessage | UpdateReadFeaturedStickers | UpdateRecentStickers | UpdateConfig | UpdatePtsChanged | UpdateChannelWebPage | UpdateDialogPinned | UpdatePinnedDialogs | UpdateBotWebhookJSON | UpdateBotWebhookJSONQuery | UpdateBotShippingQuery | UpdateBotPrecheckoutQuery | UpdatePhoneCall | UpdateLangPackTooLong | UpdateLangPack | UpdateFavedStickers | UpdateChannelReadMessagesContents | UpdateContactsReset | UpdateChannelAvailableMessages | UpdateDialogUnreadMark | UpdateMessagePoll | UpdateChatDefaultBannedRights | UpdateFolderPeers | UpdatePeerSettings | UpdatePeerLocated | UpdateNewScheduledMessage | UpdateDeleteScheduledMessages | UpdateTheme | UpdateGeoLiveViewed | UpdateLoginToken | UpdateMessagePollVote | UpdateDialogFilter | UpdateDialogFilterOrder | UpdateDialogFilters | UpdatePhoneCallSignalingData | UpdateChannelMessageForwards | UpdateReadChannelDiscussionInbox | UpdateReadChannelDiscussionOutbox | UpdatePeerBlocked | UpdateChannelUserTyping | UpdatePinnedMessages | UpdatePinnedChannelMessages | UpdateChat | UpdateGroupCallParticipants | UpdateGroupCall | UpdatePeerHistoryTTL | UpdateChatParticipant | UpdateChannelParticipant | UpdateBotStopped | UpdateGroupCallConnection | UpdateBotCommands | UpdatePendingJoinRequests | UpdateBotChatInviteRequester | UpdateMessageReactions | UpdateAttachMenuBots | UpdateWebViewResultSent | UpdateBotMenuButton | UpdateSavedRingtones | UpdateTranscribedAudio; + export type TypeUpdate = UpdateNewMessage | UpdateMessageID | UpdateDeleteMessages | UpdateUserTyping | UpdateChatUserTyping | UpdateChatParticipants | UpdateUserStatus | UpdateUserName | UpdateUserPhoto | UpdateNewEncryptedMessage | UpdateEncryptedChatTyping | UpdateEncryption | UpdateEncryptedMessagesRead | UpdateChatParticipantAdd | UpdateChatParticipantDelete | UpdateDcOptions | UpdateNotifySettings | UpdateServiceNotification | UpdatePrivacy | UpdateUserPhone | UpdateReadHistoryInbox | UpdateReadHistoryOutbox | UpdateWebPage | UpdateReadMessagesContents | UpdateChannelTooLong | UpdateChannel | UpdateNewChannelMessage | UpdateReadChannelInbox | UpdateDeleteChannelMessages | UpdateChannelMessageViews | UpdateChatParticipantAdmin | UpdateNewStickerSet | UpdateStickerSetsOrder | UpdateStickerSets | UpdateSavedGifs | UpdateBotInlineQuery | UpdateBotInlineSend | UpdateEditChannelMessage | UpdateBotCallbackQuery | UpdateEditMessage | UpdateInlineBotCallbackQuery | UpdateReadChannelOutbox | UpdateDraftMessage | UpdateReadFeaturedStickers | UpdateRecentStickers | UpdateConfig | UpdatePtsChanged | UpdateChannelWebPage | UpdateDialogPinned | UpdatePinnedDialogs | UpdateBotWebhookJSON | UpdateBotWebhookJSONQuery | UpdateBotShippingQuery | UpdateBotPrecheckoutQuery | UpdatePhoneCall | UpdateLangPackTooLong | UpdateLangPack | UpdateFavedStickers | UpdateChannelReadMessagesContents | UpdateContactsReset | UpdateChannelAvailableMessages | UpdateDialogUnreadMark | UpdateMessagePoll | UpdateChatDefaultBannedRights | UpdateFolderPeers | UpdatePeerSettings | UpdatePeerLocated | UpdateNewScheduledMessage | UpdateDeleteScheduledMessages | UpdateTheme | UpdateGeoLiveViewed | UpdateLoginToken | UpdateMessagePollVote | UpdateDialogFilter | UpdateDialogFilterOrder | UpdateDialogFilters | UpdatePhoneCallSignalingData | UpdateChannelMessageForwards | UpdateReadChannelDiscussionInbox | UpdateReadChannelDiscussionOutbox | UpdatePeerBlocked | UpdateChannelUserTyping | UpdatePinnedMessages | UpdatePinnedChannelMessages | UpdateChat | UpdateGroupCallParticipants | UpdateGroupCall | UpdatePeerHistoryTTL | UpdateChatParticipant | UpdateChannelParticipant | UpdateBotStopped | UpdateGroupCallConnection | UpdateBotCommands | UpdatePendingJoinRequests | UpdateBotChatInviteRequester | UpdateMessageReactions | UpdateAttachMenuBots | UpdateWebViewResultSent | UpdateBotMenuButton | UpdateSavedRingtones | UpdateTranscribedAudio | UpdateReadFeaturedEmojiStickers; export type TypeUpdates = UpdatesTooLong | UpdateShortMessage | UpdateShortChatMessage | UpdateShort | UpdatesCombined | Updates | UpdateShortSentMessage; export type TypeDcOption = DcOption; export type TypeConfig = Config; @@ -100,26 +100,26 @@ namespace Api { export type TypeDocument = DocumentEmpty | Document; export type TypeNotifyPeer = NotifyPeer | NotifyUsers | NotifyChats | NotifyBroadcasts; export type TypeSendMessageAction = SendMessageTypingAction | SendMessageCancelAction | SendMessageRecordVideoAction | SendMessageUploadVideoAction | SendMessageRecordAudioAction | SendMessageUploadAudioAction | SendMessageUploadPhotoAction | SendMessageUploadDocumentAction | SendMessageGeoLocationAction | SendMessageChooseContactAction | SendMessageGamePlayAction | SendMessageRecordRoundAction | SendMessageUploadRoundAction | SpeakingInGroupCallAction | SendMessageHistoryImportAction | SendMessageChooseStickerAction | SendMessageEmojiInteraction | SendMessageEmojiInteractionSeen; - export type TypeInputPrivacyKey = InputPrivacyKeyStatusTimestamp | InputPrivacyKeyChatInvite | InputPrivacyKeyPhoneCall | InputPrivacyKeyPhoneP2P | InputPrivacyKeyForwards | InputPrivacyKeyProfilePhoto | InputPrivacyKeyPhoneNumber | InputPrivacyKeyAddedByPhone; - export type TypePrivacyKey = PrivacyKeyStatusTimestamp | PrivacyKeyChatInvite | PrivacyKeyPhoneCall | PrivacyKeyPhoneP2P | PrivacyKeyForwards | PrivacyKeyProfilePhoto | PrivacyKeyPhoneNumber | PrivacyKeyAddedByPhone; + export type TypeInputPrivacyKey = InputPrivacyKeyStatusTimestamp | InputPrivacyKeyChatInvite | InputPrivacyKeyPhoneCall | InputPrivacyKeyPhoneP2P | InputPrivacyKeyForwards | InputPrivacyKeyProfilePhoto | InputPrivacyKeyPhoneNumber | InputPrivacyKeyAddedByPhone | InputPrivacyKeyVoiceMessages; + export type TypePrivacyKey = PrivacyKeyStatusTimestamp | PrivacyKeyChatInvite | PrivacyKeyPhoneCall | PrivacyKeyPhoneP2P | PrivacyKeyForwards | PrivacyKeyProfilePhoto | PrivacyKeyPhoneNumber | PrivacyKeyAddedByPhone | PrivacyKeyVoiceMessages; export type TypeInputPrivacyRule = InputPrivacyValueAllowContacts | InputPrivacyValueAllowAll | InputPrivacyValueAllowUsers | InputPrivacyValueDisallowContacts | InputPrivacyValueDisallowAll | InputPrivacyValueDisallowUsers | InputPrivacyValueAllowChatParticipants | InputPrivacyValueDisallowChatParticipants; export type TypePrivacyRule = PrivacyValueAllowContacts | PrivacyValueAllowAll | PrivacyValueAllowUsers | PrivacyValueDisallowContacts | PrivacyValueDisallowAll | PrivacyValueDisallowUsers | PrivacyValueAllowChatParticipants | PrivacyValueDisallowChatParticipants; export type TypeAccountDaysTTL = AccountDaysTTL; - export type TypeDocumentAttribute = DocumentAttributeImageSize | DocumentAttributeAnimated | DocumentAttributeSticker | DocumentAttributeVideo | DocumentAttributeAudio | DocumentAttributeFilename | DocumentAttributeHasStickers; + export type TypeDocumentAttribute = DocumentAttributeImageSize | DocumentAttributeAnimated | DocumentAttributeSticker | DocumentAttributeVideo | DocumentAttributeAudio | DocumentAttributeFilename | DocumentAttributeHasStickers | DocumentAttributeCustomEmoji; export type TypeStickerPack = StickerPack; export type TypeWebPage = WebPageEmpty | WebPagePending | WebPage | WebPageNotModified; export type TypeAuthorization = Authorization; export type TypeReceivedNotifyMessage = ReceivedNotifyMessage; export type TypeExportedChatInvite = ChatInviteExported | ChatInvitePublicJoinRequests; export type TypeChatInvite = ChatInviteAlready | ChatInvite | ChatInvitePeek; - export type TypeInputStickerSet = InputStickerSetEmpty | InputStickerSetID | InputStickerSetShortName | InputStickerSetAnimatedEmoji | InputStickerSetDice | InputStickerSetAnimatedEmojiAnimations; + export type TypeInputStickerSet = InputStickerSetEmpty | InputStickerSetID | InputStickerSetShortName | InputStickerSetAnimatedEmoji | InputStickerSetDice | InputStickerSetAnimatedEmojiAnimations | InputStickerSetPremiumGifts; export type TypeStickerSet = StickerSet; export type TypeBotCommand = BotCommand; export type TypeBotInfo = BotInfo; export type TypeKeyboardButton = KeyboardButton | KeyboardButtonUrl | KeyboardButtonCallback | KeyboardButtonRequestPhone | KeyboardButtonRequestGeoLocation | KeyboardButtonSwitchInline | KeyboardButtonGame | KeyboardButtonBuy | KeyboardButtonUrlAuth | InputKeyboardButtonUrlAuth | KeyboardButtonRequestPoll | InputKeyboardButtonUserProfile | KeyboardButtonUserProfile | KeyboardButtonWebView | KeyboardButtonSimpleWebView; export type TypeKeyboardButtonRow = KeyboardButtonRow; export type TypeReplyMarkup = ReplyKeyboardHide | ReplyKeyboardForceReply | ReplyKeyboardMarkup | ReplyInlineMarkup; - export type TypeMessageEntity = MessageEntityUnknown | MessageEntityMention | MessageEntityHashtag | MessageEntityBotCommand | MessageEntityUrl | MessageEntityEmail | MessageEntityBold | MessageEntityItalic | MessageEntityCode | MessageEntityPre | MessageEntityTextUrl | MessageEntityMentionName | InputMessageEntityMentionName | MessageEntityPhone | MessageEntityCashtag | MessageEntityUnderline | MessageEntityStrike | MessageEntityBlockquote | MessageEntityBankCard | MessageEntitySpoiler; + export type TypeMessageEntity = MessageEntityUnknown | MessageEntityMention | MessageEntityHashtag | MessageEntityBotCommand | MessageEntityUrl | MessageEntityEmail | MessageEntityBold | MessageEntityItalic | MessageEntityCode | MessageEntityPre | MessageEntityTextUrl | MessageEntityMentionName | InputMessageEntityMentionName | MessageEntityPhone | MessageEntityCashtag | MessageEntityUnderline | MessageEntityStrike | MessageEntityBlockquote | MessageEntityBankCard | MessageEntitySpoiler | MessageEntityCustomEmoji; export type TypeInputChannel = InputChannelEmpty | InputChannel | InputChannelFromMessage; export type TypeMessageRange = MessageRange; export type TypeChannelMessagesFilter = ChannelMessagesFilterEmpty | ChannelMessagesFilter; @@ -137,7 +137,7 @@ namespace Api { export type TypeTopPeerCategory = TopPeerCategoryBotsPM | TopPeerCategoryBotsInline | TopPeerCategoryCorrespondents | TopPeerCategoryGroups | TopPeerCategoryChannels | TopPeerCategoryPhoneCalls | TopPeerCategoryForwardUsers | TopPeerCategoryForwardChats; export type TypeTopPeerCategoryPeers = TopPeerCategoryPeers; export type TypeDraftMessage = DraftMessageEmpty | DraftMessage; - export type TypeStickerSetCovered = StickerSetCovered | StickerSetMultiCovered; + export type TypeStickerSetCovered = StickerSetCovered | StickerSetMultiCovered | StickerSetFullCovered; export type TypeMaskCoords = MaskCoords; export type TypeInputStickeredMedia = InputStickeredMediaPhoto | InputStickeredMediaDocument; export type TypeGame = Game; @@ -155,7 +155,7 @@ namespace Api { export type TypePaymentSavedCredentials = PaymentSavedCredentialsCard; export type TypeWebDocument = WebDocument | WebDocumentNoProxy; export type TypeInputWebDocument = InputWebDocument; - export type TypeInputWebFileLocation = InputWebFileLocation | InputWebFileGeoPointLocation; + export type TypeInputWebFileLocation = InputWebFileLocation | InputWebFileGeoPointLocation | InputWebFileAudioAlbumThumbLocation; export type TypeInputPaymentCredentials = InputPaymentCredentialsSaved | InputPaymentCredentials | InputPaymentCredentialsApplePay | InputPaymentCredentialsGooglePay; export type TypeShippingOption = ShippingOption; export type TypeInputStickerSetItem = InputStickerSetItem; @@ -282,6 +282,9 @@ namespace Api { export type TypeNotificationSound = NotificationSoundDefault | NotificationSoundNone | NotificationSoundLocal | NotificationSoundRingtone; export type TypeAttachMenuPeerType = AttachMenuPeerTypeSameBotPM | AttachMenuPeerTypeBotPM | AttachMenuPeerTypePM | AttachMenuPeerTypeChat | AttachMenuPeerTypeBroadcast; export type TypeInputInvoice = InputInvoiceMessage | InputInvoiceSlug; + export type TypeInputStorePaymentPurpose = InputStorePaymentPremiumSubscription | InputStorePaymentGiftPremium; + export type TypePremiumGiftOption = PremiumGiftOption; + export type TypePaymentFormMethod = PaymentFormMethod; export type TypeResPQ = ResPQ; export type TypeP_Q_inner_data = PQInnerData | PQInnerDataDc | PQInnerDataTemp | PQInnerDataTempDc; export type TypeServer_DH_Params = ServerDHParamsFail | ServerDHParamsOk; @@ -1703,6 +1706,15 @@ namespace Api { }> { text: string; }; + export class MessageActionGiftPremium extends VirtualClass<{ + currency: string; + amount: long; + months: int; + }> { + currency: string; + amount: long; + months: int; + }; export class Dialog extends VirtualClass<{ // flags: undefined; pinned?: true; @@ -1968,6 +1980,7 @@ namespace Api { canPinMessage?: true; hasScheduled?: true; videoCallsAvailable?: true; + voiceMessagesForbidden?: true; id: long; about?: string; settings: Api.TypePeerSettings; @@ -1982,6 +1995,7 @@ namespace Api { privateForwardName?: string; botGroupAdminRights?: Api.TypeChatAdminRights; botBroadcastAdminRights?: Api.TypeChatAdminRights; + premiumGifts?: Api.TypePremiumGiftOption[]; }> { // flags: undefined; blocked?: true; @@ -1990,6 +2004,7 @@ namespace Api { canPinMessage?: true; hasScheduled?: true; videoCallsAvailable?: true; + voiceMessagesForbidden?: true; id: long; about?: string; settings: Api.TypePeerSettings; @@ -2004,6 +2019,7 @@ namespace Api { privateForwardName?: string; botGroupAdminRights?: Api.TypeChatAdminRights; botBroadcastAdminRights?: Api.TypeChatAdminRights; + premiumGifts?: Api.TypePremiumGiftOption[]; }; export class Contact extends VirtualClass<{ userId: long; @@ -2340,10 +2356,12 @@ namespace Api { export class UpdateStickerSetsOrder extends VirtualClass<{ // flags: undefined; masks?: true; + emojis?: true; order: long[]; }> { // flags: undefined; masks?: true; + emojis?: true; order: long[]; }; export class UpdateStickerSets extends VirtualClass {}; @@ -2912,6 +2930,7 @@ namespace Api { transcriptionId: long; text: string; }; + export class UpdateReadFeaturedEmojiStickers extends VirtualClass {}; export class UpdatesTooLong extends VirtualClass {}; export class UpdateShortMessage extends VirtualClass<{ // flags: undefined; @@ -3430,6 +3449,7 @@ namespace Api { export class InputPrivacyKeyProfilePhoto extends VirtualClass {}; export class InputPrivacyKeyPhoneNumber extends VirtualClass {}; export class InputPrivacyKeyAddedByPhone extends VirtualClass {}; + export class InputPrivacyKeyVoiceMessages extends VirtualClass {}; export class PrivacyKeyStatusTimestamp extends VirtualClass {}; export class PrivacyKeyChatInvite extends VirtualClass {}; export class PrivacyKeyPhoneCall extends VirtualClass {}; @@ -3438,6 +3458,7 @@ namespace Api { export class PrivacyKeyProfilePhoto extends VirtualClass {}; export class PrivacyKeyPhoneNumber extends VirtualClass {}; export class PrivacyKeyAddedByPhone extends VirtualClass {}; + export class PrivacyKeyVoiceMessages extends VirtualClass {}; export class InputPrivacyValueAllowContacts extends VirtualClass {}; export class InputPrivacyValueAllowAll extends VirtualClass {}; export class InputPrivacyValueAllowUsers extends VirtualClass<{ @@ -3548,6 +3569,17 @@ namespace Api { fileName: string; }; export class DocumentAttributeHasStickers extends VirtualClass {}; + export class DocumentAttributeCustomEmoji extends VirtualClass<{ + // flags: undefined; + free?: true; + alt: string; + stickerset: Api.TypeInputStickerSet; + }> { + // flags: undefined; + free?: true; + alt: string; + stickerset: Api.TypeInputStickerSet; + }; export class StickerPack extends VirtualClass<{ emoticon: string; documents: long[]; @@ -3748,6 +3780,7 @@ namespace Api { emoticon: string; }; export class InputStickerSetAnimatedEmojiAnimations extends VirtualClass {}; + export class InputStickerSetPremiumGifts extends VirtualClass {}; export class StickerSet extends VirtualClass<{ // flags: undefined; archived?: true; @@ -3755,6 +3788,7 @@ namespace Api { masks?: true; animated?: true; videos?: true; + emojis?: true; installedDate?: int; id: long; accessHash: long; @@ -3763,6 +3797,7 @@ namespace Api { thumbs?: Api.TypePhotoSize[]; thumbDcId?: int; thumbVersion?: int; + thumbDocumentId?: long; count: int; hash: int; }> { @@ -3772,6 +3807,7 @@ namespace Api { masks?: true; animated?: true; videos?: true; + emojis?: true; installedDate?: int; id: long; accessHash: long; @@ -3780,6 +3816,7 @@ namespace Api { thumbs?: Api.TypePhotoSize[]; thumbDcId?: int; thumbVersion?: int; + thumbDocumentId?: long; count: int; hash: int; }; @@ -4117,6 +4154,15 @@ namespace Api { offset: int; length: int; }; + export class MessageEntityCustomEmoji extends VirtualClass<{ + offset: int; + length: int; + documentId: long; + }> { + offset: int; + length: int; + documentId: long; + }; export class InputChannelEmpty extends VirtualClass {}; export class InputChannel extends VirtualClass<{ channelId: long; @@ -4665,6 +4711,15 @@ namespace Api { set: Api.TypeStickerSet; covers: Api.TypeDocument[]; }; + export class StickerSetFullCovered extends VirtualClass<{ + set: Api.TypeStickerSet; + packs: Api.TypeStickerPack[]; + documents: Api.TypeDocument[]; + }> { + set: Api.TypeStickerSet; + packs: Api.TypeStickerPack[]; + documents: Api.TypeDocument[]; + }; export class MaskCoords extends VirtualClass<{ n: int; x: double; @@ -5185,6 +5240,17 @@ namespace Api { zoom: int; scale: int; }; + export class InputWebFileAudioAlbumThumbLocation extends VirtualClass<{ + // flags: undefined; + document?: Api.TypeInputDocument; + title?: string; + performer?: string; + } | void> { + // flags: undefined; + document?: Api.TypeInputDocument; + title?: string; + performer?: string; + }; export class InputPaymentCredentialsSaved extends VirtualClass<{ id: string; tmpPassword: bytes; @@ -7316,6 +7382,44 @@ namespace Api { }> { slug: string; }; + export class InputStorePaymentPremiumSubscription extends VirtualClass<{ + // flags: undefined; + restore?: true; + } | void> { + // flags: undefined; + restore?: true; + }; + export class InputStorePaymentGiftPremium extends VirtualClass<{ + userId: Api.TypeInputUser; + currency: string; + amount: long; + }> { + userId: Api.TypeInputUser; + currency: string; + amount: long; + }; + export class PremiumGiftOption extends VirtualClass<{ + // flags: undefined; + months: int; + currency: string; + amount: long; + botUrl: string; + storeProduct?: string; + }> { + // flags: undefined; + months: int; + currency: string; + amount: long; + botUrl: string; + storeProduct?: string; + }; + export class PaymentFormMethod extends VirtualClass<{ + url: string; + title: string; + }> { + url: string; + title: string; + }; export class ResPQ extends VirtualClass<{ nonce: int128; serverNonce: int128; @@ -8993,8 +9097,9 @@ namespace Api { url: string; nativeProvider?: string; nativeParams?: Api.TypeDataJSON; + additionalMethods?: Api.TypePaymentFormMethod[]; savedInfo?: Api.TypePaymentRequestedInfo; - savedCredentials?: Api.TypePaymentSavedCredentials; + savedCredentials?: Api.TypePaymentSavedCredentials[]; users: Api.TypeUser[]; }> { // flags: undefined; @@ -9010,8 +9115,9 @@ namespace Api { url: string; nativeProvider?: string; nativeParams?: Api.TypeDataJSON; + additionalMethods?: Api.TypePaymentFormMethod[]; savedInfo?: Api.TypePaymentRequestedInfo; - savedCredentials?: Api.TypePaymentSavedCredentials; + savedCredentials?: Api.TypePaymentSavedCredentials[]; users: Api.TypeUser[]; }; export class ValidatedRequestedInfo extends VirtualClass<{ @@ -9606,9 +9712,13 @@ namespace Api { rules: Api.TypeInputPrivacyRule[]; }; export class DeleteAccount extends Request, Bool> { + // flags: undefined; reason: string; + password?: Api.TypeInputCheckPasswordSRP; }; export class GetAccountTTL extends Request {}; export class SetAccountTTL extends Request, Bool> { // flags: undefined; masks?: true; + emojis?: true; order: long[]; }; export class GetDocumentByHash extends Request, messages.TypeArchivedStickers> { // flags: undefined; masks?: true; + emojis?: true; offsetId: long; limit: int; }; @@ -11792,6 +11906,21 @@ namespace Api { transcriptionId: long; good: Bool; }; + export class GetCustomEmojiDocuments extends Request, Api.TypeDocument[]> { + documentId: long[]; + }; + export class GetEmojiStickers extends Request, messages.TypeAllStickers> { + hash: long; + }; + export class GetFeaturedEmojiStickers extends Request, messages.TypeFeaturedStickers> { + hash: long; + }; } export namespace updates { @@ -12468,27 +12597,24 @@ namespace Api { invoiceMedia: Api.TypeInputMedia; }; export class AssignAppStoreTransaction extends Request, Api.TypeUpdates> { - // flags: undefined; - restore?: true; - transactionId: string; receipt: bytes; + purpose: Api.TypeInputStorePaymentPurpose; }; export class AssignPlayMarketTransaction extends Request, Api.TypeUpdates> { - purchaseToken: string; + receipt: Api.TypeDataJSON; + purpose: Api.TypeInputStorePaymentPurpose; }; - export class RestorePlayMarketReceipt extends Request, Api.TypeUpdates> { - receipt: bytes; + export class CanPurchasePremium extends Request, Bool> { + purpose: Api.TypeInputStorePaymentPurpose; }; - export class CanPurchasePremium extends Request {}; export class RequestRecurringPayment extends Request = UserFull; contact#145ade0b user_id:long mutual:Bool = Contact; importedContact#c13e3c50 user_id:long client_id:long = ImportedContact; contactStatus#16d9703b user_id:long status:UserStatus = ContactStatus; @@ -239,7 +240,7 @@ updateDeleteChannelMessages#c32d5b12 channel_id:long messages:Vector pts:in updateChannelMessageViews#f226ac08 channel_id:long id:int views:int = Update; updateChatParticipantAdmin#d7ca61a2 chat_id:long user_id:long is_admin:Bool version:int = Update; updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update; -updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true order:Vector = Update; +updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true emojis:flags.1?true order:Vector = Update; updateStickerSets#43ae3dec = Update; updateSavedGifs#9375341e = Update; updateBotInlineQuery#496f379c flags:# query_id:long user_id:long query:string geo:flags.0?GeoPoint peer_type:flags.1?InlineQueryPeerType offset:string = Update; @@ -308,6 +309,7 @@ updateWebViewResultSent#1592b79d query_id:long = Update; updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update; updateSavedRingtones#74d8be99 = Update; updateTranscribedAudio#84cd5a flags:# pending:flags.0?true peer:Peer msg_id:int transcription_id:long text:string = Update; +updateReadFeaturedEmojiStickers#fb4c496c = 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 new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector state:updates.State = updates.Difference; @@ -385,6 +387,7 @@ inputPrivacyKeyForwards#a4dd4c08 = InputPrivacyKey; inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey; inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey; inputPrivacyKeyAddedByPhone#d1219bdd = InputPrivacyKey; +inputPrivacyKeyVoiceMessages#aee69d68 = InputPrivacyKey; privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey; privacyKeyChatInvite#500e6dfa = PrivacyKey; privacyKeyPhoneCall#3d662b7b = PrivacyKey; @@ -393,6 +396,7 @@ privacyKeyForwards#69ec56a3 = PrivacyKey; privacyKeyProfilePhoto#96151fed = PrivacyKey; privacyKeyPhoneNumber#d19ae46d = PrivacyKey; privacyKeyAddedByPhone#42ffd42b = PrivacyKey; +privacyKeyVoiceMessages#697f414 = PrivacyKey; inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule; inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule; inputPrivacyValueAllowUsers#131cc67f users:Vector = InputPrivacyRule; @@ -418,6 +422,7 @@ documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_strea documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute; documentAttributeFilename#15590068 file_name:string = DocumentAttribute; documentAttributeHasStickers#9801d2f7 = DocumentAttribute; +documentAttributeCustomEmoji#fd149899 flags:# free:flags.0?true alt:string stickerset:InputStickerSet = DocumentAttribute; messages.stickersNotModified#f1749a22 = messages.Stickers; messages.stickers#30a6ec7e hash:long stickers:Vector = messages.Stickers; stickerPack#12b299d4 emoticon:string documents:Vector = StickerPack; @@ -446,7 +451,8 @@ inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet; inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet; inputStickerSetDice#e67f520e emoticon:string = InputStickerSet; inputStickerSetAnimatedEmojiAnimations#cde3739 = InputStickerSet; -stickerSet#d7df217a flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector thumb_dc_id:flags.4?int thumb_version:flags.4?int count:int hash:int = StickerSet; +inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet; +stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet; messages.stickerSet#b60a24a6 set:StickerSet packs:Vector documents:Vector = messages.StickerSet; messages.stickerSetNotModified#d3f924eb = messages.StickerSet; botCommand#c27ac8c7 command:string description:string = BotCommand; @@ -491,6 +497,7 @@ messageEntityStrike#bf0693d4 offset:int length:int = MessageEntity; messageEntityBlockquote#20df5d0 offset:int length:int = MessageEntity; messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity; messageEntitySpoiler#32ca960f offset:int length:int = MessageEntity; +messageEntityCustomEmoji#c8cf05f8 offset:int length:int document_id:long = MessageEntity; inputChannelEmpty#ee8c1e86 = InputChannel; inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel; inputChannelFromMessage#5b934f9d peer:InputPeer msg_id:int channel_id:long = InputChannel; @@ -582,6 +589,7 @@ messages.stickerSetInstallResultSuccess#38641628 = messages.StickerSetInstallRes messages.stickerSetInstallResultArchive#35e410a8 sets:Vector = messages.StickerSetInstallResult; stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered; stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector = StickerSetCovered; +stickerSetFullCovered#1aed5ee5 set:StickerSet packs:Vector documents:Vector = StickerSetCovered; maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords; inputStickeredMediaPhoto#4a992157 id:InputPhoto = InputStickeredMedia; inputStickeredMediaDocument#438865b id:InputDocument = InputStickeredMedia; @@ -651,8 +659,9 @@ webDocumentNoProxy#f9c8bcc6 url:string size:int mime_type:string attributes:Vect inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector = InputWebDocument; inputWebFileLocation#c239d686 url:string access_hash:long = InputWebFileLocation; inputWebFileGeoPointLocation#9f2221c9 geo_point:InputGeoPoint access_hash:long w:int h:int zoom:int scale:int = InputWebFileLocation; +inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# document:flags.0?InputDocument title:flags.1?string performer:flags.1?string = InputWebFileLocation; upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile; -payments.paymentForm#b0133b37 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?PaymentSavedCredentials users:Vector = payments.PaymentForm; +payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector users:Vector = payments.PaymentForm; payments.validatedRequestedInfo#d1451883 flags:# id:flags.0?string shipping_options:flags.1?Vector = payments.ValidatedRequestedInfo; payments.paymentResult#4e5f810d updates:Updates = payments.PaymentResult; payments.paymentVerificationNeeded#d8411139 url:string = payments.PaymentResult; @@ -998,6 +1007,10 @@ inputInvoiceSlug#c326caef slug:string = InputInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; messages.transcribedAudio#93752c52 flags:# pending:flags.0?true transcription_id:long text:string = messages.TranscribedAudio; help.premiumPromo#8a4f3c29 status_text:string status_entities:Vector video_sections:Vector videos:Vector currency:string monthly_amount:long users:Vector = help.PremiumPromo; +inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true = InputStorePaymentPurpose; +inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose; +premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; +paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod; ---functions--- 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; invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X; diff --git a/src/lib/gramjs/tl/static/api.tl b/src/lib/gramjs/tl/static/api.tl index 525e85b72..ff11468d3 100644 --- a/src/lib/gramjs/tl/static/api.tl +++ b/src/lib/gramjs/tl/static/api.tl @@ -161,6 +161,7 @@ messageActionSetChatTheme#aa786345 emoticon:string = MessageAction; messageActionChatJoinedByRequest#ebbca3cb = MessageAction; messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction; messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction; +messageActionGiftPremium#aba0f5c6 currency:string amount:long months:int = MessageAction; dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; @@ -210,7 +211,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason; inputReportReasonIllegalDrugs#a8eb2be = ReportReason; inputReportReasonPersonalDetails#9ec7863d = ReportReason; -userFull#8c72ea81 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights = UserFull; +userFull#c4b1fc3f flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector = UserFull; contact#145ade0b user_id:long mutual:Bool = Contact; @@ -292,7 +293,7 @@ updateDeleteChannelMessages#c32d5b12 channel_id:long messages:Vector pts:in updateChannelMessageViews#f226ac08 channel_id:long id:int views:int = Update; updateChatParticipantAdmin#d7ca61a2 chat_id:long user_id:long is_admin:Bool version:int = Update; updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update; -updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true order:Vector = Update; +updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true emojis:flags.1?true order:Vector = Update; updateStickerSets#43ae3dec = Update; updateSavedGifs#9375341e = Update; updateBotInlineQuery#496f379c flags:# query_id:long user_id:long query:string geo:flags.0?GeoPoint peer_type:flags.1?InlineQueryPeerType offset:string = Update; @@ -361,6 +362,7 @@ updateWebViewResultSent#1592b79d query_id:long = Update; updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update; updateSavedRingtones#74d8be99 = Update; updateTranscribedAudio#84cd5a flags:# pending:flags.0?true peer:Peer msg_id:int transcription_id:long text:string = Update; +updateReadFeaturedEmojiStickers#fb4c496c = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -463,6 +465,7 @@ inputPrivacyKeyForwards#a4dd4c08 = InputPrivacyKey; inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey; inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey; inputPrivacyKeyAddedByPhone#d1219bdd = InputPrivacyKey; +inputPrivacyKeyVoiceMessages#aee69d68 = InputPrivacyKey; privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey; privacyKeyChatInvite#500e6dfa = PrivacyKey; @@ -472,6 +475,7 @@ privacyKeyForwards#69ec56a3 = PrivacyKey; privacyKeyProfilePhoto#96151fed = PrivacyKey; privacyKeyPhoneNumber#d19ae46d = PrivacyKey; privacyKeyAddedByPhone#42ffd42b = PrivacyKey; +privacyKeyVoiceMessages#697f414 = PrivacyKey; inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule; inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule; @@ -502,6 +506,7 @@ documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_strea documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute; documentAttributeFilename#15590068 file_name:string = DocumentAttribute; documentAttributeHasStickers#9801d2f7 = DocumentAttribute; +documentAttributeCustomEmoji#fd149899 flags:# free:flags.0?true alt:string stickerset:InputStickerSet = DocumentAttribute; messages.stickersNotModified#f1749a22 = messages.Stickers; messages.stickers#30a6ec7e hash:long stickers:Vector = messages.Stickers; @@ -545,8 +550,9 @@ inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet; inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet; inputStickerSetDice#e67f520e emoticon:string = InputStickerSet; inputStickerSetAnimatedEmojiAnimations#cde3739 = InputStickerSet; +inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet; -stickerSet#d7df217a flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector thumb_dc_id:flags.4?int thumb_version:flags.4?int count:int hash:int = StickerSet; +stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet; messages.stickerSet#b60a24a6 set:StickerSet packs:Vector documents:Vector = messages.StickerSet; messages.stickerSetNotModified#d3f924eb = messages.StickerSet; @@ -598,6 +604,7 @@ messageEntityStrike#bf0693d4 offset:int length:int = MessageEntity; messageEntityBlockquote#20df5d0 offset:int length:int = MessageEntity; messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity; messageEntitySpoiler#32ca960f offset:int length:int = MessageEntity; +messageEntityCustomEmoji#c8cf05f8 offset:int length:int document_id:long = MessageEntity; inputChannelEmpty#ee8c1e86 = InputChannel; inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel; @@ -724,6 +731,7 @@ messages.stickerSetInstallResultArchive#35e410a8 sets:Vector stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered; stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector = StickerSetCovered; +stickerSetFullCovered#1aed5ee5 set:StickerSet packs:Vector documents:Vector = StickerSetCovered; maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords; @@ -812,10 +820,11 @@ inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector inputWebFileLocation#c239d686 url:string access_hash:long = InputWebFileLocation; inputWebFileGeoPointLocation#9f2221c9 geo_point:InputGeoPoint access_hash:long w:int h:int zoom:int scale:int = InputWebFileLocation; +inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# document:flags.0?InputDocument title:flags.1?string performer:flags.1?string = InputWebFileLocation; upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile; -payments.paymentForm#b0133b37 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?PaymentSavedCredentials users:Vector = payments.PaymentForm; +payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector users:Vector = payments.PaymentForm; payments.validatedRequestedInfo#d1451883 flags:# id:flags.0?string shipping_options:flags.1?Vector = payments.ValidatedRequestedInfo; @@ -1357,6 +1366,13 @@ messages.transcribedAudio#93752c52 flags:# pending:flags.0?true transcription_id help.premiumPromo#8a4f3c29 status_text:string status_entities:Vector video_sections:Vector videos:Vector currency:string monthly_amount:long users:Vector = help.PremiumPromo; +inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true = InputStorePaymentPurpose; +inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose; + +premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; + +paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1400,7 +1416,7 @@ account.checkUsername#2714d86c username:string = Bool; account.updateUsername#3e0bdd7c username:string = User; account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules; account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector = account.PrivacyRules; -account.deleteAccount#418d4e0b reason:string = Bool; +account.deleteAccount#a2c0cf74 flags:# reason:string password:flags.0?InputCheckPasswordSRP = Bool; account.getAccountTTL#8fc711d = AccountDaysTTL; account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool; account.sendChangePhoneCode#82574ae5 phone_number:string settings:CodeSettings = auth.SentCode; @@ -1538,7 +1554,7 @@ messages.getMessagesViews#5784d3e1 peer:InputPeer id:Vector increment:Bool messages.editChatAdmin#a85bd1c2 chat_id:long user_id:InputUser is_admin:Bool = Bool; messages.migrateChat#a2875319 chat_id:long = Updates; messages.searchGlobal#4bc6589a flags:# folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; -messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector = Bool; +messages.reorderStickerSets#78337739 flags:# masks:flags.0?true emojis:flags.1?true order:Vector = Bool; messages.getDocumentByHash#b1f2061f sha256:bytes size:long mime_type:string = Document; messages.getSavedGifs#5cf09635 hash:long = messages.SavedGifs; messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool; @@ -1558,7 +1574,7 @@ messages.readFeaturedStickers#5b118126 id:Vector = Bool; messages.getRecentStickers#9da9403b flags:# attached:flags.0?true hash:long = messages.RecentStickers; messages.saveRecentSticker#392718f8 flags:# attached:flags.0?true id:InputDocument unsave:Bool = Bool; messages.clearRecentStickers#8999602d flags:# attached:flags.0?true = Bool; -messages.getArchivedStickers#57f17692 flags:# masks:flags.0?true offset_id:long limit:int = messages.ArchivedStickers; +messages.getArchivedStickers#57f17692 flags:# masks:flags.0?true emojis:flags.1?true offset_id:long limit:int = messages.ArchivedStickers; messages.getMaskStickers#640f82b8 hash:long = messages.AllStickers; messages.getAttachedStickers#cc5b67cc media:InputStickeredMedia = Vector; messages.setGameScore#8ef8ecc0 flags:# edit_message:flags.0?true force:flags.1?true peer:InputPeer id:int user_id:InputUser score:int = Updates; @@ -1659,6 +1675,9 @@ messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInl messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates; messages.transcribeAudio#269e9a49 peer:InputPeer msg_id:int = messages.TranscribedAudio; messages.rateTranscribedAudio#7f1d072f peer:InputPeer msg_id:int transcription_id:long good:Bool = Bool; +messages.getCustomEmojiDocuments#d9ab0f54 document_id:Vector = Vector; +messages.getEmojiStickers#fbfca18f hash:long = messages.AllStickers; +messages.getFeaturedEmojiStickers#ecf6736 hash:long = messages.FeaturedStickers; updates.getState#edd4882a = updates.State; updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference; @@ -1762,10 +1781,9 @@ payments.getSavedInfo#227d824b = payments.SavedInfo; payments.clearSavedInfo#d83d70c1 flags:# credentials:flags.0?true info:flags.1?true = Bool; payments.getBankCardData#2e79d779 number:string = payments.BankCardData; payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoice; -payments.assignAppStoreTransaction#fec13c6 flags:# restore:flags.0?true transaction_id:string receipt:bytes = Updates; -payments.assignPlayMarketTransaction#4faa4aed purchase_token:string = Updates; -payments.restorePlayMarketReceipt#d164e36a receipt:bytes = Updates; -payments.canPurchasePremium#aa6a90c8 = Bool; +payments.assignAppStoreTransaction#80ed747d receipt:bytes purpose:InputStorePaymentPurpose = Updates; +payments.assignPlayMarketTransaction#dffd50d3 receipt:DataJSON purpose:InputStorePaymentPurpose = Updates; +payments.canPurchasePremium#9fc19eb6 purpose:InputStorePaymentPurpose = Bool; payments.requestRecurringPayment#146e958d user_id:InputUser recurring_init_charge:string invoice_media:InputMedia = Updates; stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector software:flags.3?string = messages.StickerSet; diff --git a/src/util/deeplink.ts b/src/util/deeplink.ts index 67e0bd358..f3d6cd91c 100644 --- a/src/util/deeplink.ts +++ b/src/util/deeplink.ts @@ -1,8 +1,9 @@ import { getActions } from '../global'; import { IS_SAFARI } from './environment'; -type DeepLinkMethod = 'resolve' | 'login' | 'passport' | 'settings' | 'join' | 'addstickers' | 'setlanguage' | -'addtheme' | 'confirmphone' | 'socks' | 'proxy' | 'privatepost' | 'bg' | 'share' | 'msg' | 'msg_url' | 'invoice'; +type DeepLinkMethod = 'resolve' | 'login' | 'passport' | 'settings' | 'join' | 'addstickers' | 'addemoji' | +'setlanguage' | 'addtheme' | 'confirmphone' | 'socks' | 'proxy' | 'privatepost' | 'bg' | 'share' | 'msg' | 'msg_url' | +'invoice'; export const processDeepLink = (url: string) => { const { @@ -80,6 +81,7 @@ export const processDeepLink = (url: string) => { openChatByInvite({ hash: invite }); break; } + case 'addemoji': case 'addstickers': { const { set } = params;