[dev] API Layer 151 (#2290)

This commit is contained in:
Alexander Zinchuk 2023-01-22 18:11:39 +01:00
parent c3a2b5af38
commit 288ce625a3
50 changed files with 508 additions and 193 deletions

View File

@ -35,6 +35,7 @@ export interface GramJsAppConfig extends LimitsConfig {
premium_invoice_slug: string;
premium_promo_order: string[];
default_emoji_statuses_stickerset_id: string;
hidden_members_group_size_min: number;
// Forums
topics_pinned_limit: number;
}
@ -84,6 +85,7 @@ export function buildAppConfig(json: GramJs.TypeJSONValue): ApiAppConfig {
topicsPinnedLimit: appConfig.topics_pinned_limit,
maxUserReactionsDefault: appConfig.reactions_user_max_default,
maxUserReactionsPremium: appConfig.reactions_user_max_premium,
hiddenMembersMinCount: appConfig.hidden_members_group_size_min,
limits: {
uploadMaxFileparts: getLimit(appConfig, 'upload_max_fileparts', 'uploadMaxFileparts'),
stickersFaved: getLimit(appConfig, 'stickers_faved_limit', 'stickersFaved'),

View File

@ -66,6 +66,7 @@ export function buildApiAttachBot(bot: GramJs.AttachMenuBot): ApiAttachBot {
return {
id: bot.botId.toString(),
hasSettings: bot.hasSettings,
shouldRequestWriteAccess: bot.requestWriteAccess,
shortName: bot.shortName,
peerTypes: bot.peerTypes.map(buildApiAttachMenuPeerType),
icons: bot.icons.map(buildApiAttachMenuIcon).filter(Boolean),

View File

@ -1044,6 +1044,8 @@ function buildAction(
} else {
text = 'ChatList.UnsupportedMessage';
}
} else if (action instanceof GramJs.MessageActionAttachMenuBotAllowed) {
text = 'ActionAttachMenuBotAllowed';
} else {
text = 'ChatList.UnsupportedMessage';
}

View File

@ -35,6 +35,7 @@ export function buildStickerFromDocument(document: GramJs.TypeDocument, isNoPrem
const isLottie = mimeType === LOTTIE_STICKER_MIME_TYPE;
const isVideo = mimeType === VIDEO_STICKER_MIME_TYPE;
const isCustomEmoji = Boolean(customEmojiAttribute);
const shouldUseTextColor = isCustomEmoji && customEmojiAttribute.textColor;
const imageSizeAttribute = document.attributes
.find((attr: any): attr is GramJs.DocumentAttributeImageSize => (
@ -94,6 +95,7 @@ export function buildStickerFromDocument(document: GramJs.TypeDocument, isNoPrem
thumbnail,
hasEffect,
isFree,
shouldUseTextColor,
};
}
@ -149,6 +151,10 @@ function buildApiStickerSetInfo(inputSet?: GramJs.TypeInputStickerSet): ApiStick
export function buildStickerSetCovered(coveredStickerSet: GramJs.TypeStickerSetCovered): ApiStickerSet {
const stickerSet = buildStickerSet(coveredStickerSet.set);
if (coveredStickerSet instanceof GramJs.StickerSetNoCovered) {
return stickerSet;
}
const stickerSetCovers = (coveredStickerSet instanceof GramJs.StickerSetCovered) ? [coveredStickerSet.cover]
: (coveredStickerSet instanceof GramJs.StickerSetMultiCovered) ? coveredStickerSet.covers
: coveredStickerSet.documents;

View File

@ -279,15 +279,37 @@ export async function loadAttachBots({
return undefined;
}
export async function loadAttachBot({
bot,
}: {
bot: ApiUser;
}) {
const result = await invokeRequest(new GramJs.messages.GetAttachMenuBot({
bot: buildInputPeer(bot.id, bot.accessHash),
}));
if (result instanceof GramJs.AttachMenuBotsBot) {
addEntitiesWithPhotosToLocalDb(result.users);
return {
bot: buildApiAttachBot(result.bot),
users: result.users.map(buildApiUser).filter(Boolean),
};
}
return undefined;
}
export function toggleAttachBot({
bot,
isWriteAllowed,
isEnabled,
}: {
bot: ApiUser;
isWriteAllowed?: boolean;
isEnabled: boolean;
}) {
return invokeRequest(new GramJs.messages.ToggleBotInAttachMenu({
bot: buildInputPeer(bot.id, bot.accessHash),
writeAllowed: isWriteAllowed || undefined,
enabled: isEnabled,
}));
}

View File

@ -470,6 +470,7 @@ async function getFullChannelInfo(
participantsCount,
stickerset,
chatPhoto,
participantsHidden,
} = result.fullChat;
if (chatPhoto instanceof GramJs.Photo) {
@ -538,6 +539,7 @@ async function getFullChannelInfo(
recentRequesterIds: recentRequesters?.map((userId) => buildApiPeerId(userId, 'user')),
statisticsDcId: statsDc,
stickerSet: stickerset ? buildStickerSet(stickerset) : undefined,
areParticipantsHidden: participantsHidden,
},
users: [...(users || []), ...(bannedUsers || []), ...(adminUsers || [])],
userStatusesById: statusesById,
@ -1344,6 +1346,17 @@ export function toggleIsProtected({
}), true);
}
export function toggleParticipantsHidden({
chat, isEnabled,
}: { chat: ApiChat; isEnabled: boolean }) {
const { id, accessHash } = chat;
return invokeRequest(new GramJs.channels.ToggleParticipantsHidden({
channel: buildInputPeer(id, accessHash),
enabled: isEnabled,
}), true);
}
export function toggleForum({
chat, isEnabled,
}: { chat: ApiChat; isEnabled: boolean }) {

View File

@ -20,7 +20,7 @@ export {
updateChatTitle, updateChatAbout, toggleSignatures, updateChatAdmin, fetchGroupsForDiscussion, setDiscussionGroup,
migrateChat, openChatByInvite, fetchMembers, importChatInvite, addChatMembers, deleteChatMember, toggleIsProtected,
getChatByPhoneNumber, toggleJoinToSend, toggleJoinRequest, fetchTopics, deleteTopic, togglePinnedTopic,
editTopic, toggleForum, fetchTopicById, createTopic,
editTopic, toggleForum, fetchTopicById, createTopic, toggleParticipantsHidden,
} from './chats';
export {
@ -71,7 +71,7 @@ export {
export {
answerCallbackButton, fetchTopInlineBots, fetchInlineBot, fetchInlineBotResults, sendInlineBotResult, startBot,
requestWebView, requestSimpleWebView, sendWebViewData, prolongWebView, loadAttachBots, toggleAttachBot,
requestBotUrlAuth, requestLinkUrlAuth, acceptBotUrlAuth, acceptLinkUrlAuth,
requestBotUrlAuth, requestLinkUrlAuth, acceptBotUrlAuth, acceptLinkUrlAuth, loadAttachBot,
} from './bots';
export {

View File

@ -806,6 +806,11 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
userId: buildApiPeerId(update.userId, 'user'),
status: buildApiUserStatus(update.status),
});
} else if (update instanceof GramJs.UpdateUser) {
onUpdate({
'@type': 'updateRequestUserUpdate',
id: buildApiPeerId(update.userId, 'user'),
});
} else if (update instanceof GramJs.UpdateUserEmojiStatus) {
const emojiStatus = buildApiUserEmojiStatus(update.emojiStatus);
onUpdate({
@ -831,20 +836,6 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
usernames,
},
});
} else if (update instanceof GramJs.UpdateUserPhoto) {
const { userId, photo } = update;
const apiUserId = buildApiPeerId(userId, 'user');
const avatarHash = buildAvatarHash(photo);
if (localDb.users[apiUserId]) {
localDb.users[apiUserId].photo = photo;
}
onUpdate({
'@type': 'updateUser',
id: apiUserId,
user: { avatarHash },
});
} else if (update instanceof GramJs.UpdateUserPhone) {
const { userId, phone } = update;

View File

@ -114,6 +114,7 @@ export interface ApiChatFullInfo {
statisticsDcId?: number;
stickerSet?: ApiStickerSet;
profilePhoto?: ApiPhoto;
areParticipantsHidden?: boolean;
}
export interface ApiChatMember {

View File

@ -43,6 +43,7 @@ export interface ApiSticker {
isPreloadedGlobally?: boolean;
hasEffect?: boolean;
isFree?: boolean;
shouldUseTextColor?: boolean;
}
export interface ApiStickerSet {

View File

@ -178,6 +178,7 @@ export interface ApiAppConfig {
topicsPinnedLimit: number;
maxUserReactionsDefault: number;
maxUserReactionsPremium: number;
hiddenMembersMinCount: number;
limits: Record<ApiLimitType, readonly [number, number]>;
}

View File

@ -342,6 +342,11 @@ export type ApiUpdateUser = {
user: Partial<ApiUser>;
};
export type ApiUpdateRequestUserUpdate = {
'@type': 'updateRequestUserUpdate';
id: string;
};
export type ApiUpdateUserStatus = {
'@type': 'updateUserStatus';
userId: string;
@ -595,7 +600,7 @@ export type ApiUpdateTopics = {
};
export type ApiUpdate = (
ApiUpdateReady | ApiUpdateSession | ApiUpdateWebAuthTokenFailed |
ApiUpdateReady | ApiUpdateSession | ApiUpdateWebAuthTokenFailed | ApiUpdateRequestUserUpdate |
ApiUpdateAuthorizationState | ApiUpdateAuthorizationError | ApiUpdateConnectionState | ApiUpdateCurrentUser |
ApiUpdateChat | ApiUpdateChatInbox | ApiUpdateChatTypingStatus | ApiUpdateChatFullInfo | ApiUpdatePinnedChatIds |
ApiUpdateChatMembers | ApiUpdateChatJoin | ApiUpdateChatLeave | ApiUpdateChatPinned | ApiUpdatePinnedMessageIds |

View File

@ -70,6 +70,7 @@ export type ApiAttachMenuPeerType = 'self' | ApiChatType;
export interface ApiAttachBot {
id: string;
hasSettings?: boolean;
shouldRequestWriteAccess?: boolean;
shortName: string;
peerTypes: ApiAttachMenuPeerType[];
icons: ApiAttachBotIcon[];

View File

@ -11,10 +11,6 @@
height: calc(100% + 1px) !important;
}
&:global(.custom-color) {
--emoji-status-color: var(--color-primary);
}
canvas {
display: block;
}

View File

@ -11,7 +11,7 @@ import { getPropertyHexColor } from '../../util/themeStyle';
import { hexToRgb } from '../../util/switchTheme';
import buildClassName from '../../util/buildClassName';
import safePlay from '../../util/safePlay';
import { selectIsAlwaysHighPriorityEmoji, selectIsDefaultEmojiStatusPack } from '../../global/selectors';
import { selectIsAlwaysHighPriorityEmoji } from '../../global/selectors';
import useCustomEmoji from './hooks/useCustomEmoji';
@ -76,14 +76,14 @@ const CustomEmoji: FC<OwnProps> = ({
const [shouldLoop, setShouldLoop] = useState(true);
const [customColor, setCustomColor] = useState<[number, number, number] | undefined>();
const hasCustomColor = customEmoji && selectIsDefaultEmojiStatusPack(getGlobal(), customEmoji.stickerSetInfo);
const hasCustomColor = customEmoji?.shouldUseTextColor;
useEffect(() => {
if (!hasCustomColor) {
setCustomColor(undefined);
return;
}
const hexColor = getPropertyHexColor(getComputedStyle(containerRef.current!), '--emoji-status-color');
const hexColor = getPropertyHexColor(getComputedStyle(containerRef.current!), '--color-text');
if (!hexColor) {
setCustomColor(undefined);
return;
@ -127,7 +127,6 @@ const CustomEmoji: FC<OwnProps> = ({
className,
'custom-emoji',
'emoji',
hasCustomColor && 'custom-color',
withGridFix && styles.withGridFix,
)}
onClick={onClick}

View File

@ -45,9 +45,6 @@
cursor: pointer;
--custom-emoji-size: 1.5rem;
.custom-color {
--emoji-status-color: var(--color-white);
}
--color-text: var(--color-white);
}
}

View File

@ -1,6 +1,6 @@
import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react';
import React, {
memo, useCallback, useEffect, useMemo, useRef,
memo, useCallback, useEffect, useMemo, useRef, useState,
} from '../../lib/teact/teact';
import { getActions } from '../../global';
@ -9,6 +9,8 @@ import type { ApiBotInlineMediaResult, ApiSticker } from '../../api/types';
import buildClassName from '../../util/buildClassName';
import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';
import { IS_TOUCH_ENV } from '../../util/environment';
import { getPropertyHexColor } from '../../util/themeStyle';
import { hexToRgb } from '../../util/switchTheme';
import type { ObserveFn } from '../../hooks/useIntersectionObserver';
import { useIsIntersecting } from '../../hooks/useIntersectionObserver';
@ -64,6 +66,22 @@ const StickerButton = <T extends number | ApiSticker | ApiBotInlineMediaResult |
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
const lang = useLang();
const [customColor, setCustomColor] = useState<[number, number, number] | undefined>();
const hasCustomColor = sticker.shouldUseTextColor;
useEffect(() => {
if (!hasCustomColor) {
setCustomColor(undefined);
return;
}
const hexColor = getPropertyHexColor(getComputedStyle(ref.current!), '--color-text');
if (!hexColor) {
setCustomColor(undefined);
return;
}
const customColorRgb = hexToRgb(hexColor);
setCustomColor([customColorRgb.r, customColorRgb.g, customColorRgb.b]);
}, [hasCustomColor]);
const {
id, isCustomEmoji, hasEffect: isPremium, stickerSetInfo,
@ -234,6 +252,7 @@ const StickerButton = <T extends number | ApiSticker | ApiBotInlineMediaResult |
noPlay={!shouldPlay}
withSharedAnimation
sharedCanvasRef={sharedCanvasRef}
customColor={customColor}
/>
{isLocked && (
<div

View File

@ -89,8 +89,8 @@
&.selected:not(.forum):hover {
--background-color: var(--color-chat-active) !important;
.custom-emoji.custom-color {
--emoji-status-color: var(--color-white);
.custom-emoji {
--color-text: var(--color-white);
}
.VerifiedIcon, .PremiumIcon {
@ -167,6 +167,10 @@
background: var(--background-color);
}
.custom-emoji {
--color-text: var(--color-primary);
}
.avatar-badge-wrapper {
position: absolute;
bottom: 0;

View File

@ -34,7 +34,6 @@ import {
selectNotifySettings,
selectNotifyExceptions,
selectUserStatus,
selectIsDefaultEmojiStatusPack,
selectTopicFromMessage,
selectThreadParam,
} from '../../../global/selectors';
@ -327,12 +326,12 @@ export default memo(withGlobal<OwnProps>(
const user = privateChatUserId ? selectUser(global, privateChatUserId) : undefined;
const userStatus = privateChatUserId ? selectUserStatus(global, privateChatUserId) : undefined;
const statusEmoji = user?.emojiStatus && global.customEmojis.byId[user.emojiStatus.documentId];
const isEmojiStatusColored = statusEmoji && selectIsDefaultEmojiStatusPack(global, statusEmoji.stickerSetInfo);
const lastMessageTopic = chat.lastMessage && selectTopicFromMessage(global, chat.lastMessage);
const typingStatus = selectThreadParam(global, chatId, MAIN_THREAD_ID, 'typingStatus');
const statusEmoji = user?.emojiStatus && global.customEmojis.byId[user.emojiStatus.documentId];
return {
chat,
isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),
@ -352,9 +351,9 @@ export default memo(withGlobal<OwnProps>(
}),
user,
userStatus,
isEmojiStatusColored,
lastMessageTopic,
typingStatus,
isEmojiStatusColored: statusEmoji?.shouldUseTextColor,
};
},
)(Chat));

View File

@ -1,35 +1,68 @@
import React, { memo } from '../../lib/teact/teact';
import React, {
memo, useCallback, useEffect, useState,
} from '../../lib/teact/teact';
import { getActions } from '../../global';
import type { FC } from '../../lib/teact/teact';
import type { ApiUser } from '../../api/types';
import type { ApiAttachBot } from '../../api/types';
import renderText from '../common/helpers/renderText';
import useLang from '../../hooks/useLang';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import usePrevious from '../../hooks/usePrevious';
import ConfirmDialog from '../ui/ConfirmDialog';
import Checkbox from '../ui/Checkbox';
export type OwnProps = {
bot?: ApiUser;
bot?: ApiAttachBot;
};
const AttachBotInstallModal: FC<OwnProps> = ({
bot,
}) => {
const { cancelAttachBotInstall, confirmAttachBotInstall } = getActions();
const { confirmAttachBotInstall, cancelAttachBotInstall } = getActions();
const [isWriteAllowed, setIsWriteAllowed] = useState(bot?.shouldRequestWriteAccess || false);
const lang = useLang();
const name = useCurrentOrPrev(bot?.firstName, true);
const prevBot = usePrevious(bot);
const renderingBot = bot || prevBot;
const handleConfirm = useCallback(() => {
confirmAttachBotInstall({
isWriteAllowed,
});
}, [confirmAttachBotInstall, isWriteAllowed]);
// Reset on re-open
useEffect(() => {
if (bot) {
setIsWriteAllowed(bot.shouldRequestWriteAccess ?? false);
}
}, [bot]);
return (
<ConfirmDialog
isOpen={Boolean(bot)}
onClose={cancelAttachBotInstall}
confirmHandler={confirmAttachBotInstall}
title={name}
text={lang('WebApp.AddToAttachmentText', name)}
/>
isButtonsInOneRow
title={renderingBot?.shortName}
confirmHandler={handleConfirm}
>
{lang('WebApp.AddToAttachmentText', renderingBot?.shortName)}
{renderingBot?.shouldRequestWriteAccess && (
<Checkbox
className="dialog-checkbox"
checked={isWriteAllowed}
label={renderText(
lang('WebApp.AddToAttachmentAllowMessages', renderingBot?.shortName),
['simple_markdown'],
)}
onCheck={setIsWriteAllowed}
/>
)}
</ConfirmDialog>
);
};

View File

@ -27,12 +27,12 @@ const AttachBotRecipientPicker: FC<OwnProps> = ({
}
}, [isOpen, markIsShown]);
const { botId, filter, startParam } = requestedAttachBotInChat || {};
const { bot, filter, startParam } = requestedAttachBotInChat || {};
const handlePeerRecipient = useCallback((recipientId: string) => {
callAttachBot({ botId: botId!, chatId: recipientId, startParam });
callAttachBot({ bot: bot!, chatId: recipientId, startParam });
cancelAttachBotInChat();
}, [botId, callAttachBot, cancelAttachBotInChat, startParam]);
}, [bot, callAttachBot, cancelAttachBotInChat, startParam]);
if (!isOpen && !isShown) {
return undefined;

View File

@ -6,6 +6,7 @@ import { getActions, getGlobal, withGlobal } from '../../global';
import type { AnimationLevel, LangCode } from '../../types';
import type {
ApiAttachBot,
ApiChat, ApiMessage, ApiUser,
} from '../../api/types';
import type { ApiLimitTypeWithModal, GlobalState } from '../../global/types';
@ -109,7 +110,7 @@ type StateProps = {
isPremiumModalOpen?: boolean;
botTrustRequest?: GlobalState['botTrustRequest'];
botTrustRequestBot?: ApiUser;
attachBotToInstall?: ApiUser;
attachBotToInstall?: ApiAttachBot;
requestedAttachBotInChat?: GlobalState['requestedAttachBotInChat'];
requestedDraft?: GlobalState['requestedDraft'];
currentUser?: ApiUser;
@ -567,7 +568,7 @@ export default memo(withGlobal(
isRatePhoneCallModalOpen: Boolean(global.ratingPhoneCall),
botTrustRequest,
botTrustRequestBot: botTrustRequest && selectUser(global, botTrustRequest.botId),
attachBotToInstall: requestedAttachBotInstall && selectUser(global, requestedAttachBotInstall.botId),
attachBotToInstall: requestedAttachBotInstall?.bot,
requestedAttachBotInChat,
webApp,
currentUser,

View File

@ -119,9 +119,4 @@
.modal-content {
padding-left: 2rem;
}
.dialog-buttons {
justify-content: flex-end;
gap: 0.25rem;
}
}

View File

@ -92,6 +92,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
openChat,
openInvoice,
setWebAppPaymentSlug,
showNotification,
} = getActions();
const [mainButton, setMainButton] = useState<WebAppButton | undefined>();
const [isBackButtonVisible, setIsBackButtonVisible] = useState(false);
@ -188,9 +189,15 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
if (!eventData.message.trim().length || !eventData.buttons?.length || eventData.buttons.length > 3) return;
setPopupParams(eventData);
}
if (eventType === 'web_app_open_scan_qr_popup') {
showNotification({
message: 'Scan QR code is not supported in this client yet',
});
}
}, [
bot, buttonText, closeWebApp, openInvoice, openTelegramLink, sendWebViewData, setWebAppPaymentSlug,
isPaymentModalOpen,
isPaymentModalOpen, showNotification,
]);
const {

View File

@ -36,6 +36,7 @@ export type WebAppInboundEvent = {
eventType: 'web_app_open_link';
eventData: {
url: string;
try_instant_view?: boolean;
};
} | {
eventType: 'web_app_open_tg_link';
@ -72,9 +73,19 @@ export type WebAppInboundEvent = {
eventData: {
need_confirmation: boolean;
};
} | {
eventType: 'web_app_open_scan_qr_popup';
eventData: {
text?: string;
};
} | {
eventType: 'web_app_read_text_from_clipboard';
eventData: {
req_id: string;
};
} | {
eventType: 'web_app_request_viewport' | 'web_app_request_theme' | 'web_app_ready' | 'web_app_expand'
| 'web_app_request_phone' | 'web_app_close' | 'iframe_ready';
| 'web_app_request_phone' | 'web_app_close' | 'iframe_ready' | 'web_app_close_scan_qr_popup';
eventData: null;
};
@ -119,7 +130,18 @@ type WebAppOutboundEvent = {
button_id?: string;
};
} | {
eventType: 'main_button_pressed' | 'back_button_pressed' | 'settings_button_pressed';
eventType: 'qr_text_received';
eventData: {
data: string;
};
} | {
eventType: 'clipboard_text_received';
eventData: {
req_id: string;
data: string | null;
};
} | {
eventType: 'main_button_pressed' | 'back_button_pressed' | 'settings_button_pressed' | 'scan_qr_popup_closed';
};
const SCROLLBAR_STYLE = `* {
@ -223,11 +245,25 @@ const useWebAppFrame = (
if (!isSimpleView) return; // Allowed only in simple view
ignoreEventsRef.current = true;
}
if (data.eventType === 'web_app_read_text_from_clipboard') {
const { req_id: requestId } = data.eventData;
// eslint-disable-next-line no-null/no-null -- Required by spec
window.navigator.clipboard.readText().catch(() => null).then((text) => {
sendEvent({
eventType: 'clipboard_text_received',
eventData: {
req_id: requestId,
data: text,
},
});
});
}
onEvent(data);
} catch (err) {
// Ignore other messages
}
}, [isSimpleView, onEvent, sendCustomStyle, sendTheme, sendViewport, windowSize]);
}, [isSimpleView, onEvent, sendCustomStyle, sendEvent, sendTheme, sendViewport, windowSize.isResizing]);
useEffect(() => {
const { width, height, isResizing } = windowSize;

View File

@ -318,6 +318,10 @@
}
}
}
.custom-emoji {
--color-text: var(--color-primary);
}
}
.Avatar, .topic-header-icon {

View File

@ -74,7 +74,7 @@ const AttachBotItem: FC<OwnProps> = ({
icon={!icon ? 'bots' : undefined}
// eslint-disable-next-line react/jsx-no-bind
onClick={() => callAttachBot({
botId: bot.id,
bot,
chatId,
threadId,
})}

View File

@ -742,10 +742,12 @@ const Composer: FC<OwnProps & StateProps> = ({
return;
}
const attachBot = attachBots[chatId];
callAttachBot({
botId: chatId, chatId, isFromBotMenu: true, url: botMenuButton.url, threadId,
bot: attachBot, chatId, isFromBotMenu: true, url: botMenuButton.url, threadId,
});
}, [botMenuButton, callAttachBot, chatId, threadId]);
}, [attachBots, botMenuButton, callAttachBot, chatId, threadId]);
const handleActivateBotCommandMenu = useCallback(() => {
closeSymbolMenu();

View File

@ -125,7 +125,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
return MEMO_EMPTY_ARRAY;
}
const defaultSets = [];
const defaultSets: StickerSetOrRecent[] = [];
if (withDefaultTopicIcons) {
const defaultTopicIconsPack = stickerSetsById[defaultTopicIconsId!];
@ -139,6 +139,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
} else if (recentCustomEmoji.length) {
defaultSets.push({
id: RECENT_SYMBOL_SET_ID,
accessHash: '0',
title: lang('RecentStickers'),
stickers: recentCustomEmoji,
count: recentCustomEmoji.length,
@ -296,7 +297,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
shouldRender={activeSetIndex >= i - 1 && activeSetIndex <= i + 1}
isSavedMessages={isSavedMessages}
shouldHideRecentHeader={withDefaultTopicIcons}
withDefaultTopicIcon={stickerSet.id === RECENT_SYMBOL_SET_ID}
withDefaultTopicIcon={withDefaultTopicIcons && stickerSet.id === RECENT_SYMBOL_SET_ID}
isCustomEmojiPicker
isCurrentUserPremium={isCurrentUserPremium}
onStickerSelect={handleEmojiSelect}

View File

@ -145,6 +145,7 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
if (favoriteStickers.length) {
defaultSets.push({
id: FAVORITE_SYMBOL_SET_ID,
accessHash: '0',
title: lang('FavoriteStickers'),
stickers: favoriteStickers,
count: favoriteStickers.length,
@ -154,6 +155,7 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
if (recentStickers.length) {
defaultSets.push({
id: RECENT_SYMBOL_SET_ID,
accessHash: '0',
title: lang('RecentStickers'),
stickers: recentStickers,
count: recentStickers.length,
@ -171,6 +173,7 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
if (totalPremiumStickers.length) {
defaultSets.push({
id: PREMIUM_STICKER_SET_ID,
accessHash: '0',
title: lang('PremiumStickers'),
stickers: totalPremiumStickers,
count: totalPremiumStickers.length,
@ -183,6 +186,7 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
if (fullSet) {
defaultSets.push({
id: CHAT_STICKER_SET_ID,
accessHash: fullSet.accessHash,
title: lang('GroupStickers'),
stickers: fullSet.stickers,
count: fullSet.stickers!.length,

View File

@ -1,5 +1,5 @@
import React, {
memo, useCallback, useLayoutEffect, useMemo, useRef, useState,
memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,
} from '../../../lib/teact/teact';
import { getActions, getGlobal } from '../../../global';
@ -7,7 +7,6 @@ import type { FC } from '../../../lib/teact/teact';
import type { ApiSticker } from '../../../api/types';
import type { StickerSetOrRecent } from '../../../types';
import type { ObserveFn } from '../../../hooks/useIntersectionObserver';
import { useOnIntersect } from '../../../hooks/useIntersectionObserver';
import {
DEFAULT_TOPIC_ICON_STICKER_ID,
@ -21,6 +20,7 @@ import useLang from '../../../hooks/useLang';
import useFlag from '../../../hooks/useFlag';
import useMediaTransition from '../../../hooks/useMediaTransition';
import { useResizeObserver } from '../../../hooks/useResizeObserver';
import { useIsIntersecting } from '../../../hooks/useIntersectionObserver';
import StickerButton from '../../common/StickerButton';
import ConfirmDialog from '../../ui/ConfirmDialog';
@ -74,6 +74,7 @@ const StickerSet: FC<OwnProps> = ({
clearRecentCustomEmoji,
openPremiumModal,
toggleStickerSet,
loadStickers,
} = getActions();
// eslint-disable-next-line no-null/no-null
@ -89,7 +90,7 @@ const StickerSet: FC<OwnProps> = ({
const [itemsPerRow, setItemsPerRow] = useState(ITEMS_PER_ROW_FALLBACK);
useOnIntersect(ref, observeIntersection);
const isIntersecting = useIsIntersecting(ref, observeIntersection);
const transitionClassNames = useMediaTransition(shouldRender);
@ -149,6 +150,17 @@ const StickerSet: FC<OwnProps> = ({
setItemsPerRow(calculateItemsPerRow(ref.current.clientWidth));
}, [calculateItemsPerRow]);
useEffect(() => {
if (isIntersecting && !stickerSet.stickers?.length && stickerSet.accessHash) {
loadStickers({
stickerSetInfo: {
id: stickerSet.id,
accessHash: stickerSet.accessHash,
},
});
}
}, [isIntersecting, loadStickers, stickerSet]);
const isLocked = !isSavedMessages && !isRecent && isEmoji && !isCurrentUserPremium
&& stickerSet.stickers?.some(({ isFree }) => !isFree);

View File

@ -1,7 +1,7 @@
import type { FC } from '../../../lib/teact/teact';
import React, { memo, useRef } from '../../../lib/teact/teact';
import { getGlobal } from '../../../global';
import React, { memo, useEffect, useRef } from '../../../lib/teact/teact';
import { getActions, getGlobal } from '../../../global';
import type { FC } from '../../../lib/teact/teact';
import type { ApiStickerSet } from '../../../api/types';
import type { ObserveFn } from '../../../hooks/useIntersectionObserver';
@ -37,6 +37,7 @@ const StickerSetCover: FC<OwnProps> = ({
observeIntersection,
sharedCanvasRef,
}) => {
const { loadStickers } = getActions();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
@ -55,6 +56,17 @@ const StickerSetCover: FC<OwnProps> = ({
const bounds = useBoundsInSharedCanvas(containerRef, sharedCanvasRef);
useEffect(() => {
if (isIntersecting && !stickerSet.stickers?.length) {
loadStickers({
stickerSetInfo: {
id: stickerSet.id,
accessHash: stickerSet.accessHash,
},
});
}
}, [isIntersecting, loadStickers, stickerSet]);
return (
<div ref={containerRef} className="sticker-set-cover">
{isReady ? (

View File

@ -244,8 +244,8 @@
& > .color-#{$i} {
color: var(--color-user-#{$i});
.custom-emoji.custom-color {
--emoji-status-color: var(--color-user-#{$i});
.custom-emoji {
--color-text: var(--color-user-#{$i});
}
.PremiumIcon {
@ -273,10 +273,6 @@
.custom-emoji {
margin-left: 0.25rem;
&.custom-color {
opacity: 0.5;
}
}
.PremiumIcon {

View File

@ -78,7 +78,7 @@ const CreateTopic: FC<OwnProps & StateProps> = ({
}, [chat, createTopic, iconColorIndex, iconEmojiId, title]);
const handleCustomEmojiSelect = useCallback((emoji: ApiSticker) => {
if (!emoji.isFree && !isCurrentUserPremium) {
if (!emoji.isFree && !isCurrentUserPremium && emoji.id !== DEFAULT_TOPIC_ICON_STICKER_ID) {
openPremiumModal({ initialSection: 'animated_emoji' });
return;
}

View File

@ -87,7 +87,7 @@ const EditTopic: FC<OwnProps & StateProps> = ({
}, [chat, editTopic, iconEmojiId, title, topic]);
const handleCustomEmojiSelect = useCallback((emoji: ApiSticker) => {
if (!emoji.isFree && !isCurrentUserPremium) {
if (!emoji.isFree && !isCurrentUserPremium && emoji.id !== DEFAULT_TOPIC_ICON_STICKER_ID) {
openPremiumModal({ initialSection: 'animated_emoji' });
return;
}

View File

@ -10,7 +10,7 @@ import { ManagementScreens } from '../../../types';
import { unique } from '../../../util/iteratees';
import { selectChat } from '../../../global/selectors';
import {
sortUserIds, isChatChannel, filterUsersByName, sortChatIds, isUserBot, getHasAdminRight,
sortUserIds, isChatChannel, filterUsersByName, sortChatIds, isUserBot, getHasAdminRight, isChatBasicGroup,
} from '../../../global/helpers';
import useLang from '../../../hooks/useLang';
import useHistoryBack from '../../../hooks/useHistoryBack';
@ -24,6 +24,7 @@ import InputText from '../../ui/InputText';
import InfiniteScroll from '../../ui/InfiniteScroll';
import Loading from '../../ui/Loading';
import DeleteMemberModal from '../DeleteMemberModal';
import Switcher from '../../ui/Switcher';
type OwnProps = {
chatId: string;
@ -47,9 +48,12 @@ type StateProps = {
serverTimeOffset: number;
currentUserId?: string;
canDeleteMembers?: boolean;
isBasicGroup?: boolean;
areParticipantsHidden?: boolean;
};
const ManageGroupMembers: FC<OwnProps & StateProps> = ({
chatId,
noAdmins,
members,
adminMembersById,
@ -64,11 +68,15 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
serverTimeOffset,
currentUserId,
canDeleteMembers,
isBasicGroup,
areParticipantsHidden,
onClose,
onScreenSelect,
onChatMemberSelect,
}) => {
const { openChat, setUserSearchQuery, closeManagement } = getActions();
const {
openChat, setUserSearchQuery, closeManagement, toggleParticipantsHidden,
} = getActions();
const lang = useLang();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);
@ -152,6 +160,10 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
setDeletingUserId(undefined);
}, []);
const handleToggleParticipantsHidden = useCallback(() => {
toggleParticipantsHidden({ chatId, isEnabled: !areParticipantsHidden });
}, [areParticipantsHidden, chatId, toggleParticipantsHidden]);
useHistoryBack({
isActive,
onBack: onClose,
@ -184,6 +196,17 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
<div className="Management">
{noAdmins && renderSearchField()}
<div className="custom-scroll">
{!isBasicGroup && (
<div className="section">
<ListItem icon="group" ripple onClick={handleToggleParticipantsHidden}>
<span>{lang('ChannelHideMembers')}</span>
<Switcher label={lang('ChannelHideMembers')} checked={areParticipantsHidden} />
</ListItem>
<p className="section-info">
{lang(areParticipantsHidden ? 'GroupMembers.MembersHiddenOn' : 'GroupMembers.MembersHiddenOff')}
</p>
</div>
)}
<div className="section">
{viewportIds?.length ? (
<InfiniteScroll
@ -247,6 +270,8 @@ export default memo(withGlobal<OwnProps>(
const canDeleteMembers = chat && (chat.isCreator || getHasAdminRight(chat, 'banUsers'));
return {
isBasicGroup: Boolean(chat && isChatBasicGroup(chat)),
areParticipantsHidden: Boolean(chat && chat.fullInfo?.areParticipantsHidden),
members,
adminMembersById,
userStatusesById,

View File

@ -175,17 +175,21 @@
.dialog-buttons {
display: flex;
align-items: flex-end;
flex-direction: row-reverse;
justify-content: flex-start;
.confirm-dialog-button + .confirm-dialog-button {
margin-left: 1rem;
}
}
.dialog-checkbox {
margin: 1rem 0;
}
.confirm-dialog-button {
width: auto;
height: auto;
margin-left: auto;
text-align: right;
font-weight: 500;
white-space: pre-wrap;

View File

@ -1,5 +1,5 @@
.ShowMoreButton {
color: var(--text-color) !important;
color: var(--color-text) !important;
display: flex;
align-items: center;
text-align: left;

View File

@ -44,7 +44,7 @@ export const CUSTOM_EMOJI_PREVIEW_CACHE_DISABLED = false;
export const CUSTOM_EMOJI_PREVIEW_CACHE_NAME = 'tt-custom-emoji-preview';
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-v15';
export const LANG_CACHE_NAME = 'tt-lang-packs-v16';
export const ASSET_CACHE_NAME = 'tt-assets';
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];

View File

@ -559,17 +559,17 @@ addActionHandler('loadAttachBots', async (global, actions, payload) => {
});
addActionHandler('toggleAttachBot', async (global, actions, payload) => {
const { botId, isEnabled } = payload;
const { botId, isWriteAllowed, isEnabled } = payload;
const bot = selectUser(global, botId);
if (!bot) return;
await toggleAttachBot(bot, isEnabled);
await toggleAttachBot(bot, isEnabled, isWriteAllowed);
});
async function toggleAttachBot(bot: ApiUser, isEnabled: boolean) {
await callApi('toggleAttachBot', { bot, isEnabled });
async function toggleAttachBot(bot: ApiUser, isEnabled: boolean, isWriteAllowed?: boolean) {
await callApi('toggleAttachBot', { bot, isWriteAllowed, isEnabled });
await loadAttachBots();
}
@ -592,19 +592,16 @@ async function loadAttachBots(hash?: string) {
addActionHandler('callAttachBot', (global, actions, payload) => {
const {
chatId, botId, isFromBotMenu, url, startParam, threadId,
chatId, bot, isFromBotMenu, url, startParam, threadId,
} = payload;
const { attachMenu: { bots } } = global;
if (!isFromBotMenu && !bots[botId]) {
if (!isFromBotMenu && !global.attachMenu.bots[bot.id]) {
return {
...global,
requestedAttachBotInstall: {
botId,
bot,
onConfirm: {
action: 'callAttachBot',
payload: {
chatId, botId, startParam, threadId,
},
payload,
},
},
};
@ -614,7 +611,7 @@ addActionHandler('callAttachBot', (global, actions, payload) => {
actions.requestWebView({
url,
peerId: chatId,
botId,
botId: bot.id,
theme,
buttonText: '',
isFromBotMenu,
@ -624,23 +621,24 @@ addActionHandler('callAttachBot', (global, actions, payload) => {
return undefined;
});
addActionHandler('confirmAttachBotInstall', async (global) => {
addActionHandler('confirmAttachBotInstall', async (global, actions, payload) => {
const { requestedAttachBotInstall } = global;
const { isWriteAllowed } = payload;
const { botId, onConfirm } = requestedAttachBotInstall!;
const { bot, onConfirm } = requestedAttachBotInstall!;
setGlobal({
...global,
requestedAttachBotInstall: undefined,
});
const bot = selectUser(global, botId);
if (!bot) return;
const botUser = selectUser(global, bot.id);
if (!botUser) return;
await toggleAttachBot(bot, true);
await toggleAttachBot(botUser, true, isWriteAllowed);
if (onConfirm) {
const { action, payload } = onConfirm;
getActions()[action](payload);
const { action, payload: confirmPayload } = onConfirm;
actions[action](confirmPayload);
}
});
@ -652,20 +650,17 @@ addActionHandler('cancelAttachBotInstall', (global) => {
});
addActionHandler('requestAttachBotInChat', (global, actions, payload) => {
const { botId, filter, startParam } = payload;
const { bot, filter, startParam } = payload;
const currentChatId = selectCurrentMessageList(global)?.chatId;
const { attachMenu: { bots } } = global;
const bot = bots[botId];
if (!bot) return;
const supportedFilters = bot.peerTypes.filter((type): type is ApiChatType => (
type !== 'self' && filter.includes(type)
));
if (!supportedFilters.length) {
actions.callAttachBot({
chatId: currentChatId || botId,
botId,
chatId: currentChatId || bot.id,
bot,
startParam,
});
return;
@ -674,7 +669,7 @@ addActionHandler('requestAttachBotInChat', (global, actions, payload) => {
setGlobal({
...global,
requestedAttachBotInChat: {
botId,
bot,
filter: supportedFilters,
startParam,
},

View File

@ -1316,11 +1316,11 @@ addActionHandler('processAttachBotParameters', async (global, actions, payload)
setGlobal({
...global,
requestedAttachBotInstall: {
botId: bot.id,
bot,
onConfirm: {
action: 'requestAttachBotInChat',
payload: {
botId: bot.id,
bot,
filter,
startParam,
},
@ -1331,7 +1331,7 @@ addActionHandler('processAttachBotParameters', async (global, actions, payload)
}
getActions().requestAttachBotInChat({
botId: bot.id,
bot,
filter,
startParam,
});
@ -1424,6 +1424,37 @@ addActionHandler('toggleForum', async (global, actions, payload) => {
}
});
addActionHandler('toggleParticipantsHidden', async (global, actions, payload) => {
const { chatId, isEnabled } = payload;
const chat = selectChat(global, chatId);
if (!chat) {
return;
}
const prevIsEnabled = chat.fullInfo?.areParticipantsHidden;
global = updateChat(global, chatId, {
fullInfo: {
...chat.fullInfo,
areParticipantsHidden: isEnabled,
},
});
setGlobal(global);
const result = await callApi('toggleParticipantsHidden', { chat, isEnabled });
if (!result && prevIsEnabled !== undefined) {
global = getGlobal();
global = updateChat(global, chatId, {
fullInfo: {
...chat.fullInfo,
areParticipantsHidden: prevIsEnabled,
},
});
setGlobal(global);
}
});
addActionHandler('createTopic', async (global, actions, payload) => {
const {
chatId, title, iconColor, iconEmojiId,
@ -1922,12 +1953,22 @@ async function getAttachBotOrNotify(global: GlobalState, username: string) {
if (!user) return undefined;
const isBot = isUserBot(user);
if (!isBot || !user.isAttachBot) {
if (!isBot) return undefined;
const result = await callApi('loadAttachBot', {
bot: user,
});
global = getGlobal();
if (!result) {
getActions().showNotification({ message: langProvider.getTranslation('WebApp.AddToAttachmentUnavailableError') });
return undefined;
}
return user;
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
setGlobal(global);
return result.bot;
}
async function openChatByUsername(
@ -1949,7 +1990,7 @@ async function openChatByUsername(
if (!currentChat || !bot) return;
actions.callAttachBot({
botId: bot.id,
bot,
chatId: currentChat.id,
...(typeof startAttach === 'string' && { startParam: startAttach }),
});
@ -1991,18 +2032,15 @@ async function openChatByUsername(
async function openAttachMenuFromLink(
actions: GlobalActions,
chatId: string, attach: string, startAttach?: string | boolean,
chatId: string,
attach: string,
startAttach?: string | boolean,
) {
const botChat = await fetchChatByUsername(attach);
if (!botChat) return;
const botUser = selectUser(getGlobal(), botChat.id);
if (!botUser || !botUser.isAttachBot) {
actions.showNotification({ message: langProvider.getTranslation('WebApp.AddToAttachmentUnavailableError') });
return;
}
const bot = await getAttachBotOrNotify(getGlobal(), attach);
if (!bot) return;
actions.callAttachBot({
botId: botUser.id,
bot,
chatId,
...(typeof startAttach === 'string' && { startParam: startAttach }),
});

View File

@ -42,6 +42,11 @@ addActionHandler('apiUpdate', (global, actions, update) => {
return updateUser(global, update.id, update.user);
}
case 'updateRequestUserUpdate': {
actions.loadFullUser({ userId: update.id });
break;
}
case 'updateUserEmojiStatus': {
return updateUser(global, update.userId, { emojiStatus: update.emojiStatus });
}

View File

@ -139,11 +139,8 @@ export function selectLocalAnimatedEmojiEffectByName(name: string) {
return name === 'Cumshot' ? '🍆' : undefined;
}
export function selectIsDefaultEmojiStatusPack(global: GlobalState, stickerSet: ApiStickerSetInfo | ApiStickerSet) {
return 'id' in stickerSet && stickerSet.id === global.appConfig?.defaultEmojiStatusesStickerSetId;
}
export function selectIsAlwaysHighPriorityEmoji(global: GlobalState, stickerSet: ApiStickerSetInfo | ApiStickerSet) {
return selectIsDefaultEmojiStatusPack(global, stickerSet)
|| ('id' in stickerSet && stickerSet.id === RESTRICTED_EMOJI_SET_ID);
if (!('id' in stickerSet)) return false;
return stickerSet.id === global.appConfig?.defaultEmojiStatusesStickerSetId
|| stickerSet.id === RESTRICTED_EMOJI_SET_ID;
}

View File

@ -643,14 +643,14 @@ export type GlobalState = {
};
};
requestedAttachBotInstall?: {
botId: string;
bot: ApiAttachBot;
onConfirm?: {
action: keyof GlobalActions;
payload: any; // TODO Add TS support
};
};
requestedAttachBotInChat?: {
botId: string;
bot: ApiAttachBot;
filter: ApiChatType[];
startParam?: string;
};
@ -805,6 +805,11 @@ export interface ActionPayloads {
threadId: number;
};
toggleParticipantsHidden: {
chatId: string;
isEnabled: boolean;
};
// Messages
setEditingDraft: {
text?: ApiFormattedText;
@ -1131,7 +1136,9 @@ export interface ActionPayloads {
};
cancelAttachBotInstall: never;
confirmAttachBotInstall: never;
confirmAttachBotInstall: {
isWriteAllowed: boolean;
};
processAttachBotParameters: {
username: string;
@ -1139,7 +1146,7 @@ export interface ActionPayloads {
startParam?: string;
};
requestAttachBotInChat: {
botId: string;
bot: ApiAttachBot;
filter: ApiChatType[];
startParam?: string;
};
@ -1157,13 +1164,14 @@ export interface ActionPayloads {
toggleAttachBot: {
botId: string;
isWriteAllowed?: boolean;
isEnabled: boolean;
};
callAttachBot: {
chatId: string;
threadId?: number;
botId: string;
bot: ApiAttachBot;
isFromBotMenu?: boolean;
url?: string;
startParam?: string;

View File

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

File diff suppressed because one or more lines are too long

View File

@ -19,15 +19,15 @@ inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_na
inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile;
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
inputMediaEmpty#9664f57f = InputMedia;
inputMediaUploadedPhoto#1e287d04 flags:# file:InputFile stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaPhoto#b3ba0635 flags:# id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaDocument#33473058 flags:# id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaDocument#33473058 flags:# spoiler:flags.2?true id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaDocumentExternal#fb52dc99 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
inputMediaInvoice#8eb5a6d5 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
@ -66,7 +66,7 @@ storage.fileWebp#1081464c = storage.FileType;
userEmpty#d3bc4b7a id:long = User;
user#8f97c628 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
userStatusEmpty#9d05049 = UserStatus;
userStatusOnline#edb93949 expires:int = UserStatus;
userStatusOffline#8c703f was_online:int = UserStatus;
@ -79,7 +79,7 @@ chatForbidden#6592a1a7 id:long title:string = Chat;
channel#83259464 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector<Username> = Chat;
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull;
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
chatParticipantAdmin#a0933f5b user_id:long inviter_id:long date:int = ChatParticipant;
@ -91,11 +91,11 @@ messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message;
message#38116ee0 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia;
messageMediaUnsupported#9f84f49e = MessageMedia;
messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true spoiler:flags.4?true document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
messageMediaGame#fdb19008 game:Game = MessageMedia;
@ -138,6 +138,8 @@ messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
messageActionGiftPremium#aba0f5c6 currency:string amount:long months:int = MessageAction;
messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction;
messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction;
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
messageActionAttachMenuBotAllowed#e7e75f97 = MessageAction;
dialog#d58a08c6 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 ttl_period:flags.5?int = Dialog;
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
photoEmpty#2331b22d id:long = Photo;
@ -174,7 +176,7 @@ inputReportReasonGeoIrrelevant#dbd4feed = ReportReason;
inputReportReasonFake#f5ddd6e7 = ReportReason;
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
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<PremiumGiftOption> = UserFull;
userFull#f8d32aed 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 personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> = 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;
@ -219,7 +221,6 @@ updateChatUserTyping#83487af0 chat_id:long from_id:Peer action:SendMessageAction
updateChatParticipants#7761198 participants:ChatParticipants = Update;
updateUserStatus#e5bdf8de user_id:long status:UserStatus = Update;
updateUserName#a7848924 user_id:long first_name:string last_name:string usernames:Vector<Username> = Update;
updateUserPhoto#f227868c user_id:long date:int photo:UserProfilePhoto previous:Bool = Update;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
@ -320,6 +321,7 @@ updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?tru
updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = Update;
updateChannelPinnedTopic#192efbe3 flags:# pinned:flags.0?true channel_id:long topic_id:int = Update;
updateChannelPinnedTopics#fe198602 flags:# channel_id:long order:flags.0?Vector<int> = Update;
updateUser#20529438 user_id:long = 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;
@ -433,7 +435,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;
documentAttributeCustomEmoji#fd149899 flags:# free:flags.0?true text_color:flags.1?true alt:string stickerset:InputStickerSet = DocumentAttribute;
messages.stickersNotModified#f1749a22 = messages.Stickers;
messages.stickers#30a6ec7e hash:long stickers:Vector<Document> = messages.Stickers;
stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
@ -489,7 +491,7 @@ keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton;
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
replyKeyboardHide#a03e5b85 flags:# selective:flags.2?true = ReplyMarkup;
replyKeyboardForceReply#86b40b08 flags:# single_use:flags.1?true selective:flags.2?true placeholder:flags.3?string = ReplyMarkup;
replyKeyboardMarkup#85dd99d1 flags:# resize:flags.0?true single_use:flags.1?true selective:flags.2?true rows:Vector<KeyboardButtonRow> placeholder:flags.3?string = ReplyMarkup;
replyKeyboardMarkup#85dd99d1 flags:# resize:flags.0?true single_use:flags.1?true selective:flags.2?true persistent:flags.4?true rows:Vector<KeyboardButtonRow> placeholder:flags.3?string = ReplyMarkup;
replyInlineMarkup#48a30254 rows:Vector<KeyboardButtonRow> = ReplyMarkup;
messageEntityUnknown#bb92ba95 offset:int length:int = MessageEntity;
messageEntityMention#fa04579d offset:int length:int = MessageEntity;
@ -608,6 +610,7 @@ messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered>
stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered;
stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector<Document> = StickerSetCovered;
stickerSetFullCovered#40d13c0e set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = StickerSetCovered;
stickerSetNoCovered#77b15d1c set:StickerSet = StickerSetCovered;
maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;
inputStickeredMediaPhoto#4a992157 id:InputPhoto = InputStickeredMedia;
inputStickeredMediaDocument#438865b id:InputDocument = InputStickeredMedia;
@ -1005,7 +1008,7 @@ phone.groupCallStreamChannels#d0e482b2 channels:Vector<GroupCallStreamChannel> =
phone.groupCallStreamRtmpUrl#2dbf3432 url:string key:string = phone.GroupCallStreamRtmpUrl;
attachMenuBotIconColor#4576f3f0 name:string color:int = AttachMenuBotIconColor;
attachMenuBotIcon#b2a7386b flags:# name:string icon:Document colors:flags.0?Vector<AttachMenuBotIconColor> = AttachMenuBotIcon;
attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true has_settings:flags.1?true bot_id:long short_name:string peer_types:Vector<AttachMenuPeerType> icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true has_settings:flags.1?true request_write_access:flags.2?true bot_id:long short_name:string peer_types:Vector<AttachMenuPeerType> icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
attachMenuBotsNotModified#f1d88a5c = AttachMenuBots;
attachMenuBots#3c4301c0 hash:long bots:Vector<AttachMenuBot> users:Vector<User> = AttachMenuBots;
attachMenuBotsBot#93bf667f bot:AttachMenuBot users:Vector<User> = AttachMenuBotsBot;
@ -1243,7 +1246,7 @@ messages.getUnreadReactions#3223495b flags:# peer:InputPeer top_msg_id:flags.0?i
messages.readReactions#54aa7f8e flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool;
messages.requestWebView#178b480b flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = WebViewResult;
messages.prolongWebView#7ff34309 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = Bool;
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult;
@ -1257,8 +1260,8 @@ messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates;
updates.getState#edd4882a = updates.State;
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
photos.updateProfilePhoto#72d4742c id:InputPhoto = photos.Photo;
photos.uploadProfilePhoto#89f30f69 flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
photos.updateProfilePhoto#1c3d5956 flags:# fallback:flags.0?true id:InputPhoto = photos.Photo;
photos.uploadProfilePhoto#89f30f69 flags:# fallback:flags.3?true file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>;
photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos;
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
@ -1309,6 +1312,7 @@ channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector<int> = m
channels.editForumTopic#f4dfa185 flags:# channel:InputChannel topic_id:int title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = Updates;
channels.updatePinnedForumTopic#6c2d9026 channel:InputChannel topic_id:int pinned:Bool = Updates;
channels.deleteTopicHistory#34435f2d channel:InputChannel top_msg_id:int = messages.AffectedHistory;
channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates;
payments.getPaymentForm#37148dbb flags:# invoice:InputInvoice theme_params:flags.0?DataJSON = payments.PaymentForm;
payments.getPaymentReceipt#2478d1cc peer:InputPeer msg_id:int = payments.PaymentReceipt;
payments.validateRequestedInfo#b6c8f12b flags:# save:flags.0?true invoice:InputInvoice info:PaymentRequestedInfo = payments.ValidatedRequestedInfo;

View File

@ -270,5 +270,6 @@
"channels.getForumTopicsByID",
"channels.editForumTopic",
"channels.updatePinnedForumTopic",
"channels.deleteTopicHistory"
"channels.deleteTopicHistory",
"channels.toggleParticipantsHidden"
]

View File

@ -28,15 +28,15 @@ inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
inputMediaEmpty#9664f57f = InputMedia;
inputMediaUploadedPhoto#1e287d04 flags:# file:InputFile stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaPhoto#b3ba0635 flags:# id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaDocument#33473058 flags:# id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaDocument#33473058 flags:# spoiler:flags.2?true id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaDocumentExternal#fb52dc99 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
inputMediaInvoice#8eb5a6d5 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
@ -83,7 +83,7 @@ userEmpty#d3bc4b7a id:long = User;
user#8f97c628 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
userStatusEmpty#9d05049 = UserStatus;
userStatusOnline#edb93949 expires:int = UserStatus;
@ -99,7 +99,7 @@ channel#83259464 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull;
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
@ -116,11 +116,11 @@ message#38116ee0 flags:# out:flags.1?true mentioned:flags.4?true media_unread:fl
messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia;
messageMediaUnsupported#9f84f49e = MessageMedia;
messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true spoiler:flags.4?true document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
messageMediaGame#fdb19008 game:Game = MessageMedia;
@ -164,6 +164,8 @@ messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
messageActionGiftPremium#aba0f5c6 currency:string amount:long months:int = MessageAction;
messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction;
messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction;
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
messageActionAttachMenuBotAllowed#e7e75f97 = MessageAction;
dialog#d58a08c6 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 ttl_period:flags.5?int = Dialog;
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
@ -214,7 +216,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason;
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
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<PremiumGiftOption> = UserFull;
userFull#f8d32aed 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 personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> = UserFull;
contact#145ade0b user_id:long mutual:Bool = Contact;
@ -272,7 +274,6 @@ updateChatUserTyping#83487af0 chat_id:long from_id:Peer action:SendMessageAction
updateChatParticipants#7761198 participants:ChatParticipants = Update;
updateUserStatus#e5bdf8de user_id:long status:UserStatus = Update;
updateUserName#a7848924 user_id:long first_name:string last_name:string usernames:Vector<Username> = Update;
updateUserPhoto#f227868c user_id:long date:int photo:UserProfilePhoto previous:Bool = Update;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
@ -373,6 +374,7 @@ updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?tru
updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = Update;
updateChannelPinnedTopic#192efbe3 flags:# pinned:flags.0?true channel_id:long topic_id:int = Update;
updateChannelPinnedTopics#fe198602 flags:# channel_id:long order:flags.0?Vector<int> = Update;
updateUser#20529438 user_id:long = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -517,7 +519,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;
documentAttributeCustomEmoji#fd149899 flags:# free:flags.0?true text_color:flags.1?true alt:string stickerset:InputStickerSet = DocumentAttribute;
messages.stickersNotModified#f1749a22 = messages.Stickers;
messages.stickers#30a6ec7e hash:long stickers:Vector<Document> = messages.Stickers;
@ -595,7 +597,7 @@ keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
replyKeyboardHide#a03e5b85 flags:# selective:flags.2?true = ReplyMarkup;
replyKeyboardForceReply#86b40b08 flags:# single_use:flags.1?true selective:flags.2?true placeholder:flags.3?string = ReplyMarkup;
replyKeyboardMarkup#85dd99d1 flags:# resize:flags.0?true single_use:flags.1?true selective:flags.2?true rows:Vector<KeyboardButtonRow> placeholder:flags.3?string = ReplyMarkup;
replyKeyboardMarkup#85dd99d1 flags:# resize:flags.0?true single_use:flags.1?true selective:flags.2?true persistent:flags.4?true rows:Vector<KeyboardButtonRow> placeholder:flags.3?string = ReplyMarkup;
replyInlineMarkup#48a30254 rows:Vector<KeyboardButtonRow> = ReplyMarkup;
messageEntityUnknown#bb92ba95 offset:int length:int = MessageEntity;
@ -750,6 +752,7 @@ messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered>
stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered;
stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector<Document> = StickerSetCovered;
stickerSetFullCovered#40d13c0e set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = StickerSetCovered;
stickerSetNoCovered#77b15d1c set:StickerSet = StickerSetCovered;
maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;
@ -1349,7 +1352,7 @@ attachMenuBotIconColor#4576f3f0 name:string color:int = AttachMenuBotIconColor;
attachMenuBotIcon#b2a7386b flags:# name:string icon:Document colors:flags.0?Vector<AttachMenuBotIconColor> = AttachMenuBotIcon;
attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true has_settings:flags.1?true bot_id:long short_name:string peer_types:Vector<AttachMenuPeerType> icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true has_settings:flags.1?true request_write_access:flags.2?true bot_id:long short_name:string peer_types:Vector<AttachMenuPeerType> icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
attachMenuBotsNotModified#f1d88a5c = AttachMenuBots;
attachMenuBots#3c4301c0 hash:long bots:Vector<AttachMenuBot> users:Vector<User> = AttachMenuBots;
@ -1751,7 +1754,7 @@ messages.readReactions#54aa7f8e flags:# peer:InputPeer top_msg_id:flags.0?int =
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool;
messages.requestWebView#178b480b flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = WebViewResult;
messages.prolongWebView#7ff34309 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = Bool;
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult;
@ -1774,10 +1777,11 @@ updates.getState#edd4882a = updates.State;
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
photos.updateProfilePhoto#72d4742c id:InputPhoto = photos.Photo;
photos.uploadProfilePhoto#89f30f69 flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
photos.updateProfilePhoto#1c3d5956 flags:# fallback:flags.0?true id:InputPhoto = photos.Photo;
photos.uploadProfilePhoto#89f30f69 flags:# fallback:flags.3?true file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>;
photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos;
photos.uploadContactProfilePhoto#b91a83bf flags:# suggest:flags.3?true save:flags.4?true user_id:InputUser file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
upload.getFile#be5335be flags:# precise:flags.0?true cdn_supported:flags.1?true location:InputFileLocation offset:long limit:int = upload.File;
@ -1866,6 +1870,7 @@ channels.deleteTopicHistory#34435f2d channel:InputChannel top_msg_id:int = messa
channels.reorderPinnedForumTopics#2950a18f flags:# force:flags.0?true channel:InputChannel order:Vector<int> = Updates;
channels.toggleAntiSpam#68f3e4eb channel:InputChannel enabled:Bool = Updates;
channels.reportAntiSpamFalsePositive#a850a693 channel:InputChannel msg_id:int = Bool;
channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates;
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
@ -1944,4 +1949,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
// LAYER 150
// LAYER 151

View File

@ -219,7 +219,8 @@ export enum SettingsScreens {
}
export type StickerSetOrRecent = Pick<ApiStickerSet, (
'id' | 'title' | 'count' | 'stickers' | 'hasThumbnail' | 'isLottie' | 'isVideos' | 'isEmoji' | 'installedDate'
'id' | 'accessHash' | 'title' | 'count' | 'stickers' | 'hasThumbnail' | 'isLottie' | 'isVideos' | 'isEmoji' |
'installedDate'
)>;
export enum LeftColumnContent {