Various features from Layer 177 (#4447)

This commit is contained in:
Alexander Zinchuk 2024-04-19 13:37:58 +04:00
parent db1d7ceea0
commit b69e2b8d0f
54 changed files with 1402 additions and 461 deletions

View File

@ -72,6 +72,7 @@ export interface GramJsAppConfig extends LimitsConfig {
stories_changelog_user_id?: number;
// Boosts
group_transcribe_level_min?: number;
new_noncontact_peers_require_premium_without_ownpremium?: boolean;
}
function buildEmojiSounds(appConfig: GramJsAppConfig) {
@ -145,5 +146,6 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp
storyViewersExpirePeriod: appConfig.story_viewers_expire_period ?? STORY_VIEWERS_EXPIRE_PERIOD,
storyChangelogUserId: appConfig.stories_changelog_user_id?.toString() ?? SERVICE_NOTIFICATIONS_USER_ID,
groupTranscribeLevelMin: appConfig.group_transcribe_level_min,
canLimitNewMessagesWithoutPremium: appConfig.new_noncontact_peers_require_premium_without_ownpremium,
};
}

View File

@ -0,0 +1,42 @@
import type { Api as GramJs } from '../../../lib/gramjs';
import type { ApiBusinessIntro, ApiBusinessLocation, ApiBusinessWorkHours } from '../../types';
import { buildGeoPoint } from './messageContent';
import { buildStickerFromDocument } from './symbols';
export function buildApiBusinessLocation(location: GramJs.TypeBusinessLocation): ApiBusinessLocation {
const {
address, geoPoint,
} = location;
return {
address,
geo: geoPoint && buildGeoPoint(geoPoint),
};
}
export function buildApiBusinessWorkHours(workHours: GramJs.TypeBusinessWorkHours): ApiBusinessWorkHours {
const {
timezoneId, weeklyOpen,
} = workHours;
return {
timezoneId,
workHours: weeklyOpen.map(({ startMinute, endMinute }) => ({
startMinute,
endMinute,
})),
};
}
export function buildApiBusinessIntro(intro: GramJs.TypeBusinessIntro): ApiBusinessIntro {
const {
title, description, sticker,
} = intro;
return {
title,
description,
sticker: sticker && buildStickerFromDocument(sticker),
};
}

View File

@ -14,6 +14,7 @@ import type {
ApiChatReactions,
ApiChatSettings,
ApiExportedInvite,
ApiMissingInvitedUser,
ApiRestrictionReason,
ApiSendAsPeerId,
ApiTopic,
@ -634,3 +635,13 @@ export function buildApiChatlistExportedInvite(
peerIds: peers.map(getApiChatIdFromMtpPeer).filter(Boolean),
};
}
export function buildApiMissingInvitedUser(
user: GramJs.TypeMissingInvitee,
): ApiMissingInvitedUser {
return {
id: user.userId.toString(),
isRequiringPremiumToMessage: user.premiumRequiredForPm,
isRequiringPremiumToInvite: user.premiumWouldAllowInvite,
};
}

View File

@ -154,6 +154,7 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
let allowChatIds: string[] | undefined;
let blockUserIds: string[] | undefined;
let blockChatIds: string[] | undefined;
let shouldAllowPremium: true | undefined;
const localChats = localDb.chats;
@ -187,6 +188,8 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
if (localChats[dialogId]) return dialogId;
return channelId;
});
} else if (rule instanceof GramJs.PrivacyValueAllowPremium) {
shouldAllowPremium = true;
}
});
@ -203,6 +206,7 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
allowChatIds: allowChatIds || [],
blockUserIds: blockUserIds || [],
blockChatIds: blockChatIds || [],
shouldAllowPremium,
};
}

View File

@ -160,7 +160,7 @@ export type UniversalMessage = (
'out' | 'message' | 'entities' | 'fromId' | 'peerId' | 'fwdFrom' | 'replyTo' | 'replyMarkup' | 'post' |
'media' | 'action' | 'views' | 'editDate' | 'editHide' | 'mediaUnread' | 'groupedId' | 'mentioned' | 'viaBotId' |
'replies' | 'fromScheduled' | 'postAuthor' | 'noforwards' | 'reactions' | 'forwards' | 'silent' | 'pinned' |
'savedPeerId' | 'fromBoostsApplied' | 'quickReplyShortcutId'
'savedPeerId' | 'fromBoostsApplied' | 'quickReplyShortcutId' | 'viaBusinessBotId'
)>
);
@ -240,6 +240,7 @@ export function buildApiMessageWithChatId(
hasComments,
savedPeerId,
senderBoosts,
viaBusinessBotId: mtpMessage.viaBusinessBotId?.toString(),
});
}

View File

@ -22,13 +22,7 @@ export function buildStickerFromDocument(document: GramJs.TypeDocument, isNoPrem
const customEmojiAttribute = document.attributes
.find((attr): attr is GramJs.DocumentAttributeCustomEmoji => attr instanceof GramJs.DocumentAttributeCustomEmoji);
const fileAttribute = (mimeType === LOTTIE_STICKER_MIME_TYPE || mimeType === VIDEO_STICKER_MIME_TYPE)
&& document.attributes
.find((attr: any): attr is GramJs.DocumentAttributeFilename => (
attr instanceof GramJs.DocumentAttributeFilename
));
if (!(stickerAttribute || customEmojiAttribute) && !fileAttribute) {
if (!(stickerAttribute || customEmojiAttribute)) {
return undefined;
}
@ -104,9 +98,7 @@ export function buildStickerFromDocument(document: GramJs.TypeDocument, isNoPrem
export function buildStickerSet(set: GramJs.StickerSet): ApiStickerSet {
const {
archived,
animated,
installedDate,
videos,
id,
accessHash,
title,
@ -117,17 +109,25 @@ export function buildStickerSet(set: GramJs.StickerSet): ApiStickerSet {
thumbDocumentId,
} = set;
const hasStaticThumb = thumbs?.some((thumb) => thumb.type === 's');
const hasAnimatedThumb = thumbs?.some((thumb) => thumb.type === 'a');
const hasVideoThumb = thumbs?.some((thumb) => thumb.type === 'v');
const thumbCustomEmojiId = thumbDocumentId && String(thumbDocumentId);
const hasThumbnail = hasStaticThumb || hasAnimatedThumb || hasVideoThumb || Boolean(thumbCustomEmojiId);
return {
isArchived: archived,
isLottie: animated,
isVideos: videos,
isEmoji: emojis,
installedDate,
id: String(id),
accessHash: String(accessHash),
title,
hasThumbnail: Boolean(thumbs?.length || thumbDocumentId),
thumbCustomEmojiId: thumbDocumentId?.toString(),
hasStaticThumb,
hasAnimatedThumb,
hasVideoThumb,
hasThumbnail,
thumbCustomEmojiId,
count,
shortName,
};

View File

@ -1,8 +1,6 @@
import { Api as GramJs } from '../../../lib/gramjs';
import type {
ApiBusinessLocation,
ApiBusinessWorkHours,
ApiPremiumGiftOption,
ApiUser,
ApiUserFullInfo,
@ -12,8 +10,8 @@ import type {
import { omitUndefined } from '../../../util/iteratees';
import { buildApiBotInfo } from './bots';
import { buildApiBusinessIntro, buildApiBusinessLocation, buildApiBusinessWorkHours } from './business';
import { buildApiPhoto, buildApiUsernames } from './common';
import { buildGeoPoint } from './messageContent';
import { buildApiEmojiStatus, buildApiPeerColor, buildApiPeerId } from './peers';
export function buildApiUserFullInfo(mtpUserFull: GramJs.users.UserFull): ApiUserFullInfo {
@ -22,7 +20,8 @@ export function buildApiUserFullInfo(mtpUserFull: GramJs.users.UserFull): ApiUse
about, commonChatsCount, pinnedMsgId, botInfo, blocked,
profilePhoto, voiceMessagesForbidden, premiumGifts,
fallbackPhoto, personalPhoto, translationsDisabled, storiesPinnedAvailable,
contactRequirePremium, businessWorkHours, businessLocation,
contactRequirePremium, businessWorkHours, businessLocation, businessIntro,
personalChannelId, personalChannelMessage,
},
users,
} = mtpUserFull;
@ -45,6 +44,9 @@ export function buildApiUserFullInfo(mtpUserFull: GramJs.users.UserFull): ApiUse
isContactRequirePremium: contactRequirePremium,
businessLocation: businessLocation && buildApiBusinessLocation(businessLocation),
businessWorkHours: businessWorkHours && buildApiBusinessWorkHours(businessWorkHours),
businessIntro: businessIntro && buildApiBusinessIntro(businessIntro),
personalChannelId: personalChannelId && buildApiPeerId(personalChannelId, 'channel'),
personalChannelMessageId: personalChannelMessage,
});
}
@ -159,28 +161,3 @@ export function buildApiPremiumGiftOption(option: GramJs.TypePremiumGiftOption):
botUrl,
};
}
export function buildApiBusinessLocation(location: GramJs.TypeBusinessLocation): ApiBusinessLocation {
const {
address, geoPoint,
} = location;
return {
address,
geo: geoPoint && buildGeoPoint(geoPoint),
};
}
export function buildApiBusinessWorkHours(workHours: GramJs.TypeBusinessWorkHours): ApiBusinessWorkHours {
const {
timezoneId, weeklyOpen,
} = workHours;
return {
timezoneId,
workHours: weeklyOpen.map(({ startMinute, endMinute }) => ({
startMinute,
endMinute,
})),
};
}

View File

@ -749,6 +749,9 @@ export function buildInputPrivacyRules(
)),
}));
}
if (rules.shouldAllowPremium) {
privacyRules.push(new GramJs.InputPrivacyValueAllowPremium());
}
if (!rules.isUnspecified) {
switch (rules.visibility) {

View File

@ -11,6 +11,7 @@ import type {
ApiChatReactions,
ApiGroupCall,
ApiMessage,
ApiMissingInvitedUser,
ApiPeer,
ApiPhoto,
ApiTopic,
@ -42,6 +43,7 @@ import {
buildApiChatlistInvite,
buildApiChatReactions,
buildApiChatSettings,
buildApiMissingInvitedUser,
buildApiTopic,
buildChatMembers,
getPeerKey,
@ -73,10 +75,10 @@ import {
import localDb from '../localDb';
import { scheduleMutedChatUpdate } from '../scheduleUnmute';
import {
applyState, processAffectedHistory, processUpdate, updateChannelState,
applyState, processAffectedHistory, updateChannelState,
} from '../updates/updateManager';
import { dispatchThreadInfoUpdates } from '../updates/updater';
import { invokeRequest, uploadFile } from './client';
import { handleGramJsUpdate, invokeRequest, uploadFile } from './client';
type FullChatData = {
fullInfo: ApiChatFullInfo;
@ -782,36 +784,20 @@ export async function createChannel({
const channel = buildApiChatFromPreview(newChannel)!;
let restrictedUserIds: string[] | undefined;
let missingUsers: ApiMissingInvitedUser[] | undefined;
if (users?.length) {
try {
const updates = await invokeRequest(new GramJs.channels.InviteToChannel({
channel: buildInputEntity(channel.id, channel.accessHash) as GramJs.InputChannel,
users: users.map(({ id, accessHash }) => buildInputEntity(id, accessHash)) as GramJs.InputUser[],
}), {
shouldIgnoreUpdates: true,
shouldThrow: true,
});
if (updates) {
processUpdate(updates);
restrictedUserIds = handleUserPrivacyRestrictedUpdates(updates);
}
} catch (err) {
if ((err as Error).message === 'USER_PRIVACY_RESTRICTED') {
restrictedUserIds = users.map(({ id }) => id);
} else {
onUpdate({
'@type': 'error',
error: {
message: (err as Error).message,
},
});
}
}
const invitedUsers = await invokeRequest(new GramJs.channels.InviteToChannel({
channel: buildInputEntity(channel.id, channel.accessHash) as GramJs.InputChannel,
users: users.map(({ id, accessHash }) => buildInputEntity(id, accessHash)) as GramJs.InputUser[],
}));
if (!invitedUsers) return undefined;
handleGramJsUpdate(invitedUsers.updates);
missingUsers = invitedUsers.missingInvitees.map(buildApiMissingInvitedUser);
}
return { channel, restrictedUserIds };
return { channel, missingUsers };
}
export function joinChannel({
@ -882,37 +868,25 @@ export async function createGroupChat({
}: {
title: string; users: ApiUser[];
}) {
const result = await invokeRequest(new GramJs.messages.CreateChat({
const invitedUsers = await invokeRequest(new GramJs.messages.CreateChat({
title,
users: users.map(({ id, accessHash }) => buildInputEntity(id, accessHash)) as GramJs.InputUser[],
}), {
shouldIgnoreUpdates: true,
shouldThrow: true,
});
}));
if (!invitedUsers) return undefined;
// `createChat` can return a lot of different update types according to docs,
// but currently chat creation returns only `Updates` type.
// Errors are added to catch unexpected cases in future testing
if (!(result instanceof GramJs.Updates)) {
if (DEBUG) {
// eslint-disable-next-line no-console
console.error('Unexpected chat creation update', result);
}
return undefined;
}
processUpdate(result);
const restrictedUserIds = handleUserPrivacyRestrictedUpdates(result);
handleGramJsUpdate(invitedUsers.updates);
const missingUsers = invitedUsers.missingInvitees.map(buildApiMissingInvitedUser);
const newChat = result.chats[0];
const newChat = (invitedUsers.updates as GramJs.Updates).chats[0];
if (!newChat || !(newChat instanceof GramJs.Chat)) {
if (DEBUG) {
// eslint-disable-next-line no-console
console.error('Created chat not found', result);
console.error('Created chat not found', invitedUsers.updates);
}
return undefined;
}
return { chat: buildApiChatFromPreview(newChat), restrictedUserIds };
return { chat: buildApiChatFromPreview(newChat), missingUsers };
}
export async function editChatPhoto({
@ -1437,48 +1411,24 @@ export async function openChatByInvite(hash: string) {
export async function addChatMembers(chat: ApiChat, users: ApiUser[]) {
try {
if (chat.type === 'chatTypeChannel' || chat.type === 'chatTypeSuperGroup') {
try {
const updates = await invokeRequest(new GramJs.channels.InviteToChannel({
channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel,
users: users.map((user) => buildInputEntity(user.id, user.accessHash)) as GramJs.InputUser[],
}), {
shouldIgnoreUpdates: true,
shouldThrow: true,
});
if (!updates) {
return undefined;
}
processUpdate(updates);
return handleUserPrivacyRestrictedUpdates(updates);
} catch (err) {
if ((err as Error).message === 'USER_PRIVACY_RESTRICTED') {
return users.map(({ id }) => id);
}
throw err;
}
const invitedUsers = await invokeRequest(new GramJs.channels.InviteToChannel({
channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel,
users: users.map((user) => buildInputEntity(user.id, user.accessHash)) as GramJs.InputUser[],
}));
if (!invitedUsers) return undefined;
handleGramJsUpdate(invitedUsers.updates);
return invitedUsers.missingInvitees.map(buildApiMissingInvitedUser);
}
const addChatUsersResult = await Promise.all(
users.map(async (user) => {
try {
const updates = await invokeRequest(new GramJs.messages.AddChatUser({
chatId: buildInputEntity(chat.id) as BigInt.BigInteger,
userId: buildInputEntity(user.id, user.accessHash) as GramJs.InputUser,
}), {
shouldIgnoreUpdates: true,
shouldThrow: true,
});
if (updates) {
processUpdate(updates);
return handleUserPrivacyRestrictedUpdates(updates);
}
return undefined;
} catch (err) {
if ((err as Error).message === 'USER_PRIVACY_RESTRICTED') {
return [user.id];
}
throw err;
}
const invitedUsers = await invokeRequest(new GramJs.messages.AddChatUser({
chatId: buildInputEntity(chat.id) as BigInt.BigInteger,
userId: buildInputEntity(user.id, user.accessHash) as GramJs.InputUser,
}));
if (!invitedUsers) return undefined;
handleGramJsUpdate(invitedUsers.updates);
return invitedUsers.missingInvitees.map(buildApiMissingInvitedUser);
}),
);
if (addChatUsersResult) {
@ -2066,24 +2016,3 @@ export async function fetchChannelRecommendations({ chat }: { chat: ApiChat }) {
result instanceof GramJs.messages.ChatsSlice ? result.count : undefined,
};
}
function handleUserPrivacyRestrictedUpdates(updates: GramJs.TypeUpdates) {
if (!(updates instanceof GramJs.Updates) && !(updates instanceof GramJs.UpdatesCombined)) {
return undefined;
}
const eligibleUpdates = updates
.updates
.filter(
(u): u is GramJs.UpdateGroupInvitePrivacyForbidden => {
return u instanceof GramJs.UpdateGroupInvitePrivacyForbidden;
},
);
if (eligibleUpdates.length === 0) {
return undefined;
}
return eligibleUpdates
.map((u) => buildApiPeerId(u.userId, 'user'));
}

View File

@ -171,7 +171,7 @@ async function download(
mimeType = 'image/jpeg';
}
} else if (entityType === 'sticker' && sizeType) {
mimeType = 'image/webp';
mimeType = (entity as GramJs.Document).mimeType;
} else if (entityType === 'webDocument') {
mimeType = (entity as GramJs.TypeWebDocument).mimeType;
fullSize = (entity as GramJs.TypeWebDocument).size;
@ -221,12 +221,6 @@ function getMessageMediaMimeType(message: GramJs.Message, sizeType?: string) {
if (message.media instanceof GramJs.MessageMediaDocument) {
const document = message.media.document;
if (document instanceof GramJs.Document) {
if (sizeType) {
return document.attributes.some((a) => a instanceof GramJs.DocumentAttributeSticker)
? 'image/webp'
: 'image/jpeg';
}
return document.mimeType;
}
}

View File

@ -1958,9 +1958,20 @@ export async function sendQuickReply({
chat: ApiChat;
shortcutId: number;
}) {
// Remove this request when the client fully supports quick replies and caches them
const messages = await invokeRequest(new GramJs.messages.GetQuickReplyMessages({
shortcutId,
}));
if (!messages || messages instanceof GramJs.messages.MessagesNotModified) return;
const ids = messages.messages.map((m) => m.id);
const randomIds = ids.map(generateRandomBigInt);
const result = await invokeRequest(new GramJs.messages.SendQuickReplyMessages({
peer: buildInputPeer(chat.id, chat.accessHash),
shortcutId,
id: ids,
randomId: randomIds,
}), {
shouldIgnoreUpdates: true,
});

View File

@ -30,7 +30,7 @@ import {
serializeBytes,
} from '../helpers';
import localDb from '../localDb';
import { invokeRequest } from './client';
import { handleGramJsUpdate, invokeRequest } from './client';
import { getTemporaryPaymentPassword } from './twoFaSettings';
let onUpdate: OnApiUpdate;
@ -108,6 +108,8 @@ export async function sendPaymentForm({
...(tipAmount && { tipAmount: BigInt(tipAmount) }),
}));
if (!result) return false;
if (result instanceof GramJs.payments.PaymentVerificationNeeded) {
onUpdate({
'@type': 'updatePaymentVerificationNeeded',
@ -115,6 +117,8 @@ export async function sendPaymentForm({
});
return undefined;
} else {
handleGramJsUpdate(result.updates);
}
return Boolean(result);

View File

@ -50,6 +50,7 @@ export async function fetchFullUser({
updateLocalDb(result);
addEntitiesToLocalDb(result.users);
addEntitiesToLocalDb(result.chats);
if (result.fullUser.profilePhoto instanceof GramJs.Photo) {
localDb.photos[result.fullUser.profilePhoto.id.toString()] = result.fullUser.profilePhoto;
@ -71,8 +72,15 @@ export async function fetchFullUser({
localDb.documents[botInfo.descriptionDocument.id.toString()] = botInfo.descriptionDocument;
}
if (result.fullUser.businessIntro?.sticker instanceof GramJs.Document) {
localDb.documents[result.fullUser.businessIntro.sticker.id.toString()] = result.fullUser.businessIntro.sticker;
}
const fullInfo = buildApiUserFullInfo(result);
const user = buildApiUser(result.users[0])!;
const users = result.users.map(buildApiUser).filter(Boolean);
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
const user = users.find(({ id: userId }) => userId === id)!;
onUpdate({
'@type': 'updateUser',
@ -84,7 +92,12 @@ export async function fetchFullUser({
fullInfo,
});
return { user, fullInfo };
return {
user,
fullInfo,
users,
chats,
};
}
export async function fetchCommonChats(id: string, accessHash?: string, maxId?: string) {

22
src/api/types/business.ts Normal file
View File

@ -0,0 +1,22 @@
import type { ApiGeoPoint, ApiSticker } from './messages';
export interface ApiBusinessLocation {
geo?: ApiGeoPoint;
address: string;
}
export interface ApiBusinessTimetableSegment {
startMinute: number;
endMinute: number;
}
export interface ApiBusinessWorkHours {
timezoneId: string;
workHours: ApiBusinessTimetableSegment[];
}
export interface ApiBusinessIntro {
title: string;
description: string;
sticker?: ApiSticker;
}

View File

@ -278,3 +278,9 @@ export interface ApiPeerColor {
color?: number;
backgroundEmojiId?: string;
}
export interface ApiMissingInvitedUser {
id: string;
isRequiringPremiumToInvite?: boolean;
isRequiringPremiumToMessage?: boolean;
}

View File

@ -10,3 +10,4 @@ export * from './misc';
export * from './calls';
export * from './statistics';
export * from './stories';
export * from './business';

View File

@ -52,14 +52,15 @@ export interface ApiSticker {
export interface ApiStickerSet {
isArchived?: true;
isLottie?: true;
isVideos?: true;
isEmoji?: true;
installedDate?: number;
id: string;
accessHash: string;
title: string;
hasThumbnail?: boolean;
hasStaticThumb?: boolean;
hasAnimatedThumb?: boolean;
hasVideoThumb?: boolean;
thumbCustomEmojiId?: string;
count: number;
stickers?: ApiSticker[];
@ -564,6 +565,7 @@ export interface ApiMessage {
isKeyboardSingleUse?: boolean;
isKeyboardSelective?: boolean;
viaBotId?: string;
viaBusinessBotId?: string;
postAuthorTitle?: string;
isScheduled?: boolean;
shouldHideKeyboardButtons?: boolean;

View File

@ -203,6 +203,7 @@ export interface ApiAppConfig {
storyViewersExpirePeriod: number;
storyChangelogUserId: string;
groupTranscribeLevelMin?: number;
canLimitNewMessagesWithoutPremium?: boolean;
}
export interface ApiConfig {

View File

@ -1,7 +1,8 @@
import type { API_CHAT_TYPES } from '../../config';
import type { ApiBotInfo } from './bots';
import type { ApiBusinessIntro, ApiBusinessLocation, ApiBusinessWorkHours } from './business';
import type { ApiPeerColor } from './chats';
import type { ApiDocument, ApiGeoPoint, ApiPhoto } from './messages';
import type { ApiDocument, ApiPhoto } from './messages';
export interface ApiUser {
id: string;
@ -54,8 +55,11 @@ export interface ApiUserFullInfo {
isTranslationDisabled?: true;
hasPinnedStories?: boolean;
isContactRequirePremium?: boolean;
personalChannelId?: string;
personalChannelMessageId?: number;
businessLocation?: ApiBusinessLocation;
businessWorkHours?: ApiBusinessWorkHours;
businessIntro?: ApiBusinessIntro;
}
export type ApiFakeType = 'fake' | 'scam';
@ -115,18 +119,3 @@ export interface ApiEmojiStatus {
documentId: string;
until?: number;
}
export interface ApiBusinessLocation {
geo?: ApiGeoPoint;
address: string;
}
export interface ApiBusinessTimetableSegment {
startMinute: number;
endMinute: number;
}
export interface ApiBusinessWorkHours {
timezoneId: string;
workHours: ApiBusinessTimetableSegment[];
}

View File

@ -0,0 +1,38 @@
.businessLocation {
width: 4rem;
height: 4rem;
object-fit: cover;
border-radius: 0.25rem;
flex-shrink: 0;
margin-inline-start: 0.25rem;
}
.personalChannel {
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: auto auto;
column-gap: 0.5rem;
margin-bottom: 0.5rem;
}
.personalChannelTitle {
grid-column: 1;
grid-row: 1;
color: var(--color-text-secondary);
font-size: 0.875rem;
margin-inline-start: 0.5rem;
margin-bottom: 0;
}
.personalChannelSubscribers {
grid-column: 2;
grid-row: 1;
color: var(--color-text-secondary);
font-size: 0.875rem;
margin-inline-end: 0.5rem;
}
.personalChannelItem {
grid-column: 1 / span 2;
grid-row: 2;
}

View File

@ -32,6 +32,7 @@ import { copyTextToClipboard } from '../../util/clipboard';
import { formatPhoneNumberWithCode } from '../../util/phoneNumber';
import { debounce } from '../../util/schedulers';
import stopEvent from '../../util/stopEvent';
import { ChatAnimationTypes } from '../left/main/hooks';
import renderText from './helpers/renderText';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
@ -40,11 +41,14 @@ import useLastCallback from '../../hooks/useLastCallback';
import useMedia from '../../hooks/useMedia';
import useDevicePixelRatio from '../../hooks/window/useDevicePixelRatio';
import Chat from '../left/main/Chat';
import ListItem from '../ui/ListItem';
import Skeleton from '../ui/placeholder/Skeleton';
import Switcher from '../ui/Switcher';
import BusinessHours from './BusinessHours';
import styles from './ChatExtra.module.scss';
type OwnProps = {
chatOrUserId: string;
isSavedDialog?: boolean;
@ -63,6 +67,7 @@ type StateProps = {
chatInviteLink?: string;
topicLink?: string;
hasSavedMessages?: boolean;
personalChannel?: ApiChat;
};
const DEFAULT_MAP_CONFIG = {
@ -87,6 +92,7 @@ const ChatExtra: FC<OwnProps & StateProps> = ({
chatInviteLink,
topicLink,
hasSavedMessages,
personalChannel,
}) => {
const {
showNotification,
@ -105,7 +111,11 @@ const ChatExtra: FC<OwnProps & StateProps> = ({
} = user || {};
const { id: chatId, usernames: chatUsernames } = chat || {};
const peerId = userId || chatId;
const { businessLocation, businessWorkHours } = userFullInfo || {};
const {
businessLocation,
businessWorkHours,
personalChannelMessageId,
} = userFullInfo || {};
const lang = useLang();
const [areNotificationsEnabled, setAreNotificationsEnabled] = useState(!isMuted);
@ -261,6 +271,22 @@ const ChatExtra: FC<OwnProps & StateProps> = ({
return (
<div className="ChatExtra">
{personalChannel && (
<div className={styles.personalChannel}>
<h3 className={styles.personalChannelTitle}>{lang('ProfileChannel')}</h3>
<span className={styles.personalChannelSubscribers}>
{lang('Subscribers', personalChannel.membersCount, 'i')}
</span>
<Chat
chatId={personalChannel.id}
orderDiff={0}
animationType={ChatAnimationTypes.None}
isPreview
previewMessageId={personalChannelMessageId}
className={styles.personalChannelItem}
/>
</div>
)}
{formattedNumber && Boolean(formattedNumber.length) && (
// eslint-disable-next-line react/jsx-no-bind
<ListItem icon="phone" multiline narrow ripple onClick={() => copy(formattedNumber, lang('Phone'))}>
@ -365,6 +391,10 @@ export default memo(withGlobal<OwnProps>(
const hasSavedMessages = !isSavedDialog && global.chats.listIds.saved?.includes(chatOrUserId);
const personalChannel = userFullInfo?.personalChannelId
? selectChat(global, userFullInfo.personalChannelId)
: undefined;
return {
phoneCodeList,
chat,
@ -377,6 +407,7 @@ export default memo(withGlobal<OwnProps>(
description,
topicLink,
hasSavedMessages,
personalChannel,
};
},
)(ChatExtra));

View File

@ -56,6 +56,7 @@ type StateProps =
self?: ApiUser;
isSavedMessages?: boolean;
areMessagesLoaded: boolean;
isSynced?: boolean;
};
const PrivateChatInfo: FC<OwnProps & StateProps> = ({
@ -83,6 +84,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
ripple,
className,
storyViewerOrigin,
isSynced,
onEmojiStatusClick,
}) => {
const {
@ -97,10 +99,10 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
useEffect(() => {
if (userId) {
if (withFullInfo) loadFullUser({ userId });
if (withFullInfo && isSynced) loadFullUser({ userId });
if (withMediaViewer) loadProfilePhotos({ profileId: userId });
}
}, [userId, withFullInfo, withMediaViewer]);
}, [userId, withFullInfo, withMediaViewer, isSynced]);
const handleAvatarViewerOpen = useLastCallback(
(e: React.MouseEvent<HTMLDivElement, MouseEvent>, hasMedia: boolean) => {
@ -224,6 +226,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>(
(global, { userId, forceShowSelf }): StateProps => {
const { isSynced } = global;
const user = selectUser(global, userId);
const userStatus = selectUserStatus(global, userId);
const isSavedMessages = !forceShowSelf && user && user.isSelf;
@ -236,6 +239,7 @@ export default memo(withGlobal<OwnProps>(
isSavedMessages,
areMessagesLoaded,
self,
isSynced,
};
},
)(PrivateChatInfo));

View File

@ -63,7 +63,7 @@ type StateProps =
chatProfilePhoto?: ApiPhoto;
emojiStatusSticker?: ApiSticker;
}
& Pick<GlobalState, 'connectionState'>;
& Pick<GlobalState, 'isSynced'>;
const EMOJI_STATUS_SIZE = 24;
const EMOJI_TOPIC_SIZE = 120;
@ -74,7 +74,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
user,
userStatus,
chat,
connectionState,
isSynced,
mediaId,
avatarOwnerId,
topic,
@ -132,10 +132,10 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
}, [currentPhotoIndex, photos.length]);
useEffect(() => {
if (connectionState === 'connectionStateReady' && userId && !forceShowSelf) {
if (isSynced && userId && !forceShowSelf) {
loadFullUser({ userId });
}
}, [userId, loadFullUser, connectionState, forceShowSelf]);
}, [userId, loadFullUser, isSynced, forceShowSelf]);
usePhotosPreload(photos, currentPhotoIndex);
@ -381,7 +381,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>(
(global, { userId }): StateProps => {
const { connectionState } = global;
const { isSynced } = global;
const user = selectUser(global, userId);
const isPrivate = isUserId(userId);
const userStatus = selectUserStatus(global, userId);
@ -397,7 +397,7 @@ export default memo(withGlobal<OwnProps>(
const emojiStatusSticker = emojiStatus ? global.customEmojis.byId[emojiStatus.documentId] : undefined;
return {
connectionState,
isSynced,
user,
userStatus,
chat,

View File

@ -19,6 +19,14 @@
-webkit-touch-callout: none;
&.standalone {
position: static;
.LastMessageMeta {
margin-inline-end: 0;
}
}
&.animate-opacity {
will-change: opacity;
transition: opacity 0.2s ease-out;
@ -54,7 +62,7 @@
}
}
&:last-of-type {
&:not(.standalone):last-of-type {
border-bottom: 0.5rem solid transparent; // `margin` does not help, and `padding` affects forum indicator height
}
@ -223,7 +231,7 @@
}
.ChatBadge-transition {
position: relative;
position: relative;
transition: opacity var(--layer-transition), transform var(--layer-transition);
body.no-page-transitions & {

View File

@ -79,8 +79,11 @@ type OwnProps = {
orderDiff: number;
animationType: ChatAnimationTypes;
isPinned?: boolean;
offsetTop: number;
offsetTop?: number;
isSavedDialog?: boolean;
isPreview?: boolean;
previewMessageId?: number;
className?: string;
observeIntersection?: ObserveFn;
onDragEnter?: (chatId: string) => void;
};
@ -139,6 +142,9 @@ const Chat: FC<OwnProps & StateProps> = ({
lastMessage,
isSavedDialog,
currentUserId,
isPreview,
previewMessageId,
className,
onDragEnter,
}) => {
const {
@ -146,9 +152,11 @@ const Chat: FC<OwnProps & StateProps> = ({
openSavedDialog,
toggleChatInfo,
focusLastMessage,
focusMessage,
loadTopics,
openForumPanel,
closeForumPanel,
setShouldCloseRightColumn,
} = getActions();
const { isMobile } = useAppLayout();
@ -181,6 +189,7 @@ const Chat: FC<OwnProps & StateProps> = ({
withInterfaceAnimations,
orderDiff,
isSavedDialog,
isPreview,
});
const getIsForumPanelClosed = useSelectorSignal(selectIsForumPanelClosed);
@ -188,6 +197,18 @@ const Chat: FC<OwnProps & StateProps> = ({
const handleClick = useLastCallback(() => {
const noForumTopicPanel = isMobile && isForumAsMessages;
if (isMobile) {
setShouldCloseRightColumn({ value: true });
}
if (isPreview) {
focusMessage({
chatId,
messageId: previewMessageId!,
});
return;
}
if (isSavedDialog) {
openSavedDialog({ chatId, noForumTopicPanel: true }, { forceOnHeavyAnimation: true });
@ -256,6 +277,7 @@ const Chat: FC<OwnProps & StateProps> = ({
canChangeFolder,
isSavedDialog,
currentUserId,
isPreview,
});
const isIntersecting = useIsIntersecting(ref, chat ? observeIntersection : undefined);
@ -286,18 +308,20 @@ const Chat: FC<OwnProps & StateProps> = ({
const peer = user || chat;
const className = buildClassName(
const chatClassName = buildClassName(
'Chat chat-item-clickable',
isUserId(chatId) ? 'private' : 'group',
isForum && 'forum',
isSelected && 'selected',
isSelectedForum && 'selected-forum',
isPreview && 'standalone',
className,
);
return (
<ListItem
ref={ref}
className={className}
className={chatClassName}
href={href}
style={`top: ${offsetTop}px`}
ripple={!isForum && !isMobile}
@ -345,7 +369,14 @@ const Chat: FC<OwnProps & StateProps> = ({
</div>
<div className="subtitle">
{renderSubtitle()}
<ChatBadge chat={chat} isPinned={isPinned} isMuted={isMuted} isSavedDialog={isSavedDialog} />
{!isPreview && (
<ChatBadge
chat={chat}
isPinned={isPinned}
isMuted={isMuted}
isSavedDialog={isSavedDialog}
/>
)}
</div>
</div>
{shouldRenderDeleteModal && (
@ -387,7 +418,9 @@ const Chat: FC<OwnProps & StateProps> = ({
};
export default memo(withGlobal<OwnProps>(
(global, { chatId, isSavedDialog }): StateProps => {
(global, {
chatId, isSavedDialog, isPreview, previewMessageId,
}): StateProps => {
const chat = selectChat(global, chatId);
if (!chat) {
return {
@ -395,8 +428,10 @@ export default memo(withGlobal<OwnProps>(
};
}
const lastMessageId = selectChatLastMessageId(global, chatId, isSavedDialog ? 'saved' : 'all');
const lastMessage = selectChatLastMessage(global, chatId, isSavedDialog ? 'saved' : 'all');
const lastMessageId = previewMessageId || selectChatLastMessageId(global, chatId, isSavedDialog ? 'saved' : 'all');
const lastMessage = previewMessageId
? selectChatMessage(global, chatId, previewMessageId)
: selectChatLastMessage(global, chatId, isSavedDialog ? 'saved' : 'all');
const { senderId, isOutgoing, forwardInfo } = lastMessage || {};
const actualSenderId = isSavedDialog ? forwardInfo?.fromId : senderId;
const replyToMessageId = lastMessage && getMessageReplyInfo(lastMessage)?.replyToMsgId;
@ -413,7 +448,7 @@ export default memo(withGlobal<OwnProps>(
threadId: currentThreadId,
type: messageListType,
} = selectCurrentMessageList(global) || {};
const isSelected = chatId === currentChatId && (isSavedDialog
const isSelected = !isPreview && chatId === currentChatId && (isSavedDialog
? chatId === currentThreadId : currentThreadId === MAIN_THREAD_ID);
const isSelectedForum = (chat.isForum && chatId === currentChatId)
|| chatId === selectTabState(global).forumPanelChatId;

View File

@ -59,6 +59,7 @@ export default function useChatListEntry({
withInterfaceAnimations,
isTopic,
isSavedDialog,
isPreview,
}: {
chat?: ApiChat;
lastMessage?: ApiMessage;
@ -73,6 +74,7 @@ export default function useChatListEntry({
observeIntersection?: ObserveFn;
isTopic?: boolean;
isSavedDialog?: boolean;
isPreview?: boolean;
animationType: ChatAnimationTypes;
orderDiff: number;
@ -104,14 +106,15 @@ export default function useChatListEntry({
}, [actionTargetUserIds]);
const renderLastMessageOrTyping = useCallback(() => {
if (!isSavedDialog && typingStatus && lastMessage && typingStatus.timestamp > lastMessage.date * 1000) {
if (!isSavedDialog && !isPreview
&& typingStatus && lastMessage && typingStatus.timestamp > lastMessage.date * 1000) {
return <TypingStatus typingStatus={typingStatus} />;
}
const isDraftReplyToTopic = draft && draft.replyInfo?.replyToMsgId === lastMessageTopic?.id;
const isEmptyLocalReply = draft?.replyInfo && !draft.text && draft.isLocal;
const canDisplayDraft = !chat?.isForum && !isSavedDialog && draft && !isEmptyLocalReply
const canDisplayDraft = !chat?.isForum && !isSavedDialog && !isPreview && draft && !isEmptyLocalReply
&& (!isTopic || !isDraftReplyToTopic);
if (canDisplayDraft) {
@ -180,7 +183,7 @@ export default function useChatListEntry({
}, [
actionTargetChatId, actionTargetMessage, actionTargetUsers, chat, chatId, draft, isAction,
isRoundVideo, isTopic, lang, lastMessage, lastMessageSender, lastMessageTopic, mediaBlobUrl, mediaThumbnail,
observeIntersection, typingStatus, isSavedDialog,
observeIntersection, typingStatus, isSavedDialog, isPreview,
]);
function renderSubtitle() {

View File

@ -18,29 +18,36 @@ type OwnProps = {
type StateProps = {
shouldNewNonContactPeersRequirePremium?: boolean;
canLimitNewMessagesWithoutPremium?: boolean;
isCurrentUserPremium?: boolean;
};
function PrivacyMessages({
isActive, onReset, shouldNewNonContactPeersRequirePremium, isCurrentUserPremium,
isActive,
canLimitNewMessagesWithoutPremium,
shouldNewNonContactPeersRequirePremium,
isCurrentUserPremium,
onReset,
}: OwnProps & StateProps) {
const { updateGlobalPrivacySettings } = getActions();
const lang = useLang();
const canChange = isCurrentUserPremium || canLimitNewMessagesWithoutPremium;
const options = useMemo(() => {
return [
{ value: 'everybody', label: lang('P2PEverybody') },
{
value: 'contacts_and_premium',
label: isCurrentUserPremium ? (
label: canChange ? (
lang('PrivacyMessagesContactsAndPremium')
) : (
<PrivacyLockedOption label={lang('PrivacyMessagesContactsAndPremium')} />
),
hidden: !isCurrentUserPremium,
hidden: !canChange,
},
];
}, [lang, isCurrentUserPremium]);
}, [lang, canChange]);
const handleChange = useLastCallback((privacy: string) => {
updateGlobalPrivacySettings({ shouldNewNonContactPeersRequirePremium: privacy === 'contacts_and_premium' });
@ -67,7 +74,7 @@ function PrivacyMessages({
{lang('Privacy.Messages.SectionFooter')}
</p>
</div>
{!isCurrentUserPremium && <PremiumStatusItem premiumSection="message_privacy" />}
{!canChange && <PremiumStatusItem premiumSection="message_privacy" />}
</>
);
}
@ -76,5 +83,6 @@ export default memo(withGlobal<OwnProps>((global): StateProps => {
return {
shouldNewNonContactPeersRequirePremium: selectNewNoncontactPeersRequirePremium(global),
isCurrentUserPremium: selectIsCurrentUserPremium(global),
canLimitNewMessagesWithoutPremium: global.appConfig?.canLimitNewMessagesWithoutPremium,
};
})(PrivacyMessages));

View File

@ -120,15 +120,6 @@
margin-bottom: 0.25rem;
}
}
.business-location {
width: 4rem;
height: 4rem;
object-fit: cover;
border-radius: 0.25rem;
flex-shrink: 0;
margin-inline-start: 0.25rem;
}
}
.settings-item-simple,

View File

@ -275,19 +275,6 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
</span>
</div>
</ListItem>
<ListItem
narrow
className="no-icon"
// eslint-disable-next-line react/jsx-no-bind
onClick={() => onScreenSelect(SettingsScreens.PrivacyGroupChats)}
>
<div className="multiline-menu-item">
<span className="title">{lang('WhoCanAddMe')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(privacyGroupChats)}
</span>
</div>
</ListItem>
<ListItem
narrow
allowDisabledClick
@ -319,6 +306,19 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
</span>
</div>
</ListItem>
<ListItem
narrow
className="no-icon"
// eslint-disable-next-line react/jsx-no-bind
onClick={() => onScreenSelect(SettingsScreens.PrivacyGroupChats)}
>
<div className="multiline-menu-item">
<span className="title">{lang('WhoCanAddMe')}</span>
<span className="subtitle" dir="auto">
{getVisibilityValue(privacyGroupChats)}
</span>
</div>
</ListItem>
</div>
{canChangeSensitive && (

View File

@ -1,10 +1,12 @@
.ContactGreeting {
.root {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
gap: 0.5rem;
.wrapper {
display: inline-flex;
@ -17,6 +19,16 @@
color: #fff;
}
.explainer {
background: var(--pattern-color);
padding: 0.25rem 0.5rem;
border-radius: 1rem;
font-size: 0.875rem;
color: #fff;
max-width: 14.5rem;
text-wrap: balance;
}
.title {
font-weight: 500;
margin-bottom: 0;
@ -28,7 +40,7 @@
}
.sticker {
margin: 2rem 0 1rem;
margin: 1rem;
height: 10rem;
width: 10rem;
cursor: var(--custom-cursor, pointer);

View File

@ -4,34 +4,47 @@ import React, {
} from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global';
import type { ApiSticker, ApiUpdateConnectionStateType } from '../../api/types';
import type {
ApiBusinessIntro, ApiSticker, ApiUpdateConnectionStateType, ApiUser,
} from '../../api/types';
import type { MessageList } from '../../global/types';
import { selectChat, selectChatLastMessage, selectCurrentMessageList } from '../../global/selectors';
import { getUserFullName } from '../../global/helpers';
import {
selectChat,
selectChatLastMessage,
selectCurrentMessageList,
selectUser,
selectUserFullInfo,
} from '../../global/selectors';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import StickerView from '../common/StickerView';
import './ContactGreeting.scss';
import styles from './ContactGreeting.module.scss';
type OwnProps = {
userId: string;
};
type StateProps = {
stickers?: ApiSticker[];
defaultStickers?: ApiSticker[];
lastUnreadMessageId?: number;
connectionState?: ApiUpdateConnectionStateType;
currentMessageList?: MessageList;
businessIntro?: ApiBusinessIntro;
user?: ApiUser;
};
const ContactGreeting: FC<OwnProps & StateProps> = ({
stickers,
defaultStickers,
connectionState,
lastUnreadMessageId,
currentMessageList,
businessIntro,
user,
}) => {
const {
loadGreetingStickers,
@ -45,19 +58,20 @@ const ContactGreeting: FC<OwnProps & StateProps> = ({
const containerRef = useRef<HTMLDivElement>(null);
const sticker = useMemo(() => {
if (!stickers?.length) return undefined;
if (businessIntro?.sticker) return businessIntro.sticker;
if (!defaultStickers?.length) return undefined;
const randomIndex = Math.floor(Math.random() * stickers.length);
return stickers[randomIndex];
}, [stickers]);
const randomIndex = Math.floor(Math.random() * defaultStickers.length);
return defaultStickers[randomIndex];
}, [businessIntro?.sticker, defaultStickers]);
useEffect(() => {
if (stickers?.length || connectionState !== 'connectionStateReady') {
if (defaultStickers?.length || connectionState !== 'connectionStateReady') {
return;
}
loadGreetingStickers();
}, [connectionState, loadGreetingStickers, stickers]);
}, [connectionState, loadGreetingStickers, defaultStickers]);
useEffect(() => {
if (connectionState === 'connectionStateReady' && lastUnreadMessageId) {
@ -79,13 +93,16 @@ const ContactGreeting: FC<OwnProps & StateProps> = ({
});
});
return (
<div className="ContactGreeting">
<div className="wrapper">
<p className="title" dir="auto">{lang('Conversation.EmptyPlaceholder')}</p>
<p className="description" dir="auto">{lang('Conversation.GreetingText')}</p>
const title = businessIntro?.title || lang('Conversation.EmptyPlaceholder');
const description = businessIntro?.description || lang('Conversation.GreetingText');
<div ref={containerRef} className="sticker" onClick={handleStickerSelect}>
return (
<div className={styles.root}>
<div className={styles.wrapper}>
<p className={styles.title} dir="auto">{title}</p>
<p className={styles.description} dir="auto">{description}</p>
<div ref={containerRef} className={styles.sticker} onClick={handleStickerSelect}>
{sticker && (
<StickerView
containerRef={containerRef}
@ -96,6 +113,11 @@ const ContactGreeting: FC<OwnProps & StateProps> = ({
)}
</div>
</div>
{businessIntro && (
<div className={styles.explainer}>
{lang('Chat.EmptyStateIntroFooter', getUserFullName(user!))}
</div>
)}
</div>
);
};
@ -108,15 +130,20 @@ export default memo(withGlobal<OwnProps>(
return {};
}
const user = selectUser(global, userId);
const fullInfo = selectUserFullInfo(global, userId);
const lastMessage = selectChatLastMessage(global, chat.id);
return {
stickers,
defaultStickers: stickers,
lastUnreadMessageId: lastMessage && lastMessage.id !== chat.lastReadInboxMessageId
? lastMessage.id
: undefined,
connectionState: global.connectionState,
currentMessageList: selectCurrentMessageList(global),
businessIntro: fullInfo?.businessIntro,
user,
};
},
)(ContactGreeting));

View File

@ -1,4 +1,6 @@
.root {
--custom-emoji-size: 2rem;
width: 1.875rem;
height: 1.875rem;
display: flex;

View File

@ -21,6 +21,7 @@ import useMediaTransition from '../../../hooks/useMediaTransition';
import useCustomEmoji from '../../common/hooks/useCustomEmoji';
import AnimatedSticker from '../../common/AnimatedSticker';
import CustomEmoji from '../../common/CustomEmoji';
import OptimizedVideo from '../../ui/OptimizedVideo';
import styles from './StickerSetCover.module.scss';
@ -47,7 +48,7 @@ const StickerSetCover: FC<OwnProps> = ({
const containerRef = useRef<HTMLDivElement>(null);
const {
hasThumbnail, thumbCustomEmojiId, isLottie, isVideos: isVideo,
hasThumbnail, hasVideoThumb, hasAnimatedThumb, hasStaticThumb, thumbCustomEmojiId,
} = stickerSet;
const { customEmoji } = useCustomEmoji(thumbCustomEmojiId);
@ -58,13 +59,15 @@ const StickerSetCover: FC<OwnProps> = ({
const isIntersecting = useIsIntersecting(containerRef, observeIntersection);
const shouldPlay = isIntersecting && !noPlay;
const shouldFallbackToStatic = stickerSet.stickers && isVideo && !IS_WEBM_SUPPORTED;
const hasOnlyStaticThumb = hasStaticThumb && !hasVideoThumb && !hasAnimatedThumb && !thumbCustomEmojiId;
const shouldFallbackToStatic = hasOnlyStaticThumb || (hasVideoThumb && !IS_WEBM_SUPPORTED && !hasAnimatedThumb);
const staticHash = shouldFallbackToStatic && getStickerPreviewHash(stickerSet.stickers![0].id);
const staticMediaData = useMedia(staticHash, !isIntersecting);
const mediaHash = ((hasThumbnail && !shouldFallbackToStatic) || isLottie) && `stickerSet${stickerSet.id}`;
const mediaHash = ((hasThumbnail && !shouldFallbackToStatic) || hasAnimatedThumb) && `stickerSet${stickerSet.id}`;
const mediaData = useMedia(mediaHash, !isIntersecting);
const isReady = mediaData || staticMediaData;
const isReady = thumbCustomEmojiId || mediaData || staticMediaData;
const transitionClassNames = useMediaTransition(isReady);
const coords = useCoordsInSharedCanvas(containerRef, sharedCanvasRef);
@ -83,7 +86,14 @@ const StickerSetCover: FC<OwnProps> = ({
return (
<div ref={containerRef} className={buildClassName(styles.root, 'sticker-set-cover')}>
{isReady ? (
isLottie ? (
thumbCustomEmojiId ? (
<CustomEmoji
documentId={thumbCustomEmojiId}
size={size}
observeIntersectionForPlaying={observeIntersection}
noPlay={noPlay}
/>
) : hasAnimatedThumb ? (
<AnimatedSticker
className={transitionClassNames}
tgsUrl={mediaData}
@ -94,7 +104,7 @@ const StickerSetCover: FC<OwnProps> = ({
sharedCanvasCoords={coords}
forceAlways={forcePlayback}
/>
) : (isVideo && !shouldFallbackToStatic) ? (
) : (hasVideoThumb && !shouldFallbackToStatic) ? (
<OptimizedVideo
className={buildClassName(styles.video, transitionClassNames)}
src={mediaData}

View File

@ -7,6 +7,8 @@ import { ApiMessageEntityTypes } from '../../../api/types';
import { selectUser } from '../../../global/selectors';
import useAppLayout from '../../../hooks/useAppLayout';
type OwnProps = {
userId?: string;
username?: string;
@ -27,9 +29,18 @@ const MentionLink: FC<OwnProps & StateProps> = ({
openChat,
openChatByUsername,
closeStoryViewer,
setShouldCloseRightColumn,
} = getActions();
const { isMobile } = useAppLayout();
const handleClick = () => {
if (isMobile) {
setShouldCloseRightColumn({
value: true,
});
}
if (userOrChat) {
openChat({ id: userOrChat.id });
} else if (username) {

View File

@ -283,6 +283,7 @@ type StateProps = {
senderBoosts?: number;
tags?: Record<ApiReactionKey, ApiSavedReactionTag>;
canTranscribeVoice?: boolean;
viaBusinessBot?: ApiUser;
};
type MetaPosition =
@ -400,6 +401,7 @@ const Message: FC<OwnProps & StateProps> = ({
senderBoosts,
tags,
canTranscribeVoice,
viaBusinessBot,
onPinnedIntersectionChange,
}) => {
const {
@ -753,7 +755,9 @@ const Message: FC<OwnProps & StateProps> = ({
ref, chatId, isFocused, focusDirection, noFocusHighlight, isResizingContainer, isJustAdded, Boolean(focusedQuote),
);
const signature = (isChannel && message.postAuthorTitle)
const viaBusinessBotTitle = viaBusinessBot ? getSenderTitle(lang, viaBusinessBot) : undefined;
const signature = viaBusinessBotTitle || (isChannel && message.postAuthorTitle)
|| ((asForwarded || isChatWithSelf) && forwardInfo?.postAuthorTitle)
|| undefined;
@ -1486,7 +1490,7 @@ export default memo(withGlobal<OwnProps>(
message, album, withSenderName, withAvatar, threadId, messageListType, isLastInDocumentGroup, isFirstInGroup,
} = ownProps;
const {
id, chatId, viaBotId, isOutgoing, forwardInfo, transcriptionId, isPinned,
id, chatId, viaBotId, isOutgoing, forwardInfo, transcriptionId, isPinned, viaBusinessBotId,
} = message;
const chat = selectChat(global, chatId);
@ -1595,6 +1599,8 @@ export default memo(withGlobal<OwnProps>(
const transcribeMinLevel = global.appConfig?.groupTranscribeLevelMin;
const canTranscribeVoice = isPremium || Boolean(transcribeMinLevel && chatLevel >= transcribeMinLevel);
const viaBusinessBot = viaBusinessBotId ? selectUser(global, viaBusinessBotId) : undefined;
return {
theme: selectTheme(global),
forceSenderName,
@ -1678,6 +1684,7 @@ export default memo(withGlobal<OwnProps>(
senderBoosts,
tags: global.savedReactionTags?.byKey,
canTranscribeVoice,
viaBusinessBot,
};
},
)(Message));

View File

@ -201,6 +201,15 @@ const useWebAppFrame = (
window.open(linkUrl, '_blank', 'noreferrer');
}
if (eventType === 'web_app_biometry_get_info') {
sendEvent({
eventType: 'biometry_info_received',
eventData: {
available: false,
},
});
}
onEvent(data);
} catch (err) {
// Ignore other messages

View File

@ -35,15 +35,6 @@
.FloatingActionButton {
z-index: 1;
}
.business-location {
width: 4rem;
height: 4rem;
object-fit: cover;
border-radius: 0.25rem;
flex-shrink: 0;
margin-inline-start: 0.25rem;
}
}
.shared-media {

View File

@ -55,6 +55,7 @@ type StateProps = {
shouldSkipHistoryAnimations?: boolean;
nextManagementScreen?: ManagementScreens;
nextProfileTab?: ProfileTabType;
shouldCloseRightColumn?: boolean;
isSavedMessages?: boolean;
isSavedDialog?: boolean;
};
@ -79,6 +80,7 @@ const RightColumn: FC<OwnProps & StateProps> = ({
shouldSkipHistoryAnimations,
nextManagementScreen,
nextProfileTab,
shouldCloseRightColumn,
isSavedMessages,
isSavedDialog,
}) => {
@ -101,6 +103,7 @@ const RightColumn: FC<OwnProps & StateProps> = ({
closeCreateTopicPanel,
closeEditTopicPanel,
closeBoostStatistics,
setShouldCloseRightColumn,
} = getActions();
const { width: windowWidth } = useWindowSize();
@ -253,6 +256,13 @@ const RightColumn: FC<OwnProps & StateProps> = ({
resetNextProfileTab();
}, [nextProfileTab]);
useEffect(() => {
if (shouldCloseRightColumn) {
close();
setShouldCloseRightColumn({ value: undefined });
}
}, [shouldCloseRightColumn]);
// Close Right Column when it transforms into overlayed state on screen resize
useEffect(() => {
if (isOpen && isOverlaying) {
@ -409,7 +419,9 @@ export default memo(withGlobal<OwnProps>(
(global, { isMobile }): StateProps => {
const { chatId, threadId } = selectCurrentMessageList(global) || {};
const areActiveChatsLoaded = selectAreActiveChatsLoaded(global);
const { management, shouldSkipHistoryAnimations, nextProfileTab } = selectTabState(global);
const {
management, shouldSkipHistoryAnimations, nextProfileTab, shouldCloseRightColumn,
} = selectTabState(global);
const nextManagementScreen = chatId ? management.byChatId[chatId]?.nextScreen : undefined;
const isSavedMessages = chatId ? selectIsChatWithSelf(global, chatId) : undefined;
@ -423,6 +435,7 @@ export default memo(withGlobal<OwnProps>(
shouldSkipHistoryAnimations,
nextManagementScreen,
nextProfileTab,
shouldCloseRightColumn,
isSavedMessages,
isSavedDialog,
};

View File

@ -49,7 +49,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-v33';
export const LANG_CACHE_NAME = 'tt-lang-packs-v34';
export const ASSET_CACHE_NAME = 'tt-assets';
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global';
@ -217,7 +217,7 @@ export const VIDEO_WEBM_TYPE = 'video/webm';
export const GIF_MIME_TYPE = 'image/gif';
export const LOTTIE_STICKER_MIME_TYPE = 'application/x-tgsticker';
export const VIDEO_STICKER_MIME_TYPE = 'video/webm';
export const VIDEO_STICKER_MIME_TYPE = VIDEO_WEBM_TYPE;
export const SUPPORTED_IMAGE_CONTENT_TYPES = new Set([
'image/png', 'image/jpeg', GIF_MIME_TYPE,

View File

@ -696,7 +696,7 @@ addActionHandler('createChannel', async (global, actions, payload): Promise<void
try {
const result = await callApi('createChannel', { title, about, users });
createdChannel = result?.channel;
restrictedUserIds = result?.restrictedUserIds;
restrictedUserIds = result?.missingUsers?.map(({ id }) => id);
} catch (error) {
global = getGlobal();
@ -864,7 +864,7 @@ addActionHandler('createGroupChat', async (global, actions, payload): Promise<vo
let createdChatId: string | undefined;
try {
const { chat: createdChat, restrictedUserIds } = await callApi('createGroupChat', {
const { chat: createdChat, missingUsers } = await callApi('createGroupChat', {
title,
users,
}) ?? {};
@ -890,6 +890,8 @@ addActionHandler('createGroupChat', async (global, actions, payload): Promise<vo
shouldReplaceHistory: true,
tabId,
});
const restrictedUserIds = missingUsers?.map(({ id }) => id);
if (restrictedUserIds) {
global = getGlobal();
global = addUsersToRestrictedInviteList(global, restrictedUserIds, chatId, tabId);
@ -1918,7 +1920,8 @@ addActionHandler('addChatMembers', async (global, actions, payload): Promise<voi
}
actions.setNewChatMembersDialogState({ newChatMembersProgress: NewChatMembersProgress.Loading, tabId });
const restrictedUserIds = await callApi('addChatMembers', chat, users);
const missingUsers = await callApi('addChatMembers', chat, users);
const restrictedUserIds = missingUsers?.map((user) => user.id);
if (restrictedUserIds) {
global = getGlobal();
global = addUsersToRestrictedInviteList(global, restrictedUserIds, chat.id, tabId);

View File

@ -542,6 +542,7 @@ addActionHandler('setPrivacySettings', async (global, actions, payload): Promise
const rules = buildApiInputPrivacyRules(global, {
visibility: settings.visibility,
isUnspecified: settings.isUnspecified,
shouldAllowPremium: settings.shouldAllowPremium,
allowedIds: isAllowList ? updatedIds : [...settings.allowUserIds, ...settings.allowChatIds],
blockedIds: !isAllowList ? updatedIds : [...settings.blockUserIds, ...settings.blockChatIds],
});

View File

@ -21,6 +21,7 @@ import {
closeNewContactDialog,
replaceUserStatuses,
updateChat,
updateChats,
updateManagementProgress,
updateUser,
updateUserFullInfo,
@ -60,6 +61,9 @@ addActionHandler('loadFullUser', async (global, actions, payload): Promise<void>
global = updateUser(global, userId, result.user);
global = updateUserFullInfo(global, userId, result.fullInfo);
global = updateUsers(global, buildCollectionByKey(result.users, 'id'));
global = updateChats(global, buildCollectionByKey(result.chats, 'id'));
setGlobal(global);
if (withPhotos || (user.photos?.length && hasChangedPhoto)) {
actions.loadProfilePhotos({ profileId: userId });

View File

@ -743,6 +743,13 @@ addActionHandler('closeInviteViaLinkModal', (global, actions, payload): ActionRe
}, tabId);
});
addActionHandler('setShouldCloseRightColumn', (global, actions, payload): ActionReturnType => {
const { value, tabId = getCurrentTabId() } = payload;
return updateTabState(global, {
shouldCloseRightColumn: value,
}, tabId);
});
let prevIsScreenLocked: boolean | undefined;
let prevBlurredTabsCount: number = 0;
let onlineTimeout: number | undefined;

View File

@ -9,11 +9,13 @@ export function buildApiInputPrivacyRules(global: GlobalState, {
isUnspecified,
allowedIds,
blockedIds,
shouldAllowPremium,
}: {
visibility: PrivacyVisibility;
isUnspecified?: boolean;
allowedIds: string[];
blockedIds: string[];
shouldAllowPremium?: true;
}): ApiInputPrivacyRules {
const {
users: { byId: usersById },
@ -30,6 +32,7 @@ export function buildApiInputPrivacyRules(global: GlobalState, {
allowedChats: allowedChatIds.map((chatId) => chatsById[chatId]).filter(Boolean),
blockedUsers: blockedUserIds.map((userId) => usersById[userId]).filter(Boolean),
blockedChats: blockedChatIds.map((chatId) => chatsById[chatId]).filter(Boolean),
shouldAllowPremium,
};
return rules;

View File

@ -246,6 +246,7 @@ export type TabState = {
resultIds?: string[];
};
shouldCloseRightColumn?: boolean;
nextProfileTab?: ProfileTabType;
forceScrollProfileTab?: boolean;
nextSettingsScreen?: SettingsScreens;
@ -1775,6 +1776,9 @@ export interface ActionPayloads {
updatePrivateLink: WithTabId | undefined;
resetManagementError: { chatId: string } & WithTabId;
setShouldCloseRightColumn: {
value?: boolean;
} & WithTabId;
requestChatUpdate: { chatId: string };
requestSavedDialogUpdate: { chatId: string };
loadChatJoinRequests: {

View File

@ -22,6 +22,7 @@ const useChatContextActions = ({
canChangeFolder,
isSavedDialog,
currentUserId,
isPreview,
handleDelete,
handleMute,
handleChatFolderChange,
@ -35,6 +36,7 @@ const useChatContextActions = ({
canChangeFolder?: boolean;
isSavedDialog?: boolean;
currentUserId?: string;
isPreview?: boolean;
handleDelete?: NoneToVoidFunction;
handleMute?: NoneToVoidFunction;
handleChatFolderChange: NoneToVoidFunction;
@ -68,7 +70,7 @@ const useChatContextActions = ({
}, [chat, isSavedDialog, lang]);
return useMemo(() => {
if (!chat) {
if (!chat || isPreview) {
return undefined;
}
@ -178,6 +180,7 @@ const useChatContextActions = ({
}, [
chat, user, canChangeFolder, lang, handleChatFolderChange, isPinned, isInSearch, isMuted, currentUserId,
handleDelete, handleMute, handleReport, folderId, isSelf, isServiceNotifications, isSavedDialog, deleteTitle,
isPreview,
]);
};

View File

@ -47,6 +47,14 @@ class FloodWaitError extends FloodError {
this.seconds = seconds;
}
}
class FloodPremiumWaitError extends FloodWaitError {
constructor(args) {
const seconds = Number(args.capture || 0);
super(`A wait of ${seconds} seconds is required${RPCError._fmtRequest(args.request)}`);
this.message = `A wait of ${seconds} seconds is required${RPCError._fmtRequest(args.request)}`;
this.seconds = seconds;
}
}
class MsgWaitError extends FloodError {
constructor(args) {
super(`Message failed to be sent.${RPCError._fmtRequest(args.request)}`);
@ -97,6 +105,7 @@ const rpcErrorRe = [
[/FILE_MIGRATE_(\d+)/, FileMigrateError],
[/FLOOD_TEST_PHONE_WAIT_(\d+)/, FloodTestPhoneWaitError],
[/FLOOD_WAIT_(\d+)/, FloodWaitError],
[/FLOOD_PREMIUM_WAIT_(\d+)/, FloodPremiumWaitError],
[/MSG_WAIT_(.*)/, MsgWaitError],
[/PHONE_MIGRATE_(\d+)/, PhoneMigrateError],
[/SLOWMODE_WAIT_(\d+)/, SlowModeWaitError],

View File

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

File diff suppressed because one or more lines are too long

View File

@ -66,7 +66,7 @@ storage.fileMov#4b09ebbc = storage.FileType;
storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;
userEmpty#d3bc4b7a id:long = User;
user#215c4438 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:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true 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> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor = User;
user#215c4438 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:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true 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> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor = User;
userProfilePhotoEmpty#4f11bae1 = 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;
@ -81,7 +81,7 @@ chatForbidden#6592a1a7 id:long title:string = Chat;
channel#aadfc8f 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:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true 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> stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int = 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 translations_disabled:flags.19?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#44c054a7 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 translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?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 stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull;
channelFull#44c054a7 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 translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?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 stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = 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;
@ -90,7 +90,7 @@ chatParticipants#3cbc93f8 chat_id:long participants:Vector<ChatParticipant> vers
chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message;
message#a66c7efc 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 invert_media:flags.27?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?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 quick_reply_shortcut_id:flags.30?int = Message;
message#2357bf25 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 invert_media:flags.27?true flags2:# offline:flags2.1?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long via_business_bot_id:flags2.0?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 quick_reply_shortcut_id:flags.30?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:# spoiler:flags.3?true photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
@ -150,6 +150,7 @@ messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags
messageActionGiveawayLaunch#332ba9ed = MessageAction;
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction;
messageActionBoostApply#cc02aa6d boosts:int = MessageAction;
messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector<RequestedPeer> = MessageAction;
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?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 +175,7 @@ inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
inputNotifyForumTopic#5c467992 peer:InputPeer top_msg_id:int = InputNotifyPeer;
inputPeerNotifySettings#cacb6ae2 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?NotificationSound stories_muted:flags.6?Bool stories_hide_sender:flags.7?Bool stories_sound:flags.8?NotificationSound = InputPeerNotifySettings;
peerNotifySettings#99622c0c flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int ios_sound:flags.3?NotificationSound android_sound:flags.4?NotificationSound other_sound:flags.5?NotificationSound stories_muted:flags.6?Bool stories_hide_sender:flags.7?Bool stories_ios_sound:flags.8?NotificationSound stories_android_sound:flags.9?NotificationSound stories_other_sound:flags.10?NotificationSound = PeerNotifySettings;
peerSettings#a518110d flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int = PeerSettings;
peerSettings#acd66c5e flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true business_bot_paused:flags.11?true business_bot_can_reply:flags.12?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int business_bot_id:flags.13?long business_bot_manage_url:flags.13?string = PeerSettings;
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
wallPaperNoFile#e0804116 id:long flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper;
inputReportReasonSpam#58dbcab8 = ReportReason;
@ -187,7 +188,7 @@ inputReportReasonGeoIrrelevant#dbd4feed = ReportReason;
inputReportReasonFake#f5ddd6e7 = ReportReason;
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
userFull#22ff3e85 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage = UserFull;
userFull#cc997720 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int = 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;
@ -335,7 +336,6 @@ updateChannelPinnedTopic#192efbe3 flags:# pinned:flags.0?true channel_id:long to
updateChannelPinnedTopics#fe198602 flags:# channel_id:long order:flags.0?Vector<int> = Update;
updateUser#20529438 user_id:long = Update;
updateAutoSaveSettings#ec05b097 = Update;
updateGroupInvitePrivacyForbidden#ccf08ad6 user_id:long = Update;
updateStory#75b3b798 peer:Peer story:StoryItem = Update;
updateReadStories#f74e932b peer:Peer max_id:int = Update;
updateStoryID#1bf335b9 id:int random_id:long = Update;
@ -355,6 +355,10 @@ updateNewQuickReply#f53da717 quick_reply:QuickReply = Update;
updateDeleteQuickReply#53e6f1ec shortcut_id:int = Update;
updateQuickReplyMessage#3e050d0f message:Message = Update;
updateDeleteQuickReplyMessages#566fe7cd shortcut_id:int messages:Vector<int> = Update;
updateBotBusinessConnect#8ae5c97a connection:BotBusinessConnection qts:int = Update;
updateBotNewBusinessMessage#9ddb347c flags:# connection_id:string message:Message reply_to_message:flags.0?Message qts:int = Update;
updateBotEditBusinessMessage#7df587c flags:# connection_id:string message:Message reply_to_message:flags.0?Message qts:int = Update;
updateBotDeleteBusinessMessage#a02a982e connection_id:string peer:Peer messages:Vector<int> qts:int = 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;
@ -435,6 +439,7 @@ inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey;
inputPrivacyKeyAddedByPhone#d1219bdd = InputPrivacyKey;
inputPrivacyKeyVoiceMessages#aee69d68 = InputPrivacyKey;
inputPrivacyKeyAbout#3823cc40 = InputPrivacyKey;
inputPrivacyKeyBirthday#d65a11cc = InputPrivacyKey;
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
privacyKeyChatInvite#500e6dfa = PrivacyKey;
privacyKeyPhoneCall#3d662b7b = PrivacyKey;
@ -445,6 +450,7 @@ privacyKeyPhoneNumber#d19ae46d = PrivacyKey;
privacyKeyAddedByPhone#42ffd42b = PrivacyKey;
privacyKeyVoiceMessages#697f414 = PrivacyKey;
privacyKeyAbout#a486b761 = PrivacyKey;
privacyKeyBirthday#2000a518 = PrivacyKey;
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
inputPrivacyValueAllowUsers#131cc67f users:Vector<InputUser> = InputPrivacyRule;
@ -454,6 +460,7 @@ inputPrivacyValueDisallowUsers#90110467 users:Vector<InputUser> = InputPrivacyRu
inputPrivacyValueAllowChatParticipants#840649cf chats:Vector<long> = InputPrivacyRule;
inputPrivacyValueDisallowChatParticipants#e94f0f86 chats:Vector<long> = InputPrivacyRule;
inputPrivacyValueAllowCloseFriends#2f453e49 = InputPrivacyRule;
inputPrivacyValueAllowPremium#77cdc9f1 = InputPrivacyRule;
privacyValueAllowContacts#fffe1bac = PrivacyRule;
privacyValueAllowAll#65427b82 = PrivacyRule;
privacyValueAllowUsers#b8905fb2 users:Vector<long> = PrivacyRule;
@ -463,6 +470,7 @@ privacyValueDisallowUsers#e4621141 users:Vector<long> = PrivacyRule;
privacyValueAllowChatParticipants#6b134e8e chats:Vector<long> = PrivacyRule;
privacyValueDisallowChatParticipants#41c87565 chats:Vector<long> = PrivacyRule;
privacyValueAllowCloseFriends#f7e8d89b = PrivacyRule;
privacyValueAllowPremium#ece9814b = PrivacyRule;
account.privacyRules#50a04e45 rules:Vector<PrivacyRule> chats:Vector<Chat> users:Vector<User> = account.PrivacyRules;
accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
@ -506,7 +514,7 @@ inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = InputStickerSet;
inputStickerSetEmojiChannelDefaultStatuses#49748553 = 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 text_color:flags.9?true channel_emoji_status:flags.10?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true emojis:flags.7?true text_color:flags.9?true channel_emoji_status:flags.10?true creator:flags.11?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet;
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
botCommand#c27ac8c7 command:string description:string = BotCommand;
@ -527,6 +535,7 @@ keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
keyboardButtonWebView#13767230 text:string url:string = KeyboardButton;
keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton;
keyboardButtonRequestPeer#53d7bfd8 text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton;
inputKeyboardButtonRequestPeer#c9662d05 flags:# name_requested:flags.0?true username_requested:flags.1?true photo_requested:flags.2?true text:string button_id:int peer_type:RequestPeerType max_quantity:int = 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;
@ -742,7 +751,7 @@ phoneCallEmpty#5366c915 id:long = PhoneCall;
phoneCallWaiting#c5226f17 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
phoneCallRequested#14b0ed0c flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCallAccepted#3660c311 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCall#967f7c67 flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector<PhoneConnection> start_date:int = PhoneCall;
phoneCall#30535af5 flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector<PhoneConnection> start_date:int custom_parameters:flags.7?DataJSON = PhoneCall;
phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.6?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
phoneConnection#9cc123c7 flags:# tcp:flags.0?true id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection;
phoneConnectionWebrtc#635fe375 flags:# turn:flags.0?true stun:flags.1?true id:long ip:string ipv6:string port:int username:string password:string = PhoneConnection;
@ -1032,7 +1041,7 @@ botCommandScopePeerUser#a1321f3 peer:InputPeer user_id:InputUser = BotCommandSco
account.resetPasswordFailedWait#e3779861 retry_date:int = account.ResetPasswordResult;
account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult;
account.resetPasswordOk#e926d63e = account.ResetPasswordResult;
sponsoredMessage#ed5383f7 flags:# recommended:flags.5?true show_peer_photo:flags.6?true random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string webpage:flags.9?SponsoredWebPage app:flags.10?BotApp message:string entities:flags.1?Vector<MessageEntity> button_text:flags.11?string sponsor_info:flags.7?string additional_info:flags.8?string = SponsoredMessage;
sponsoredMessage#ed5383f7 flags:# recommended:flags.5?true show_peer_photo:flags.6?true can_report:flags.12?true random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string webpage:flags.9?SponsoredWebPage app:flags.10?BotApp message:string entities:flags.1?Vector<MessageEntity> button_text:flags.11?string sponsor_info:flags.7?string additional_info:flags.8?string = SponsoredMessage;
messages.sponsoredMessages#c9ee1d87 flags:# posts_between:flags.0?int messages:Vector<SponsoredMessage> chats:Vector<Chat> users:Vector<User> = messages.SponsoredMessages;
messages.sponsoredMessagesEmpty#1839490f = messages.SponsoredMessages;
searchResultsCalendarPeriod#c9b0539f date:int min_msg_id:int max_msg_id:int count:int = SearchResultsCalendarPeriod;
@ -1241,9 +1250,40 @@ inputQuickReplyShortcut#24596d41 shortcut:string = InputQuickReplyShortcut;
inputQuickReplyShortcutId#1190cf1 shortcut_id:int = InputQuickReplyShortcut;
messages.quickReplies#c68d6695 quick_replies:Vector<QuickReply> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.QuickReplies;
messages.quickRepliesNotModified#5f91eb5b = messages.QuickReplies;
connectedBot#e7e999e7 flags:# can_reply:flags.0?true bot_id:long recipients:BusinessRecipients = ConnectedBot;
connectedBot#bd068601 flags:# can_reply:flags.0?true bot_id:long recipients:BusinessBotRecipients = ConnectedBot;
account.connectedBots#17d7f87b connected_bots:Vector<ConnectedBot> users:Vector<User> = account.ConnectedBots;
messages.dialogFilters#2ad93719 flags:# tags_enabled:flags.0?true filters:Vector<DialogFilter> = messages.DialogFilters;
birthday#6c8e1e06 flags:# day:int month:int year:flags.0?int = Birthday;
botBusinessConnection#896433b4 flags:# can_reply:flags.0?true disabled:flags.1?true connection_id:string user_id:long dc_id:int date:int = BotBusinessConnection;
inputBusinessIntro#9c469cd flags:# title:string description:string sticker:flags.0?InputDocument = InputBusinessIntro;
businessIntro#5a0a066d flags:# title:string description:string sticker:flags.0?Document = BusinessIntro;
messages.myStickers#faff629d count:int sets:Vector<StickerSetCovered> = messages.MyStickers;
inputCollectibleUsername#e39460a9 username:string = InputCollectible;
inputCollectiblePhone#a2e214a4 phone:string = InputCollectible;
fragment.collectibleInfo#6ebdff91 purchase_date:int currency:string amount:long crypto_currency:string crypto_amount:long url:string = fragment.CollectibleInfo;
inputBusinessBotRecipients#c4e5921e flags:# existing_chats:flags.0?true new_chats:flags.1?true contacts:flags.2?true non_contacts:flags.3?true exclude_selected:flags.5?true users:flags.4?Vector<InputUser> exclude_users:flags.6?Vector<InputUser> = InputBusinessBotRecipients;
businessBotRecipients#b88cf373 flags:# existing_chats:flags.0?true new_chats:flags.1?true contacts:flags.2?true non_contacts:flags.3?true exclude_selected:flags.5?true users:flags.4?Vector<long> exclude_users:flags.6?Vector<long> = BusinessBotRecipients;
contactBirthday#1d998733 contact_id:long birthday:Birthday = ContactBirthday;
contacts.contactBirthdays#114ff30d contacts:Vector<ContactBirthday> users:Vector<User> = contacts.ContactBirthdays;
missingInvitee#628c9224 flags:# premium_would_allow_invite:flags.0?true premium_required_for_pm:flags.1?true user_id:long = MissingInvitee;
messages.invitedUsers#7f5defa6 updates:Updates missing_invitees:Vector<MissingInvitee> = messages.InvitedUsers;
inputBusinessChatLink#11679fa7 flags:# message:string entities:flags.0?Vector<MessageEntity> title:flags.1?string = InputBusinessChatLink;
businessChatLink#b4ae666f flags:# link:string message:string entities:flags.0?Vector<MessageEntity> title:flags.1?string views:int = BusinessChatLink;
account.businessChatLinks#ec43a2d1 links:Vector<BusinessChatLink> chats:Vector<Chat> users:Vector<User> = account.BusinessChatLinks;
account.resolvedBusinessChatLinks#9a23af21 flags:# peer:Peer message:string entities:flags.0?Vector<MessageEntity> chats:Vector<Chat> users:Vector<User> = account.ResolvedBusinessChatLinks;
requestedPeerUser#d62ff46a flags:# user_id:long first_name:flags.0?string last_name:flags.0?string username:flags.1?string photo:flags.2?Photo = RequestedPeer;
requestedPeerChat#7307544f flags:# chat_id:long title:flags.0?string photo:flags.2?Photo = RequestedPeer;
requestedPeerChannel#8ba403e4 flags:# channel_id:long title:flags.0?string username:flags.1?string photo:flags.2?Photo = RequestedPeer;
sponsoredMessageReportOption#430d3150 text:string option:bytes = SponsoredMessageReportOption;
channels.sponsoredMessageReportResultChooseOption#846f9e42 title:string options:Vector<SponsoredMessageReportOption> = channels.SponsoredMessageReportResult;
channels.sponsoredMessageReportResultAdsHidden#3e3bcf2f = channels.SponsoredMessageReportResult;
channels.sponsoredMessageReportResultReported#ad798849 = channels.SponsoredMessageReportResult;
stats.broadcastRevenueStats#d07b4bad top_hours_graph:StatsGraph revenue_graph:StatsGraph current_balance:long available_balance:long overall_revenue:long usd_rate:double = stats.BroadcastRevenueStats;
stats.broadcastRevenueWithdrawalUrl#ec659737 url:string = stats.BroadcastRevenueWithdrawalUrl;
broadcastRevenueTransactionProceeds#557e2cc4 amount:long from_date:int to_date:int = BroadcastRevenueTransaction;
broadcastRevenueTransactionWithdrawal#5a590978 flags:# pending:flags.0?true failed:flags.2?true amount:long date:int provider:string transaction_date:flags.1?int transaction_url:flags.1?string = BroadcastRevenueTransaction;
broadcastRevenueTransactionRefund#42d30d2e amount:long date:int provider:string = BroadcastRevenueTransaction;
stats.broadcastRevenueTransactions#87158466 count:int transactions:Vector<BroadcastRevenueTransaction> = stats.BroadcastRevenueTransactions;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
@ -1337,9 +1377,9 @@ messages.getChats#49e9528f id:Vector<long> = messages.Chats;
messages.getFullChat#aeb00b34 chat_id:long = messages.ChatFull;
messages.editChatTitle#73783ffd chat_id:long title:string = Updates;
messages.editChatPhoto#35ddd674 chat_id:long photo:InputChatPhoto = Updates;
messages.addChatUser#f24753e3 chat_id:long user_id:InputUser fwd_limit:int = Updates;
messages.addChatUser#cbc6d107 chat_id:long user_id:InputUser fwd_limit:int = messages.InvitedUsers;
messages.deleteChatUser#a2185cab flags:# revoke_history:flags.0?true chat_id:long user_id:InputUser = Updates;
messages.createChat#34a818 flags:# users:Vector<InputUser> title:string ttl_period:flags.0?int = Updates;
messages.createChat#92ceddd4 flags:# users:Vector<InputUser> title:string ttl_period:flags.0?int = messages.InvitedUsers;
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
messages.getStickers#d5a5d3a1 emoticon:string hash:long = messages.Stickers;
@ -1373,7 +1413,7 @@ messages.getCommonChats#e40ca104 user_id:InputUser max_id:long limit:int = messa
messages.getWebPage#8d9692a3 url:string hash:int = messages.WebPage;
messages.toggleDialogPin#a731e257 flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
messages.getPinnedDialogs#d6b94df2 folder_id:int = messages.PeerDialogs;
messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia;
messages.uploadMedia#14967978 flags:# business_connection_id:flags.0?string peer:InputPeer media:InputMedia = MessageMedia;
messages.getFavedStickers#4f1aaa9 hash:long = messages.FavedStickers;
messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
messages.getUnreadMentions#f107e790 flags:# peer:InputPeer top_msg_id:flags.0?int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
@ -1451,7 +1491,8 @@ messages.updateSavedReactionTag#60297dec flags:# reaction:Reaction title:flags.0
messages.getDefaultTagReactions#bdf93428 hash:long = messages.Reactions;
messages.getOutboxReadDate#8c4bfe5d peer:InputPeer msg_id:int = OutboxReadDate;
messages.getQuickReplies#d483f2a8 hash:long = messages.QuickReplies;
messages.sendQuickReplyMessages#33153ad4 peer:InputPeer shortcut_id:int = Updates;
messages.getQuickReplyMessages#94a495c3 flags:# shortcut_id:int id:flags.0?Vector<int> hash:long = messages.Messages;
messages.sendQuickReplyMessages#6c750de1 peer:InputPeer shortcut_id:int id:Vector<int> random_id:Vector<long> = Updates;
updates.getState#edd4882a = updates.State;
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
@ -1488,7 +1529,7 @@ channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool;
channels.updateUsername#3514b3de channel:InputChannel username:string = Bool;
channels.joinChannel#24b524c5 channel:InputChannel = Updates;
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
channels.inviteToChannel#c9e33d54 channel:InputChannel users:Vector<InputUser> = messages.InvitedUsers;
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink;
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;

View File

@ -170,6 +170,7 @@
"messages.togglePeerTranslations",
"messages.getOutboxReadDate",
"messages.getQuickReplies",
"messages.getQuickReplyMessages",
"messages.sendQuickReplyMessages",
"updates.getState",
"updates.getDifference",

View File

@ -82,7 +82,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;
userEmpty#d3bc4b7a id:long = User;
user#215c4438 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:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true 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> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor = User;
user#215c4438 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:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true 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> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor = User;
userProfilePhotoEmpty#4f11bae1 = 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;
@ -101,7 +101,7 @@ channel#aadfc8f flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5
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 translations_disabled:flags.19?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#44c054a7 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 translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?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 stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull;
channelFull#44c054a7 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 translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?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 stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
@ -114,7 +114,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message;
message#a66c7efc 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 invert_media:flags.27?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?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 quick_reply_shortcut_id:flags.30?int = Message;
message#2357bf25 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 invert_media:flags.27?true flags2:# offline:flags2.1?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long via_business_bot_id:flags2.0?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 quick_reply_shortcut_id:flags.30?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;
@ -176,6 +176,7 @@ messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags
messageActionGiveawayLaunch#332ba9ed = MessageAction;
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction;
messageActionBoostApply#cc02aa6d boosts:int = MessageAction;
messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector<RequestedPeer> = MessageAction;
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?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;
@ -211,7 +212,7 @@ inputPeerNotifySettings#cacb6ae2 flags:# show_previews:flags.0?Bool silent:flags
peerNotifySettings#99622c0c flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int ios_sound:flags.3?NotificationSound android_sound:flags.4?NotificationSound other_sound:flags.5?NotificationSound stories_muted:flags.6?Bool stories_hide_sender:flags.7?Bool stories_ios_sound:flags.8?NotificationSound stories_android_sound:flags.9?NotificationSound stories_other_sound:flags.10?NotificationSound = PeerNotifySettings;
peerSettings#a518110d flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int = PeerSettings;
peerSettings#acd66c5e flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true business_bot_paused:flags.11?true business_bot_can_reply:flags.12?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int business_bot_id:flags.13?long business_bot_manage_url:flags.13?string = PeerSettings;
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
wallPaperNoFile#e0804116 id:long flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper;
@ -227,7 +228,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason;
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
userFull#22ff3e85 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage = UserFull;
userFull#cc997720 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int = UserFull;
contact#145ade0b user_id:long mutual:Bool = Contact;
@ -388,7 +389,6 @@ updateChannelPinnedTopic#192efbe3 flags:# pinned:flags.0?true channel_id:long to
updateChannelPinnedTopics#fe198602 flags:# channel_id:long order:flags.0?Vector<int> = Update;
updateUser#20529438 user_id:long = Update;
updateAutoSaveSettings#ec05b097 = Update;
updateGroupInvitePrivacyForbidden#ccf08ad6 user_id:long = Update;
updateStory#75b3b798 peer:Peer story:StoryItem = Update;
updateReadStories#f74e932b peer:Peer max_id:int = Update;
updateStoryID#1bf335b9 id:int random_id:long = Update;
@ -408,6 +408,10 @@ updateNewQuickReply#f53da717 quick_reply:QuickReply = Update;
updateDeleteQuickReply#53e6f1ec shortcut_id:int = Update;
updateQuickReplyMessage#3e050d0f message:Message = Update;
updateDeleteQuickReplyMessages#566fe7cd shortcut_id:int messages:Vector<int> = Update;
updateBotBusinessConnect#8ae5c97a connection:BotBusinessConnection qts:int = Update;
updateBotNewBusinessMessage#9ddb347c flags:# connection_id:string message:Message reply_to_message:flags.0?Message qts:int = Update;
updateBotEditBusinessMessage#7df587c flags:# connection_id:string message:Message reply_to_message:flags.0?Message qts:int = Update;
updateBotDeleteBusinessMessage#a02a982e connection_id:string peer:Peer messages:Vector<int> qts:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -513,6 +517,7 @@ inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey;
inputPrivacyKeyAddedByPhone#d1219bdd = InputPrivacyKey;
inputPrivacyKeyVoiceMessages#aee69d68 = InputPrivacyKey;
inputPrivacyKeyAbout#3823cc40 = InputPrivacyKey;
inputPrivacyKeyBirthday#d65a11cc = InputPrivacyKey;
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
privacyKeyChatInvite#500e6dfa = PrivacyKey;
@ -524,6 +529,7 @@ privacyKeyPhoneNumber#d19ae46d = PrivacyKey;
privacyKeyAddedByPhone#42ffd42b = PrivacyKey;
privacyKeyVoiceMessages#697f414 = PrivacyKey;
privacyKeyAbout#a486b761 = PrivacyKey;
privacyKeyBirthday#2000a518 = PrivacyKey;
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
@ -534,6 +540,7 @@ inputPrivacyValueDisallowUsers#90110467 users:Vector<InputUser> = InputPrivacyRu
inputPrivacyValueAllowChatParticipants#840649cf chats:Vector<long> = InputPrivacyRule;
inputPrivacyValueDisallowChatParticipants#e94f0f86 chats:Vector<long> = InputPrivacyRule;
inputPrivacyValueAllowCloseFriends#2f453e49 = InputPrivacyRule;
inputPrivacyValueAllowPremium#77cdc9f1 = InputPrivacyRule;
privacyValueAllowContacts#fffe1bac = PrivacyRule;
privacyValueAllowAll#65427b82 = PrivacyRule;
@ -544,6 +551,7 @@ privacyValueDisallowUsers#e4621141 users:Vector<long> = PrivacyRule;
privacyValueAllowChatParticipants#6b134e8e chats:Vector<long> = PrivacyRule;
privacyValueDisallowChatParticipants#41c87565 chats:Vector<long> = PrivacyRule;
privacyValueAllowCloseFriends#f7e8d89b = PrivacyRule;
privacyValueAllowPremium#ece9814b = PrivacyRule;
account.privacyRules#50a04e45 rules:Vector<PrivacyRule> chats:Vector<Chat> users:Vector<User> = account.PrivacyRules;
@ -606,7 +614,7 @@ inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = InputStickerSet;
inputStickerSetEmojiChannelDefaultStatuses#49748553 = 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 text_color:flags.9?true channel_emoji_status:flags.10?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true emojis:flags.7?true text_color:flags.9?true channel_emoji_status:flags.10?true creator:flags.11?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet;
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
@ -631,6 +639,7 @@ keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
keyboardButtonWebView#13767230 text:string url:string = KeyboardButton;
keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton;
keyboardButtonRequestPeer#53d7bfd8 text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton;
inputKeyboardButtonRequestPeer#c9662d05 flags:# name_requested:flags.0?true username_requested:flags.1?true photo_requested:flags.2?true text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton;
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
@ -915,7 +924,7 @@ phoneCallEmpty#5366c915 id:long = PhoneCall;
phoneCallWaiting#c5226f17 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
phoneCallRequested#14b0ed0c flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCallAccepted#3660c311 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCall#967f7c67 flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector<PhoneConnection> start_date:int = PhoneCall;
phoneCall#30535af5 flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector<PhoneConnection> start_date:int custom_parameters:flags.7?DataJSON = PhoneCall;
phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.6?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
phoneConnection#9cc123c7 flags:# tcp:flags.0?true id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection;
@ -1352,7 +1361,7 @@ account.resetPasswordFailedWait#e3779861 retry_date:int = account.ResetPasswordR
account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult;
account.resetPasswordOk#e926d63e = account.ResetPasswordResult;
sponsoredMessage#ed5383f7 flags:# recommended:flags.5?true show_peer_photo:flags.6?true random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string webpage:flags.9?SponsoredWebPage app:flags.10?BotApp message:string entities:flags.1?Vector<MessageEntity> button_text:flags.11?string sponsor_info:flags.7?string additional_info:flags.8?string = SponsoredMessage;
sponsoredMessage#ed5383f7 flags:# recommended:flags.5?true show_peer_photo:flags.6?true can_report:flags.12?true random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string webpage:flags.9?SponsoredWebPage app:flags.10?BotApp message:string entities:flags.1?Vector<MessageEntity> button_text:flags.11?string sponsor_info:flags.7?string additional_info:flags.8?string = SponsoredMessage;
messages.sponsoredMessages#c9ee1d87 flags:# posts_between:flags.0?int messages:Vector<SponsoredMessage> chats:Vector<Chat> users:Vector<User> = messages.SponsoredMessages;
messages.sponsoredMessagesEmpty#1839490f = messages.SponsoredMessages;
@ -1700,12 +1709,67 @@ inputQuickReplyShortcutId#1190cf1 shortcut_id:int = InputQuickReplyShortcut;
messages.quickReplies#c68d6695 quick_replies:Vector<QuickReply> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.QuickReplies;
messages.quickRepliesNotModified#5f91eb5b = messages.QuickReplies;
connectedBot#e7e999e7 flags:# can_reply:flags.0?true bot_id:long recipients:BusinessRecipients = ConnectedBot;
connectedBot#bd068601 flags:# can_reply:flags.0?true bot_id:long recipients:BusinessBotRecipients = ConnectedBot;
account.connectedBots#17d7f87b connected_bots:Vector<ConnectedBot> users:Vector<User> = account.ConnectedBots;
messages.dialogFilters#2ad93719 flags:# tags_enabled:flags.0?true filters:Vector<DialogFilter> = messages.DialogFilters;
birthday#6c8e1e06 flags:# day:int month:int year:flags.0?int = Birthday;
botBusinessConnection#896433b4 flags:# can_reply:flags.0?true disabled:flags.1?true connection_id:string user_id:long dc_id:int date:int = BotBusinessConnection;
inputBusinessIntro#9c469cd flags:# title:string description:string sticker:flags.0?InputDocument = InputBusinessIntro;
businessIntro#5a0a066d flags:# title:string description:string sticker:flags.0?Document = BusinessIntro;
messages.myStickers#faff629d count:int sets:Vector<StickerSetCovered> = messages.MyStickers;
inputCollectibleUsername#e39460a9 username:string = InputCollectible;
inputCollectiblePhone#a2e214a4 phone:string = InputCollectible;
fragment.collectibleInfo#6ebdff91 purchase_date:int currency:string amount:long crypto_currency:string crypto_amount:long url:string = fragment.CollectibleInfo;
inputBusinessBotRecipients#c4e5921e flags:# existing_chats:flags.0?true new_chats:flags.1?true contacts:flags.2?true non_contacts:flags.3?true exclude_selected:flags.5?true users:flags.4?Vector<InputUser> exclude_users:flags.6?Vector<InputUser> = InputBusinessBotRecipients;
businessBotRecipients#b88cf373 flags:# existing_chats:flags.0?true new_chats:flags.1?true contacts:flags.2?true non_contacts:flags.3?true exclude_selected:flags.5?true users:flags.4?Vector<long> exclude_users:flags.6?Vector<long> = BusinessBotRecipients;
contactBirthday#1d998733 contact_id:long birthday:Birthday = ContactBirthday;
contacts.contactBirthdays#114ff30d contacts:Vector<ContactBirthday> users:Vector<User> = contacts.ContactBirthdays;
missingInvitee#628c9224 flags:# premium_would_allow_invite:flags.0?true premium_required_for_pm:flags.1?true user_id:long = MissingInvitee;
messages.invitedUsers#7f5defa6 updates:Updates missing_invitees:Vector<MissingInvitee> = messages.InvitedUsers;
inputBusinessChatLink#11679fa7 flags:# message:string entities:flags.0?Vector<MessageEntity> title:flags.1?string = InputBusinessChatLink;
businessChatLink#b4ae666f flags:# link:string message:string entities:flags.0?Vector<MessageEntity> title:flags.1?string views:int = BusinessChatLink;
account.businessChatLinks#ec43a2d1 links:Vector<BusinessChatLink> chats:Vector<Chat> users:Vector<User> = account.BusinessChatLinks;
account.resolvedBusinessChatLinks#9a23af21 flags:# peer:Peer message:string entities:flags.0?Vector<MessageEntity> chats:Vector<Chat> users:Vector<User> = account.ResolvedBusinessChatLinks;
requestedPeerUser#d62ff46a flags:# user_id:long first_name:flags.0?string last_name:flags.0?string username:flags.1?string photo:flags.2?Photo = RequestedPeer;
requestedPeerChat#7307544f flags:# chat_id:long title:flags.0?string photo:flags.2?Photo = RequestedPeer;
requestedPeerChannel#8ba403e4 flags:# channel_id:long title:flags.0?string username:flags.1?string photo:flags.2?Photo = RequestedPeer;
sponsoredMessageReportOption#430d3150 text:string option:bytes = SponsoredMessageReportOption;
channels.sponsoredMessageReportResultChooseOption#846f9e42 title:string options:Vector<SponsoredMessageReportOption> = channels.SponsoredMessageReportResult;
channels.sponsoredMessageReportResultAdsHidden#3e3bcf2f = channels.SponsoredMessageReportResult;
channels.sponsoredMessageReportResultReported#ad798849 = channels.SponsoredMessageReportResult;
stats.broadcastRevenueStats#d07b4bad top_hours_graph:StatsGraph revenue_graph:StatsGraph current_balance:long available_balance:long overall_revenue:long usd_rate:double = stats.BroadcastRevenueStats;
stats.broadcastRevenueWithdrawalUrl#ec659737 url:string = stats.BroadcastRevenueWithdrawalUrl;
broadcastRevenueTransactionProceeds#557e2cc4 amount:long from_date:int to_date:int = BroadcastRevenueTransaction;
broadcastRevenueTransactionWithdrawal#5a590978 flags:# pending:flags.0?true failed:flags.2?true amount:long date:int provider:string transaction_date:flags.1?int transaction_url:flags.1?string = BroadcastRevenueTransaction;
broadcastRevenueTransactionRefund#42d30d2e amount:long date:int provider:string = BroadcastRevenueTransaction;
stats.broadcastRevenueTransactions#87158466 count:int transactions:Vector<BroadcastRevenueTransaction> = stats.BroadcastRevenueTransactions;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1715,6 +1779,7 @@ invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
invokeWithBusinessConnection#dd289f8e {X:Type} connection_id:string query:!X = X;
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
auth.signUp#aac7b717 flags:# no_joined_notifications:flags.0?true phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization;
@ -1835,8 +1900,19 @@ account.updateBusinessWorkHours#4b00e066 flags:# business_work_hours:flags.0?Bus
account.updateBusinessLocation#9e6b131a flags:# geo_point:flags.1?InputGeoPoint address:flags.0?string = Bool;
account.updateBusinessGreetingMessage#66cdafc4 flags:# message:flags.0?InputBusinessGreetingMessage = Bool;
account.updateBusinessAwayMessage#a26a7fa5 flags:# message:flags.0?InputBusinessAwayMessage = Bool;
account.updateConnectedBot#9c2d527d flags:# can_reply:flags.0?true deleted:flags.1?true bot:InputUser recipients:InputBusinessRecipients = Updates;
account.updateConnectedBot#43d8521d flags:# can_reply:flags.0?true deleted:flags.1?true bot:InputUser recipients:InputBusinessBotRecipients = Updates;
account.getConnectedBots#4ea4c80f = account.ConnectedBots;
account.getBotBusinessConnection#76a86270 connection_id:string = Updates;
account.updateBusinessIntro#a614d034 flags:# intro:flags.0?InputBusinessIntro = Bool;
account.toggleConnectedBotPaused#646e1097 peer:InputPeer paused:Bool = Bool;
account.disablePeerConnectedBot#5e437ed9 peer:InputPeer = Bool;
account.updateBirthday#cc6e0c11 flags:# birthday:flags.0?Birthday = Bool;
account.createBusinessChatLink#8851e68e link:InputBusinessChatLink = BusinessChatLink;
account.editBusinessChatLink#8c3410af slug:string link:InputBusinessChatLink = BusinessChatLink;
account.deleteBusinessChatLink#60073674 slug:string = Bool;
account.getBusinessChatLinks#6f70dde1 = account.BusinessChatLinks;
account.resolveBusinessChatLink#5492e5ee slug:string = account.ResolvedBusinessChatLinks;
account.updatePersonalChannel#d94305e0 channel:InputChannel = Bool;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
@ -1868,6 +1944,7 @@ contacts.exportContactToken#f8654027 = ExportedContactToken;
contacts.importContactToken#13005788 token:string = User;
contacts.editCloseFriends#ba6705f0 id:Vector<long> = Bool;
contacts.setBlocked#94c65c76 flags:# my_stories_from:flags.0?true id:Vector<InputPeer> limit:int = Bool;
contacts.getBirthdays#daeda864 = contacts.ContactBirthdays;
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
messages.getDialogs#a0f4cb4f flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.Dialogs;
@ -1888,9 +1965,9 @@ messages.getChats#49e9528f id:Vector<long> = messages.Chats;
messages.getFullChat#aeb00b34 chat_id:long = messages.ChatFull;
messages.editChatTitle#73783ffd chat_id:long title:string = Updates;
messages.editChatPhoto#35ddd674 chat_id:long photo:InputChatPhoto = Updates;
messages.addChatUser#f24753e3 chat_id:long user_id:InputUser fwd_limit:int = Updates;
messages.addChatUser#cbc6d107 chat_id:long user_id:InputUser fwd_limit:int = messages.InvitedUsers;
messages.deleteChatUser#a2185cab flags:# revoke_history:flags.0?true chat_id:long user_id:InputUser = Updates;
messages.createChat#34a818 flags:# users:Vector<InputUser> title:string ttl_period:flags.0?int = Updates;
messages.createChat#92ceddd4 flags:# users:Vector<InputUser> title:string ttl_period:flags.0?int = messages.InvitedUsers;
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
@ -1951,7 +2028,7 @@ messages.reorderPinnedDialogs#3b1adf37 flags:# force:flags.0?true folder_id:int
messages.getPinnedDialogs#d6b94df2 folder_id:int = messages.PeerDialogs;
messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = Bool;
messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool;
messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia;
messages.uploadMedia#14967978 flags:# business_connection_id:flags.0?string peer:InputPeer media:InputMedia = MessageMedia;
messages.sendScreenshotNotification#a1405817 peer:InputPeer reply_to:InputReplyTo random_id:long = Updates;
messages.getFavedStickers#4f1aaa9 hash:long = messages.FavedStickers;
messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
@ -2073,9 +2150,10 @@ messages.checkQuickReplyShortcut#f1d0fbd3 shortcut:string = Bool;
messages.editQuickReplyShortcut#5c003cef shortcut_id:int shortcut:string = Bool;
messages.deleteQuickReplyShortcut#3cc04740 shortcut_id:int = Bool;
messages.getQuickReplyMessages#94a495c3 flags:# shortcut_id:int id:flags.0?Vector<int> hash:long = messages.Messages;
messages.sendQuickReplyMessages#33153ad4 peer:InputPeer shortcut_id:int = Updates;
messages.sendQuickReplyMessages#6c750de1 peer:InputPeer shortcut_id:int id:Vector<int> random_id:Vector<long> = Updates;
messages.deleteQuickReplyMessages#e105e910 shortcut_id:int id:Vector<int> = Updates;
messages.toggleDialogFilterTags#fd2dda49 enabled:Bool = Bool;
messages.getMyStickers#d0b5e1fc offset_id:long limit:int = messages.MyStickers;
updates.getState#edd4882a = updates.State;
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
@ -2138,11 +2216,11 @@ channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool;
channels.updateUsername#3514b3de channel:InputChannel username:string = Bool;
channels.joinChannel#24b524c5 channel:InputChannel = Updates;
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
channels.inviteToChannel#c9e33d54 channel:InputChannel users:Vector<InputUser> = messages.InvitedUsers;
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink;
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true = messages.Chats;
channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true for_personal:flags.2?true = messages.Chats;
channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates;
channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector<InputUser> max_id:long min_id:long limit:int = channels.AdminLogResults;
channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool;
@ -2184,6 +2262,8 @@ channels.getChannelRecommendations#83b70d97 channel:InputChannel = messages.Chat
channels.updateEmojiStatus#f0d3e6a8 channel:InputChannel emoji_status:EmojiStatus = Updates;
channels.setBoostsToUnblockRestrictions#ad399cee channel:InputChannel boosts:int = Updates;
channels.setEmojiStickers#3cd930b7 channel:InputChannel stickerset:InputStickerSet = Bool;
channels.reportSponsoredMessage#af8ff6b9 channel:InputChannel random_id:bytes option:bytes = channels.SponsoredMessageReportResult;
channels.restrictSponsoredMessages#9ae91519 channel:InputChannel restricted:Bool = Updates;
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
@ -2219,7 +2299,7 @@ payments.applyGiftCode#f6e26854 slug:string = Updates;
payments.getGiveawayInfo#f4239425 peer:InputPeer msg_id:int = payments.GiveawayInfo;
payments.launchPrepaidGiveaway#5ff58f20 peer:InputPeer giveaway_id:long purpose:InputStorePaymentPurpose = Updates;
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = messages.StickerSet;
stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet;
@ -2229,6 +2309,7 @@ stickers.suggestShortName#4dafc503 title:string = stickers.SuggestedShortName;
stickers.changeSticker#f5537ebc flags:# sticker:InputDocument emoji:flags.0?string mask_coords:flags.1?MaskCoords keywords:flags.2?string = messages.StickerSet;
stickers.renameStickerSet#124b1c00 stickerset:InputStickerSet title:string = messages.StickerSet;
stickers.deleteStickerSet#87704394 stickerset:InputStickerSet = Bool;
stickers.replaceSticker#4696459a sticker:InputDocument new_sticker:InputStickerSetItem = messages.StickerSet;
phone.getCallConfig#55451fa9 = DataJSON;
phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
@ -2277,6 +2358,9 @@ stats.getMessagePublicForwards#5f150144 channel:InputChannel msg_id:int offset:s
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
stats.getStoryStats#374fef40 flags:# dark:flags.0?true peer:InputPeer id:int = stats.StoryStats;
stats.getStoryPublicForwards#a6437ef6 peer:InputPeer id:int offset:string limit:int = stats.PublicForwards;
stats.getBroadcastRevenueStats#75dfb671 flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastRevenueStats;
stats.getBroadcastRevenueWithdrawalUrl#2a65ef73 channel:InputChannel password:InputCheckPasswordSRP = stats.BroadcastRevenueWithdrawalUrl;
stats.getBroadcastRevenueTransactions#69280f channel:InputChannel offset:int limit:int = stats.BroadcastRevenueTransactions;
chatlists.exportChatlistInvite#8472478e chatlist:InputChatlist title:string peers:Vector<InputPeer> = chatlists.ExportedChatlistInvite;
chatlists.deleteExportedInvite#719c5c5e chatlist:InputChatlist slug:string = Bool;
@ -2328,3 +2412,5 @@ smsjobs.updateSettings#93fa0bf flags:# allow_international:flags.0?true = Bool;
smsjobs.getStatus#10a698e8 = smsjobs.Status;
smsjobs.getSmsJob#778d902f job_id:string = SmsJob;
smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool;
fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo;

View File

@ -123,6 +123,7 @@ export interface ApiPrivacySettings {
allowChatIds: string[];
blockUserIds: string[];
blockChatIds: string[];
shouldAllowPremium?: true;
}
export interface ApiInputPrivacyRules {
@ -132,6 +133,7 @@ export interface ApiInputPrivacyRules {
allowedChats?: ApiChat[];
blockedUsers?: ApiUser[];
blockedChats?: ApiChat[];
shouldAllowPremium?: true;
}
export type IAnchorPosition = {
@ -250,8 +252,8 @@ export enum SettingsScreens {
}
export type StickerSetOrReactionsSetOrRecent = Pick<ApiStickerSet, (
'id' | 'accessHash' | 'title' | 'count' | 'stickers' | 'hasThumbnail' | 'isLottie' | 'isVideos' | 'isEmoji' |
'installedDate' | 'isArchived'
'id' | 'accessHash' | 'title' | 'count' | 'stickers' | 'isEmoji' | 'installedDate' | 'isArchived' |
'hasThumbnail' | 'hasStaticThumb' | 'hasAnimatedThumb' | 'hasVideoThumb' | 'thumbCustomEmojiId'
)> & { reactions?: ApiReaction[] };
export enum LeftColumnContent {

View File

@ -8,119 +8,98 @@ export type PopupOptions = {
}[];
};
export type WebAppInboundEvent = {
eventType: 'iframe_ready';
eventData: {
type WebAppEvent<T, D> = D extends null ? {
eventType: T;
eventData?: undefined;
} : {
eventType: T;
eventData: D;
};
export type WebAppInboundEvent =
WebAppEvent<'iframe_ready', {
reload_supported?: boolean;
};
} | {
eventType: 'web_app_data_send';
eventData: {
}> |
WebAppEvent<'web_app_data_send', {
data: string;
};
} | {
eventType: 'web_app_setup_main_button';
eventData: {
}> |
WebAppEvent<'web_app_setup_main_button', {
is_visible: boolean;
is_active: boolean;
text: string;
color: string;
text_color: string;
is_progress_visible: boolean;
};
} | {
eventType: 'web_app_setup_back_button';
eventData: {
}> |
WebAppEvent<'web_app_setup_back_button', {
is_visible: boolean;
};
} | {
eventType: 'web_app_setup_settings_button';
eventData: {
}> |
WebAppEvent<'web_app_setup_settings_button', {
is_visible: boolean;
};
} | {
eventType: 'web_app_open_link';
eventData: {
}> |
WebAppEvent<'web_app_open_link', {
url: string;
try_instant_view?: boolean;
};
} | {
eventType: 'web_app_open_tg_link';
eventData: {
}> |
WebAppEvent<'web_app_open_tg_link', {
path_full: string;
};
} | {
eventType: 'web_app_open_invoice';
eventData: {
}> |
WebAppEvent<'web_app_open_invoice', {
slug: string;
};
} | {
eventType: 'web_app_trigger_haptic_feedback';
eventData: {
}> |
WebAppEvent<'web_app_trigger_haptic_feedback', {
type: 'impact' | 'notification' | 'selection_change';
impact_style?: 'light' | 'medium' | 'heavy';
notification_type?: 'error' | 'success' | 'warning';
};
} | {
eventType: 'web_app_set_background_color';
eventData: {
}> |
WebAppEvent<'web_app_set_background_color', {
color: string;
};
} | {
eventType: 'web_app_set_header_color';
eventData: {
}> |
WebAppEvent<'web_app_set_header_color', {
color_key?: 'bg_color' | 'secondary_bg_color';
color?: string;
};
} | {
eventType: 'web_app_open_popup';
eventData: PopupOptions;
} | {
eventType: 'web_app_setup_closing_behavior';
eventData: {
}> |
WebAppEvent<'web_app_open_popup', PopupOptions> |
WebAppEvent<'web_app_setup_closing_behavior', {
need_confirmation: boolean;
};
} | {
eventType: 'web_app_open_scan_qr_popup';
eventData: {
}> |
WebAppEvent<'web_app_open_scan_qr_popup', {
text?: string;
};
} | {
eventType: 'web_app_read_text_from_clipboard';
eventData: {
}> |
WebAppEvent<'web_app_read_text_from_clipboard', {
req_id: string;
};
} | {
eventType: 'web_app_switch_inline_query';
eventData: {
}> |
WebAppEvent<'web_app_switch_inline_query', {
query: string;
chat_types: ('users' | 'bots' | 'groups' | 'channels')[];
};
} | {
eventType: 'web_app_invoke_custom_method';
eventData: {
}> |
WebAppEvent<'web_app_invoke_custom_method', {
req_id: string;
method: string;
params: object;
};
} | {
eventType: 'web_app_request_viewport' | 'web_app_request_theme' | 'web_app_ready' | 'web_app_expand'
}> |
WebAppEvent<'web_app_biometry_request_access', {
reason: string;
}> |
WebAppEvent<'web_app_biometry_request_auth', {
reason: string;
}> |
WebAppEvent<'web_app_biometry_update_token', {
token: string;
}> |
WebAppEvent<'web_app_request_viewport' | 'web_app_request_theme' | 'web_app_ready' | 'web_app_expand'
| 'web_app_request_phone' | 'web_app_close' | 'web_app_close_scan_qr_popup'
| 'web_app_request_write_access' | 'web_app_request_phone' | 'iframe_will_reload';
eventData: null;
};
| 'web_app_request_write_access' | 'web_app_request_phone' | 'iframe_will_reload'
| 'web_app_biometry_get_info' | 'web_app_biometry_open_settings', null>;
export type WebAppOutboundEvent = {
eventType: 'viewport_changed';
eventData: {
export type WebAppOutboundEvent =
WebAppEvent<'viewport_changed', {
height: number;
width?: number;
is_expanded?: boolean;
is_state_stable?: boolean;
};
} | {
eventType: 'theme_changed';
eventData: {
}> |
WebAppEvent<'theme_changed', {
theme_params: {
bg_color: string;
text_color: string;
@ -130,57 +109,56 @@ export type WebAppOutboundEvent = {
button_text_color: string;
secondary_bg_color: string;
};
};
} | {
eventType: 'set_custom_style';
eventData: string;
} | {
eventType: 'invoice_closed';
eventData: {
}> |
WebAppEvent<'set_custom_style', string> |
WebAppEvent<'invoice_closed', {
slug: string;
status: 'paid' | 'cancelled' | 'pending' | 'failed';
};
} | {
eventType: 'phone_requested';
eventData: {
}> |
WebAppEvent<'phone_requested', {
phone_number: string;
};
} | {
eventType: 'popup_closed';
eventData: {
}> |
WebAppEvent<'popup_closed', {
button_id?: string;
};
} | {
eventType: 'qr_text_received';
eventData: {
}> |
WebAppEvent<'qr_text_received', {
data: string;
};
} | {
eventType: 'clipboard_text_received';
eventData: {
}> |
WebAppEvent<'clipboard_text_received', {
req_id: string;
data: string | null;
};
} | {
eventType: 'write_access_requested';
eventData: {
}> |
WebAppEvent<'write_access_requested', {
status: 'allowed' | 'cancelled';
};
} | {
eventType: 'phone_requested';
eventData: {
}> |
WebAppEvent<'phone_requested', {
status: 'sent' | 'cancelled';
};
} | {
eventType: 'custom_method_invoked';
eventData: {
}> |
WebAppEvent<'custom_method_invoked', {
req_id: string;
} & ({
result: object;
} | {
error: string;
});
} | {
eventType: 'main_button_pressed' | 'back_button_pressed' | 'settings_button_pressed' | 'scan_qr_popup_closed'
| 'reload_iframe';
};
})> |
WebAppEvent<'biometry_info_received', {
available: false;
} | {
available: true;
type: 'finger' | 'face' | 'unknown';
access_requested: boolean;
access_granted: boolean;
token_saved: boolean;
device_id: string;
}> |
WebAppEvent<'biometry_auth_requested', {
status: 'authorized';
token: string;
} | {
status: 'failed';
}> |
WebAppEvent<'biometry_token_updated', {
status: 'updated' | 'removed' | 'failed';
}> |
WebAppEvent<'main_button_pressed' | 'back_button_pressed' | 'settings_button_pressed' | 'scan_qr_popup_closed'
| 'reload_iframe', null>;