This commit is contained in:
Alexander Zinchuk 2023-12-28 14:38:19 +01:00
parent 6a8e685561
commit 8dbc9a590e
46 changed files with 1014 additions and 342 deletions

View File

@ -19,13 +19,17 @@ import type {
ApiTopic, ApiTopic,
} from '../../types'; } from '../../types';
import { pick, pickTruthy } from '../../../util/iteratees'; import { omitUndefined, pick, pickTruthy } from '../../../util/iteratees';
import { getServerTime, getServerTimeOffset } from '../../../util/serverTime'; import { getServerTime, getServerTimeOffset } from '../../../util/serverTime';
import { buildApiUsernames } from './common'; import { buildApiUsernames } from './common';
import { omitVirtualClassFields } from './helpers'; import { omitVirtualClassFields } from './helpers';
import { import {
buildApiEmojiStatus,
buildApiPeerColor, buildApiPeerColor,
buildApiPeerId, getApiChatIdFromMtpPeer, isPeerChat, isPeerUser, buildApiPeerId,
getApiChatIdFromMtpPeer,
isPeerChat,
isPeerUser,
} from './peers'; } from './peers';
import { buildApiReaction } from './reactions'; import { buildApiReaction } from './reactions';
@ -40,10 +44,10 @@ function buildApiChatFieldsFromPeerEntity(
isSupport = false, isSupport = false,
): PeerEntityApiChatFields { ): PeerEntityApiChatFields {
const isMin = Boolean('min' in peerEntity && peerEntity.min); const isMin = Boolean('min' in peerEntity && peerEntity.min);
const accessHash = ('accessHash' in peerEntity) && String(peerEntity.accessHash); const accessHash = ('accessHash' in peerEntity) ? String(peerEntity.accessHash) : undefined;
const hasVideoAvatar = 'photo' in peerEntity && peerEntity.photo && 'hasVideo' in peerEntity.photo const hasVideoAvatar = 'photo' in peerEntity && peerEntity.photo && 'hasVideo' in peerEntity.photo
&& peerEntity.photo.hasVideo; && peerEntity.photo.hasVideo;
const avatarHash = ('photo' in peerEntity) && peerEntity.photo && buildAvatarHash(peerEntity.photo); const avatarHash = ('photo' in peerEntity) && peerEntity.photo ? buildAvatarHash(peerEntity.photo) : undefined;
const isSignaturesShown = Boolean('signatures' in peerEntity && peerEntity.signatures); const isSignaturesShown = Boolean('signatures' in peerEntity && peerEntity.signatures);
const hasPrivateLink = Boolean('hasLink' in peerEntity && peerEntity.hasLink); const hasPrivateLink = Boolean('hasLink' in peerEntity && peerEntity.hasLink);
const isScam = Boolean('scam' in peerEntity && peerEntity.scam); const isScam = Boolean('scam' in peerEntity && peerEntity.scam);
@ -56,15 +60,17 @@ function buildApiChatFieldsFromPeerEntity(
const maxStoryId = 'storiesMaxId' in peerEntity ? peerEntity.storiesMaxId : undefined; const maxStoryId = 'storiesMaxId' in peerEntity ? peerEntity.storiesMaxId : undefined;
const storiesUnavailable = Boolean('storiesUnavailable' in peerEntity && peerEntity.storiesUnavailable); const storiesUnavailable = Boolean('storiesUnavailable' in peerEntity && peerEntity.storiesUnavailable);
const color = ('color' in peerEntity && peerEntity.color) ? buildApiPeerColor(peerEntity.color) : undefined; const color = ('color' in peerEntity && peerEntity.color) ? buildApiPeerColor(peerEntity.color) : undefined;
const emojiStatus = ('emojiStatus' in peerEntity && peerEntity.emojiStatus)
? buildApiEmojiStatus(peerEntity.emojiStatus) : undefined;
return { return omitUndefined({
isMin, isMin,
hasPrivateLink, hasPrivateLink,
isSignaturesShown, isSignaturesShown,
usernames, usernames,
...(accessHash && { accessHash }), accessHash,
hasVideoAvatar, hasVideoAvatar,
...(avatarHash && { avatarHash }), avatarHash,
...('verified' in peerEntity && { isVerified: peerEntity.verified }), ...('verified' in peerEntity && { isVerified: peerEntity.verified }),
...('callActive' in peerEntity && { isCallActive: peerEntity.callActive }), ...('callActive' in peerEntity && { isCallActive: peerEntity.callActive }),
...('callNotEmpty' in peerEntity && { isCallNotEmpty: peerEntity.callNotEmpty }), ...('callNotEmpty' in peerEntity && { isCallNotEmpty: peerEntity.callNotEmpty }),
@ -73,7 +79,7 @@ function buildApiChatFieldsFromPeerEntity(
membersCount: peerEntity.participantsCount, membersCount: peerEntity.participantsCount,
}), }),
...('noforwards' in peerEntity && { isProtected: Boolean(peerEntity.noforwards) }), ...('noforwards' in peerEntity && { isProtected: Boolean(peerEntity.noforwards) }),
...(isSupport && { isSupport: true }), isSupport: isSupport || undefined,
...buildApiChatPermissions(peerEntity), ...buildApiChatPermissions(peerEntity),
...('creator' in peerEntity && { isCreator: peerEntity.creator }), ...('creator' in peerEntity && { isCreator: peerEntity.creator }),
...buildApiChatRestrictions(peerEntity), ...buildApiChatRestrictions(peerEntity),
@ -86,7 +92,8 @@ function buildApiChatFieldsFromPeerEntity(
areStoriesHidden, areStoriesHidden,
maxStoryId, maxStoryId,
hasStories: Boolean(maxStoryId) && !storiesUnavailable, hasStories: Boolean(maxStoryId) && !storiesUnavailable,
}; emojiStatus,
});
} }
export function buildApiChatFromDialog( export function buildApiChatFromDialog(

View File

@ -7,6 +7,7 @@ import type {
ApiFormattedText, ApiFormattedText,
ApiGame, ApiGame,
ApiGiveaway, ApiGiveaway,
ApiGiveawayResults,
ApiInvoice, ApiInvoice,
ApiLocation, ApiLocation,
ApiMessageExtendedMediaPreview, ApiMessageExtendedMediaPreview,
@ -122,6 +123,9 @@ export function buildMessageMediaContent(media: GramJs.TypeMessageMedia): MediaC
const giveaway = buildGiweawayFromMedia(media); const giveaway = buildGiweawayFromMedia(media);
if (giveaway) return { giveaway }; if (giveaway) return { giveaway };
const giveawayResults = buildGiweawayResultsFromMedia(media);
if (giveawayResults) return { giveawayResults };
return undefined; return undefined;
} }
@ -480,7 +484,7 @@ function buildGiweawayFromMedia(media: GramJs.TypeMessageMedia): ApiGiveaway | u
function buildGiveaway(media: GramJs.MessageMediaGiveaway): ApiGiveaway | undefined { function buildGiveaway(media: GramJs.MessageMediaGiveaway): ApiGiveaway | undefined {
const { const {
channels, months, quantity, untilDate, countriesIso2, onlyNewSubscribers, channels, months, quantity, untilDate, countriesIso2, onlyNewSubscribers, prizeDescription,
} = media; } = media;
const channelIds = channels.map((channel) => buildApiPeerId(channel, 'channel')); const channelIds = channels.map((channel) => buildApiPeerId(channel, 'channel'));
@ -492,6 +496,38 @@ function buildGiveaway(media: GramJs.MessageMediaGiveaway): ApiGiveaway | undefi
untilDate, untilDate,
countries: countriesIso2, countries: countriesIso2,
isOnlyForNewSubscribers: onlyNewSubscribers, isOnlyForNewSubscribers: onlyNewSubscribers,
prizeDescription,
};
}
function buildGiweawayResultsFromMedia(media: GramJs.TypeMessageMedia): ApiGiveawayResults | undefined {
if (!(media instanceof GramJs.MessageMediaGiveawayResults)) {
return undefined;
}
return buildGiveawayResults(media);
}
function buildGiveawayResults(media: GramJs.MessageMediaGiveawayResults): ApiGiveawayResults | undefined {
const {
months, untilDate, onlyNewSubscribers, launchMsgId, unclaimedCount, winners, winnersCount,
additionalPeersCount, prizeDescription, refunded, channelId,
} = media;
const winnerIds = winners.map((winner) => buildApiPeerId(winner, 'user'));
return {
months,
untilDate,
isOnlyForNewSubscribers: onlyNewSubscribers,
launchMessageId: launchMsgId,
channelId: buildApiPeerId(channelId, 'channel'),
unclaimedCount,
additionalPeersCount,
isRefunded: refunded,
prizeDescription,
winnerIds,
winnersCount,
}; };
} }

View File

@ -248,7 +248,7 @@ export function buildApiGiveawayInfo(info: GramJs.payments.TypeGiveawayInfo): Ap
type: 'active', type: 'active',
startDate, startDate,
isParticipating: participating, isParticipating: participating,
adminDisallowedChatId: adminDisallowedChatId?.toString(), adminDisallowedChatId: adminDisallowedChatId && buildApiPeerId(adminDisallowedChatId, 'channel'),
disallowedCountry, disallowedCountry,
joinedTooEarlyDate, joinedTooEarlyDate,
isPreparingResults: preparingResults, isPreparingResults: preparingResults,

View File

@ -1,7 +1,7 @@
import type BigInt from 'big-integer'; import type BigInt from 'big-integer';
import { Api as GramJs } from '../../../lib/gramjs';
import type { Api as GramJs } from '../../../lib/gramjs'; import type { ApiEmojiStatus, ApiPeerColor } from '../../types';
import type { ApiPeerColor } from '../../types';
export function isPeerUser(peer: GramJs.TypePeer | GramJs.TypeInputPeer): peer is GramJs.PeerUser { export function isPeerUser(peer: GramJs.TypePeer | GramJs.TypeInputPeer): peer is GramJs.PeerUser {
return peer.hasOwnProperty('userId'); return peer.hasOwnProperty('userId');
@ -44,3 +44,15 @@ export function buildApiPeerColor(peerColor: GramJs.TypePeerColor): ApiPeerColor
backgroundEmojiId: backgroundEmojiId?.toString(), backgroundEmojiId: backgroundEmojiId?.toString(),
}; };
} }
export function buildApiEmojiStatus(mtpEmojiStatus: GramJs.TypeEmojiStatus): ApiEmojiStatus | undefined {
if (mtpEmojiStatus instanceof GramJs.EmojiStatus) {
return { documentId: mtpEmojiStatus.documentId.toString() };
}
if (mtpEmojiStatus instanceof GramJs.EmojiStatusUntil) {
return { documentId: mtpEmojiStatus.documentId.toString(), until: mtpEmojiStatus.until };
}
return undefined;
}

View File

@ -5,14 +5,17 @@ import type {
ApiMediaAreaCoordinates, ApiMediaAreaCoordinates,
ApiStealthMode, ApiStealthMode,
ApiStoryForwardInfo, ApiStoryForwardInfo,
ApiStoryView, ApiStoryViews, ApiStoryView,
ApiStoryViews,
ApiTypeStory, ApiTypeStory,
ApiTypeStoryView,
MediaContent, MediaContent,
} from '../../types'; } from '../../types';
import { buildCollectionByCallback } from '../../../util/iteratees'; import { buildCollectionByCallback, omitUndefined } from '../../../util/iteratees';
import { buildPrivacyRules } from './common'; import { buildPrivacyRules } from './common';
import { buildGeoPoint, buildMessageMediaContent, buildMessageTextContent } from './messageContent'; import { buildGeoPoint, buildMessageMediaContent, buildMessageTextContent } from './messageContent';
import { buildApiMessage } from './messages';
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers'; import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
import { buildApiReaction, buildReactionCount } from './reactions'; import { buildApiReaction, buildReactionCount } from './reactions';
@ -88,17 +91,53 @@ function buildApiStoryViews(views: GramJs.TypeStoryViews): ApiStoryViews | undef
}; };
} }
export function buildApiStoryView(view: GramJs.TypeStoryView): ApiStoryView { export function buildApiStoryView(view: GramJs.TypeStoryView): ApiTypeStoryView | undefined {
const { const {
userId, date, reaction, blockedMyStoriesFrom, blocked, blockedMyStoriesFrom, blocked,
} = view; } = view;
return {
userId: userId.toString(), if (view instanceof GramJs.StoryView) {
date, return omitUndefined<ApiStoryView>({
...(reaction && { reaction: buildApiReaction(reaction) }), type: 'user',
areStoriesBlocked: blocked || blockedMyStoriesFrom, peerId: buildApiPeerId(view.userId, 'user'),
isUserBlocked: blocked, date: view.date,
}; reaction: view.reaction && buildApiReaction(view.reaction),
areStoriesBlocked: blocked || blockedMyStoriesFrom,
isUserBlocked: blocked,
});
}
if (view instanceof GramJs.StoryViewPublicForward) {
const message = buildApiMessage(view.message);
if (!message) return undefined;
return {
type: 'forward',
peerId: message.chatId,
messageId: message.id,
message,
date: message.date,
areStoriesBlocked: blocked || blockedMyStoriesFrom,
isUserBlocked: blocked,
};
}
if (view instanceof GramJs.StoryViewPublicRepost) {
const peerId = getApiChatIdFromMtpPeer(view.peerId);
const story = buildApiStory(peerId, view.story);
if (!('content' in story)) return undefined;
return {
type: 'repost',
peerId,
storyId: view.story.id,
date: story.date,
story,
areStoriesBlocked: blocked || blockedMyStoriesFrom,
isUserBlocked: blocked,
};
}
return undefined;
} }
export function buildApiStealthMode(stealthMode: GramJs.TypeStoriesStealthMode): ApiStealthMode { export function buildApiStealthMode(stealthMode: GramJs.TypeStoriesStealthMode): ApiStealthMode {
@ -167,6 +206,17 @@ export function buildApiMediaArea(area: GramJs.TypeMediaArea): ApiMediaArea | un
}; };
} }
if (area instanceof GramJs.MediaAreaChannelPost) {
const { coordinates, channelId, msgId } = area;
return {
type: 'channelPost',
coordinates: buildApiMediaAreaCoordinates(coordinates),
channelId: buildApiPeerId(channelId, 'channel'),
messageId: msgId,
};
}
return undefined; return undefined;
} }
@ -177,11 +227,14 @@ export function buildApiPeerStories(peerStories: GramJs.PeerStories) {
} }
export function buildApiStoryForwardInfo(forwardHeader: GramJs.TypeStoryFwdHeader): ApiStoryForwardInfo { export function buildApiStoryForwardInfo(forwardHeader: GramJs.TypeStoryFwdHeader): ApiStoryForwardInfo {
const { from, fromName, storyId } = forwardHeader; const {
from, fromName, storyId, modified,
} = forwardHeader;
return { return {
storyId, storyId,
fromPeerId: from && getApiChatIdFromMtpPeer(from), fromPeerId: from && getApiChatIdFromMtpPeer(from),
fromName, fromName,
isModified: modified,
}; };
} }

View File

@ -1,7 +1,6 @@
import { Api as GramJs } from '../../../lib/gramjs'; import { Api as GramJs } from '../../../lib/gramjs';
import type { import type {
ApiEmojiStatus,
ApiPremiumGiftOption, ApiPremiumGiftOption,
ApiUser, ApiUser,
ApiUserFullInfo, ApiUserFullInfo,
@ -11,7 +10,7 @@ import type {
import { buildApiBotInfo } from './bots'; import { buildApiBotInfo } from './bots';
import { buildApiPhoto, buildApiUsernames } from './common'; import { buildApiPhoto, buildApiUsernames } from './common';
import { buildApiPeerColor, buildApiPeerId } from './peers'; import { buildApiEmojiStatus, buildApiPeerColor, buildApiPeerId } from './peers';
export function buildApiUserFullInfo(mtpUserFull: GramJs.users.UserFull): ApiUserFullInfo { export function buildApiUserFullInfo(mtpUserFull: GramJs.users.UserFull): ApiUserFullInfo {
const { const {
@ -57,7 +56,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
: undefined; : undefined;
const userType = buildApiUserType(mtpUser); const userType = buildApiUserType(mtpUser);
const usernames = buildApiUsernames(mtpUser); const usernames = buildApiUsernames(mtpUser);
const emojiStatus = mtpUser.emojiStatus ? buildApiUserEmojiStatus(mtpUser.emojiStatus) : undefined; const emojiStatus = mtpUser.emojiStatus ? buildApiEmojiStatus(mtpUser.emojiStatus) : undefined;
return { return {
id: buildApiPeerId(id, 'user'), id: buildApiPeerId(id, 'user'),
@ -116,18 +115,6 @@ export function buildApiUserStatus(mtpStatus?: GramJs.TypeUserStatus): ApiUserSt
} }
} }
export function buildApiUserEmojiStatus(mtpEmojiStatus: GramJs.TypeEmojiStatus): ApiEmojiStatus | undefined {
if (mtpEmojiStatus instanceof GramJs.EmojiStatus) {
return { documentId: mtpEmojiStatus.documentId.toString() };
}
if (mtpEmojiStatus instanceof GramJs.EmojiStatusUntil) {
return { documentId: mtpEmojiStatus.documentId.toString(), until: mtpEmojiStatus.until };
}
return undefined;
}
export function buildApiUsersAndStatuses(mtpUsers: GramJs.TypeUser[]) { export function buildApiUsersAndStatuses(mtpUsers: GramJs.TypeUser[]) {
const userStatusesById: Record<string, ApiUserStatus> = {}; const userStatusesById: Record<string, ApiUserStatus> = {};
const usersById: Record<string, ApiUser> = {}; const usersById: Record<string, ApiUser> = {};

View File

@ -87,22 +87,23 @@ export async function fetchMessagePublicForwards({
chat, chat,
messageId, messageId,
dcId, dcId,
offsetRate = 0, offset,
}: { }: {
chat: ApiChat; chat: ApiChat;
messageId: number; messageId: number;
dcId?: number; dcId?: number;
offsetRate?: number; offset?: string;
}): Promise<{ }): Promise<{
forwards?: ApiMessagePublicForward[]; forwards?: ApiMessagePublicForward[];
count?: number; count?: number;
nextRate?: number; nextOffset?: string;
chats: ApiChat[];
users: ApiUser[];
} | undefined> { } | undefined> {
const result = await invokeRequest(new GramJs.stats.GetMessagePublicForwards({ const result = await invokeRequest(new GramJs.stats.GetMessagePublicForwards({
channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel, channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel,
msgId: messageId, msgId: messageId,
offsetPeer: new GramJs.InputPeerEmpty(), offset,
offsetRate,
limit: STATISTICS_PUBLIC_FORWARDS_LIMIT, limit: STATISTICS_PUBLIC_FORWARDS_LIMIT,
}), { }), {
dcId, dcId,
@ -112,16 +113,15 @@ export async function fetchMessagePublicForwards({
return undefined; return undefined;
} }
if ('chats' in result) { addEntitiesToLocalDb(result.chats);
addEntitiesToLocalDb(result.chats); addEntitiesToLocalDb(result.users);
}
return { return {
forwards: buildMessagePublicForwards(result), forwards: buildMessagePublicForwards(result),
...('nextRate' in result ? { count: result.count,
count: result.count, nextOffset: result.nextOffset,
nextRate: result.nextRate, chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
} : undefined), users: result.users.map(buildApiUser).filter(Boolean),
}; };
} }
@ -177,23 +177,23 @@ export async function fetchStoryPublicForwards({
chat, chat,
storyId, storyId,
dcId, dcId,
offsetId = '0', offset,
}: { }: {
chat: ApiChat; chat: ApiChat;
storyId: number; storyId: number;
dcId?: number; dcId?: number;
offsetId?: string; offset?: string;
}): Promise<{ }): Promise<{
publicForwards: (ApiMessagePublicForward | ApiStoryPublicForward)[] | undefined; publicForwards: (ApiMessagePublicForward | ApiStoryPublicForward)[] | undefined;
users: ApiUser[]; users: ApiUser[];
chats: ApiChat[]; chats: ApiChat[];
count?: number; count?: number;
nextOffsetId?: string; nextOffset?: string;
} | undefined> { } | undefined> {
const result = await invokeRequest(new GramJs.stats.GetStoryPublicForwards({ const result = await invokeRequest(new GramJs.stats.GetStoryPublicForwards({
peer: buildInputPeer(chat.id, chat.accessHash), peer: buildInputPeer(chat.id, chat.accessHash),
id: storyId, id: storyId,
offset: offsetId, offset,
limit: STATISTICS_PUBLIC_FORWARDS_LIMIT, limit: STATISTICS_PUBLIC_FORWARDS_LIMIT,
}), { }), {
dcId, dcId,
@ -211,6 +211,6 @@ export async function fetchStoryPublicForwards({
users: result.users.map(buildApiUser).filter(Boolean), users: result.users.map(buildApiUser).filter(Boolean),
chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean), chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
count: result.count, count: result.count,
nextOffsetId: result.nextOffset, nextOffset: result.nextOffset,
}; };
} }

View File

@ -285,11 +285,14 @@ export async function fetchStoryViewList({
} }
addEntitiesToLocalDb(result.users); addEntitiesToLocalDb(result.users);
addEntitiesToLocalDb(result.chats);
const users = result.users.map(buildApiUser).filter(Boolean); const users = result.users.map(buildApiUser).filter(Boolean);
const views = result.views.map(buildApiStoryView); const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
const views = result.views.map(buildApiStoryView).filter(Boolean);
return { return {
users, users,
chats,
views, views,
nextOffset: result.nextOffset, nextOffset: result.nextOffset,
reactionsCount: result.reactionsCount, reactionsCount: result.reactionsCount,

View File

@ -7,10 +7,10 @@ import type {
import { DEFAULT_GIF_SEARCH_BOT_USERNAME, RECENT_STATUS_LIMIT, RECENT_STICKERS_LIMIT } from '../../../config'; import { DEFAULT_GIF_SEARCH_BOT_USERNAME, RECENT_STATUS_LIMIT, RECENT_STICKERS_LIMIT } from '../../../config';
import { buildVideoFromDocument } from '../apiBuilders/messageContent'; import { buildVideoFromDocument } from '../apiBuilders/messageContent';
import { buildApiEmojiStatus } from '../apiBuilders/peers';
import { import {
buildStickerSet, buildStickerSetCovered, processStickerPackResult, processStickerResult, buildStickerSet, buildStickerSetCovered, processStickerPackResult, processStickerResult,
} from '../apiBuilders/symbols'; } from '../apiBuilders/symbols';
import { buildApiUserEmojiStatus } from '../apiBuilders/users';
import { buildInputDocument, buildInputStickerSet, buildInputStickerSetShortName } from '../gramjsBuilders'; import { buildInputDocument, buildInputStickerSet, buildInputStickerSetShortName } from '../gramjsBuilders';
import localDb from '../localDb'; import localDb from '../localDb';
import { invokeRequest } from './client'; import { invokeRequest } from './client';
@ -445,7 +445,7 @@ export async function fetchRecentEmojiStatuses(hash = '0') {
const documentIds = result.statuses const documentIds = result.statuses
.slice(0, RECENT_STATUS_LIMIT) .slice(0, RECENT_STATUS_LIMIT)
.map(buildApiUserEmojiStatus) .map(buildApiEmojiStatus)
.filter(Boolean) .filter(Boolean)
.map(({ documentId }) => documentId); .map(({ documentId }) => documentId);
const emojiStatuses = await fetchCustomEmoji({ documentId: documentIds }); const emojiStatuses = await fetchCustomEmoji({ documentId: documentIds });

View File

@ -46,7 +46,7 @@ import {
buildApiNotifyExceptionTopic, buildApiNotifyExceptionTopic,
buildPrivacyKey, buildPrivacyKey,
} from './apiBuilders/misc'; } from './apiBuilders/misc';
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './apiBuilders/peers'; import { buildApiEmojiStatus, buildApiPeerId, getApiChatIdFromMtpPeer } from './apiBuilders/peers';
import { import {
buildApiReaction, buildApiReaction,
buildMessageReactions, buildMessageReactions,
@ -55,7 +55,6 @@ import { buildApiStealthMode, buildApiStory } from './apiBuilders/stories';
import { buildApiEmojiInteraction, buildStickerSet } from './apiBuilders/symbols'; import { buildApiEmojiInteraction, buildStickerSet } from './apiBuilders/symbols';
import { import {
buildApiUser, buildApiUser,
buildApiUserEmojiStatus,
buildApiUserStatus, buildApiUserStatus,
} from './apiBuilders/users'; } from './apiBuilders/users';
import { import {
@ -795,7 +794,7 @@ export function updater(update: Update) {
id: buildApiPeerId(update.userId, 'user'), id: buildApiPeerId(update.userId, 'user'),
}); });
} else if (update instanceof GramJs.UpdateUserEmojiStatus) { } else if (update instanceof GramJs.UpdateUserEmojiStatus) {
const emojiStatus = buildApiUserEmojiStatus(update.emojiStatus); const emojiStatus = buildApiEmojiStatus(update.emojiStatus);
onUpdate({ onUpdate({
'@type': 'updateUserEmojiStatus', '@type': 'updateUserEmojiStatus',
userId: buildApiPeerId(update.userId, 'user'), userId: buildApiPeerId(update.userId, 'user'),

View File

@ -3,7 +3,9 @@ import type {
ApiChatReactions, ApiMessage, ApiPhoto, ApiStickerSet, ApiChatReactions, ApiMessage, ApiPhoto, ApiStickerSet,
} from './messages'; } from './messages';
import type { ApiChatInviteImporter } from './misc'; import type { ApiChatInviteImporter } from './misc';
import type { ApiFakeType, ApiUser, ApiUsername } from './users'; import type {
ApiEmojiStatus, ApiFakeType, ApiUser, ApiUsername,
} from './users';
type ApiChatType = ( type ApiChatType = (
'chatTypePrivate' | 'chatTypeSecret' | 'chatTypePrivate' | 'chatTypeSecret' |
@ -43,6 +45,7 @@ export interface ApiChat {
isProtected?: boolean; isProtected?: boolean;
fakeType?: ApiFakeType; fakeType?: ApiFakeType;
color?: ApiPeerColor; color?: ApiPeerColor;
emojiStatus?: ApiEmojiStatus;
isForum?: boolean; isForum?: boolean;
isForumAsMessages?: true; isForumAsMessages?: true;
topics?: Record<number, ApiTopic>; topics?: Record<number, ApiTopic>;

View File

@ -260,6 +260,21 @@ export type ApiGiveaway = {
isOnlyForNewSubscribers?: true; isOnlyForNewSubscribers?: true;
countries?: string[]; countries?: string[];
channelIds: string[]; channelIds: string[];
prizeDescription?: string;
};
export type ApiGiveawayResults = {
months: number;
untilDate: number;
isRefunded?: true;
isOnlyForNewSubscribers?: true;
channelId: string;
prizeDescription?: string;
winnersCount?: number;
winnerIds: string[];
additionalPeersCount?: number;
launchMessageId: number;
unclaimedCount: number;
}; };
export type ApiNewPoll = { export type ApiNewPoll = {
@ -370,6 +385,7 @@ export interface ApiStoryForwardInfo {
fromPeerId?: string; fromPeerId?: string;
fromName?: string; fromName?: string;
storyId?: number; storyId?: number;
isModified?: boolean;
} }
export type ApiMessageEntityDefault = { export type ApiMessageEntityDefault = {
@ -458,6 +474,7 @@ export type MediaContent = {
game?: ApiGame; game?: ApiGame;
storyData?: ApiMessageStoryData; storyData?: ApiMessageStoryData;
giveaway?: ApiGiveaway; giveaway?: ApiGiveaway;
giveawayResults?: ApiGiveawayResults;
}; };
export interface ApiMessage { export interface ApiMessage {

View File

@ -46,8 +46,7 @@ export interface ApiPostStatistics {
publicForwards?: number; publicForwards?: number;
publicForwardsData?: (ApiMessagePublicForward | ApiStoryPublicForward)[]; publicForwardsData?: (ApiMessagePublicForward | ApiStoryPublicForward)[];
nextRate?: number; nextOffset?: string;
nextOffsetId?: string;
} }
export interface ApiBoostStatistics { export interface ApiBoostStatistics {

View File

@ -1,6 +1,6 @@
import type { ApiPrivacySettings } from '../../types'; import type { ApiPrivacySettings } from '../../types';
import type { import type {
ApiGeoPoint, ApiReaction, ApiReactionCount, ApiStoryForwardInfo, MediaContent, ApiGeoPoint, ApiMessage, ApiReaction, ApiReactionCount, ApiStoryForwardInfo, MediaContent,
} from './messages'; } from './messages';
export interface ApiStory { export interface ApiStory {
@ -71,14 +71,37 @@ export type ApiWebPageStoryData = {
peerId: string; peerId: string;
}; };
export type ApiStoryViewPublicForward = {
type: 'forward';
peerId: string;
messageId: number;
message: ApiMessage;
date: number;
isUserBlocked?: true;
areStoriesBlocked?: true;
};
export type ApiStoryViewPublicRepost = {
type: 'repost';
isUserBlocked?: true;
areStoriesBlocked?: true;
date: number;
peerId: string;
storyId: number;
story: ApiStory;
};
export type ApiStoryView = { export type ApiStoryView = {
userId: string; type: 'user';
peerId: string;
date: number; date: number;
reaction?: ApiReaction; reaction?: ApiReaction;
isUserBlocked?: true; isUserBlocked?: true;
areStoriesBlocked?: true; areStoriesBlocked?: true;
}; };
export type ApiTypeStoryView = ApiStoryView | ApiStoryViewPublicForward | ApiStoryViewPublicRepost;
export type ApiStealthMode = { export type ApiStealthMode = {
activeUntil?: number; activeUntil?: number;
cooldownUntil?: number; cooldownUntil?: number;
@ -113,4 +136,12 @@ export type ApiMediaAreaSuggestedReaction = {
isFlipped?: boolean; isFlipped?: boolean;
}; };
export type ApiMediaArea = ApiMediaAreaVenue | ApiMediaAreaGeoPoint | ApiMediaAreaSuggestedReaction; export type ApiMediaAreaChannelPost = {
type: 'channelPost';
coordinates: ApiMediaAreaCoordinates;
channelId: string;
messageId: number;
};
export type ApiMediaArea = ApiMediaAreaVenue | ApiMediaAreaGeoPoint | ApiMediaAreaSuggestedReaction
| ApiMediaAreaChannelPost;

Binary file not shown.

View File

@ -53,7 +53,6 @@ const FullNameTitle: FC<OwnProps> = ({
const { showNotification } = getActions(); const { showNotification } = getActions();
const isUser = isUserId(peer.id); const isUser = isUserId(peer.id);
const title = isUser ? getUserFullName(peer as ApiUser) : getChatTitle(lang, peer as ApiChat); const title = isUser ? getUserFullName(peer as ApiUser) : getChatTitle(lang, peer as ApiChat);
const emojiStatus = isUser && (peer as ApiUser).emojiStatus;
const isPremium = isUser && (peer as ApiUser).isPremium; const isPremium = isUser && (peer as ApiUser).isPremium;
const handleTitleClick = useLastCallback((e) => { const handleTitleClick = useLastCallback((e) => {
@ -86,16 +85,16 @@ const FullNameTitle: FC<OwnProps> = ({
</h3> </h3>
{!noVerified && peer.isVerified && <VerifiedIcon />} {!noVerified && peer.isVerified && <VerifiedIcon />}
{!noFake && peer.fakeType && <FakeIcon fakeType={peer.fakeType} />} {!noFake && peer.fakeType && <FakeIcon fakeType={peer.fakeType} />}
{withEmojiStatus && emojiStatus && ( {withEmojiStatus && peer.emojiStatus && (
<CustomEmoji <CustomEmoji
documentId={emojiStatus.documentId} documentId={peer.emojiStatus.documentId}
size={emojiStatusSize} size={emojiStatusSize}
loopLimit={!noLoopLimit ? EMOJI_STATUS_LOOP_LIMIT : undefined} loopLimit={!noLoopLimit ? EMOJI_STATUS_LOOP_LIMIT : undefined}
observeIntersectionForLoading={observeIntersection} observeIntersectionForLoading={observeIntersection}
onClick={onEmojiStatusClick} onClick={onEmojiStatusClick}
/> />
)} )}
{withEmojiStatus && !emojiStatus && isPremium && <PremiumIcon />} {withEmojiStatus && !peer.emojiStatus && isPremium && <PremiumIcon />}
</div> </div>
); );
}; };

View File

@ -6,6 +6,7 @@ import type {
ApiChat, ApiThreadInfo, ApiTopic, ApiTypingStatus, ApiChat, ApiThreadInfo, ApiTopic, ApiTypingStatus,
} from '../../api/types'; } from '../../api/types';
import type { LangFn } from '../../hooks/useLang'; import type { LangFn } from '../../hooks/useLang';
import type { IconName } from '../../types/icons';
import { MediaViewerOrigin, type StoryViewerOrigin } from '../../types'; import { MediaViewerOrigin, type StoryViewerOrigin } from '../../types';
import { import {
@ -30,6 +31,7 @@ import useLastCallback from '../../hooks/useLastCallback';
import Avatar from './Avatar'; import Avatar from './Avatar';
import DotAnimation from './DotAnimation'; import DotAnimation from './DotAnimation';
import FullNameTitle from './FullNameTitle'; import FullNameTitle from './FullNameTitle';
import Icon from './Icon';
import TopicIcon from './TopicIcon'; import TopicIcon from './TopicIcon';
import TypingStatus from './TypingStatus'; import TypingStatus from './TypingStatus';
@ -39,6 +41,7 @@ type OwnProps = {
chatId: string; chatId: string;
threadId?: number; threadId?: number;
className?: string; className?: string;
statusIcon?: IconName;
typingStatus?: ApiTypingStatus; typingStatus?: ApiTypingStatus;
avatarSize?: 'tiny' | 'small' | 'medium' | 'large' | 'jumbo'; avatarSize?: 'tiny' | 'small' | 'medium' | 'large' | 'jumbo';
status?: string; status?: string;
@ -48,6 +51,8 @@ type OwnProps = {
withFullInfo?: boolean; withFullInfo?: boolean;
withUpdatingStatus?: boolean; withUpdatingStatus?: boolean;
withChatType?: boolean; withChatType?: boolean;
noEmojiStatus?: boolean;
emojiStatusSize?: number;
noRtl?: boolean; noRtl?: boolean;
noAvatar?: boolean; noAvatar?: boolean;
noStatusOrTyping?: boolean; noStatusOrTyping?: boolean;
@ -69,6 +74,7 @@ type StateProps =
const GroupChatInfo: FC<OwnProps & StateProps> = ({ const GroupChatInfo: FC<OwnProps & StateProps> = ({
typingStatus, typingStatus,
className, className,
statusIcon,
avatarSize = 'medium', avatarSize = 'medium',
noAvatar, noAvatar,
status, status,
@ -88,6 +94,8 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
noStatusOrTyping, noStatusOrTyping,
withStory, withStory,
storyViewerOrigin, storyViewerOrigin,
noEmojiStatus,
emojiStatusSize,
onClick, onClick,
}) => { }) => {
const { const {
@ -133,7 +141,10 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
return withDots ? ( return withDots ? (
<DotAnimation className="status" content={status} /> <DotAnimation className="status" content={status} />
) : ( ) : (
<span className="status" dir="auto">{status}</span> <span className="status" dir="auto">
{statusIcon && <Icon className="status-icon" name={statusIcon} />}
{renderText(status)}
</span>
); );
} }
@ -206,7 +217,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
<div className="info"> <div className="info">
{topic {topic
? <h3 dir="auto" className="fullName">{renderText(topic.title)}</h3> ? <h3 dir="auto" className="fullName">{renderText(topic.title)}</h3>
: <FullNameTitle peer={chat} />} : <FullNameTitle peer={chat} emojiStatusSize={emojiStatusSize} withEmojiStatus={!noEmojiStatus} />}
{!noStatusOrTyping && renderStatusOrTyping()} {!noStatusOrTyping && renderStatusOrTyping()}
</div> </div>
</div> </div>

View File

@ -8,6 +8,7 @@ import type { IconName } from '../../types/icons';
import { getChatTitle, getUserFirstOrLastName } from '../../global/helpers'; import { getChatTitle, getUserFirstOrLastName } from '../../global/helpers';
import { selectChat, selectUser } from '../../global/selectors'; import { selectChat, selectUser } from '../../global/selectors';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { getPeerColorClass } from './helpers/peerColor';
import renderText from './helpers/renderText'; import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
@ -26,6 +27,7 @@ type OwnProps = {
clickArg?: any; clickArg?: any;
className?: string; className?: string;
fluid?: boolean; fluid?: boolean;
withPeerColors?: boolean;
onClick: (arg: any) => void; onClick: (arg: any) => void;
}; };
@ -46,6 +48,7 @@ const PickerSelectedItem: FC<OwnProps & StateProps> = ({
className, className,
fluid, fluid,
isSavedMessages, isSavedMessages,
withPeerColors,
onClick, onClick,
}) => { }) => {
const lang = useLang(); const lang = useLang();
@ -84,6 +87,7 @@ const PickerSelectedItem: FC<OwnProps & StateProps> = ({
isMinimized && 'minimized', isMinimized && 'minimized',
canClose && 'closeable', canClose && 'closeable',
fluid && 'fluid', fluid && 'fluid',
withPeerColors && getPeerColorClass(chat || user),
); );
return ( return (

View File

@ -21,6 +21,7 @@ import RippleEffect from '../ui/RippleEffect';
import Avatar from './Avatar'; import Avatar from './Avatar';
import DotAnimation from './DotAnimation'; import DotAnimation from './DotAnimation';
import FullNameTitle from './FullNameTitle'; import FullNameTitle from './FullNameTitle';
import Icon from './Icon';
import TypingStatus from './TypingStatus'; import TypingStatus from './TypingStatus';
type OwnProps = { type OwnProps = {
@ -122,7 +123,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
<DotAnimation className="status" content={status} /> <DotAnimation className="status" content={status} />
) : ( ) : (
<span className="status" dir="auto"> <span className="status" dir="auto">
{statusIcon && <i className={`icon icon-${statusIcon} status-icon`} />} {statusIcon && <Icon className="status-icon" name={statusIcon} />}
{renderText(status)} {renderText(status)}
</span> </span>
); );

View File

@ -7,6 +7,7 @@ import VoiceAllowTalk from '../../../assets/tgs/calls/VoiceAllowTalk.tgs';
import VoiceMini from '../../../assets/tgs/calls/VoiceMini.tgs'; import VoiceMini from '../../../assets/tgs/calls/VoiceMini.tgs';
import VoiceMuted from '../../../assets/tgs/calls/VoiceMuted.tgs'; import VoiceMuted from '../../../assets/tgs/calls/VoiceMuted.tgs';
import VoiceOutlined from '../../../assets/tgs/calls/VoiceOutlined.tgs'; import VoiceOutlined from '../../../assets/tgs/calls/VoiceOutlined.tgs';
import PartyPopper from '../../../assets/tgs/general/PartyPopper.tgs';
import Invite from '../../../assets/tgs/invites/Invite.tgs'; import Invite from '../../../assets/tgs/invites/Invite.tgs';
import JoinRequest from '../../../assets/tgs/invites/Requests.tgs'; import JoinRequest from '../../../assets/tgs/invites/Requests.tgs';
import MonkeyClose from '../../../assets/tgs/monkeys/TwoFactorSetupMonkeyClose.tgs'; import MonkeyClose from '../../../assets/tgs/monkeys/TwoFactorSetupMonkeyClose.tgs';
@ -44,4 +45,5 @@ export const LOCAL_TGS_URLS = {
QrPlane, QrPlane,
Congratulations, Congratulations,
Experimental, Experimental,
PartyPopper,
}; };

View File

@ -179,7 +179,6 @@ const Main: FC<OwnProps & StateProps> = ({
isMediaViewerOpen, isMediaViewerOpen,
isStoryViewerOpen, isStoryViewerOpen,
isForwardModalOpen, isForwardModalOpen,
currentUserId,
hasNotifications, hasNotifications,
hasDialogs, hasDialogs,
audioMessage, audioMessage,
@ -568,7 +567,7 @@ const Main: FC<OwnProps & StateProps> = ({
isByPhoneNumber={newContactByPhoneNumber} isByPhoneNumber={newContactByPhoneNumber}
/> />
<BoostModal info={boostModal} /> <BoostModal info={boostModal} />
<GiftCodeModal modal={giftCodeModal} currentUserId={currentUserId} /> <GiftCodeModal modal={giftCodeModal} />
<ChatlistModal info={chatlistModal} /> <ChatlistModal info={chatlistModal} />
<GameModal openedGame={openedGame} gameTitle={gameTitle} /> <GameModal openedGame={openedGame} gameTitle={gameTitle} />
<WebAppModal webApp={webApp} /> <WebAppModal webApp={webApp} />

View File

@ -203,7 +203,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
const handleGiftCodeClick = () => { const handleGiftCodeClick = () => {
const slug = message.content.action?.slug; const slug = message.content.action?.slug;
if (!slug) return; if (!slug) return;
checkGiftCode({ slug }); checkGiftCode({ slug, message: { chatId: message.chatId, messageId: message.id } });
}; };
// TODO Refactoring for action rendering // TODO Refactoring for action rendering

View File

@ -405,6 +405,7 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
withUpdatingStatus withUpdatingStatus
withStory withStory
storyViewerOrigin={StoryViewerOrigin.MiddleHeaderAvatar} storyViewerOrigin={StoryViewerOrigin.MiddleHeaderAvatar}
emojiStatusSize={EMOJI_STATUS_SIZE}
noRtl noRtl
/> />
)} )}

View File

@ -7,14 +7,19 @@
.title { .title {
display: block; display: block;
margin-top: 0.5rem;
} }
.gift { .sticker {
position: relative; position: relative;
margin-top: -2.5rem; margin-top: -2.5rem;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.resultSticker {
margin-top: 0;
}
.count { .count {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
@ -43,15 +48,16 @@
margin-bottom: 0; margin-bottom: 0;
} }
.channels { .peers {
display: flex; display: flex;
flex-direction: column; flex-wrap: wrap;
justify-content: center;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
margin-block: 0.25rem; margin-block: 0.25rem;
} }
.channel { .peer {
background-color: var(--accent-background-color); background-color: var(--accent-background-color);
color: var(--accent-color); color: var(--accent-color);
margin: unset; margin: unset;
@ -64,3 +70,29 @@
.button { .button {
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.result {
font-weight: 500;
}
.separator {
display: flex;
align-items: center;
text-align: center;
color: var(--color-text-secondary);
}
.separator::before,
.separator::after {
content: '';
flex: 1;
border-bottom: 1px solid var(--color-dividers);
}
.separator:not(:empty)::before {
margin-right: 0.25em;
}
.separator:not(:empty)::after {
margin-left: 0.25em;
}

View File

@ -4,25 +4,30 @@ import React, {
import { getActions, getGlobal, withGlobal } from '../../../global'; import { getActions, getGlobal, withGlobal } from '../../../global';
import type { import type {
ApiChat, ApiGiveawayInfo, ApiMessage, ApiPeer, ApiSticker, ApiChat, ApiGiveaway, ApiGiveawayInfo, ApiGiveawayResults, ApiMessage, ApiPeer, ApiSticker,
} from '../../../api/types'; } from '../../../api/types';
import { getChatTitle, getUserFullName, isApiPeerChat } from '../../../global/helpers'; import {
getChatTitle, getUserFullName, isApiPeerChat, isOwnMessage,
} from '../../../global/helpers';
import { import {
selectCanPlayAnimatedEmojis, selectCanPlayAnimatedEmojis,
selectChat, selectChat,
selectForwardedSender, selectForwardedSender,
selectGiftStickerForDuration, selectGiftStickerForDuration,
} from '../../../global/selectors'; } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName';
import { formatDateAtTime, formatDateTimeToString } from '../../../util/dateFormat'; import { formatDateAtTime, formatDateTimeToString } from '../../../util/dateFormat';
import { isoToEmoji } from '../../../util/emoji'; import { isoToEmoji } from '../../../util/emoji';
import { getServerTime } from '../../../util/serverTime'; import { getServerTime } from '../../../util/serverTime';
import { callApi } from '../../../api/gramjs'; import { callApi } from '../../../api/gramjs';
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
import renderText from '../../common/helpers/renderText'; import renderText from '../../common/helpers/renderText';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import AnimatedIcon from '../../common/AnimatedIcon';
import AnimatedIconFromSticker from '../../common/AnimatedIconFromSticker'; import AnimatedIconFromSticker from '../../common/AnimatedIconFromSticker';
import PickerSelectedItem from '../../common/PickerSelectedItem'; import PickerSelectedItem from '../../common/PickerSelectedItem';
import Button from '../../ui/Button'; import Button from '../../ui/Button';
@ -43,6 +48,7 @@ type StateProps = {
const NBSP = '\u00A0'; const NBSP = '\u00A0';
const GIFT_STICKER_SIZE = 175; const GIFT_STICKER_SIZE = 175;
const RESULT_STICKER_SIZE = 150;
const Giveaway = ({ const Giveaway = ({
chat, chat,
@ -57,20 +63,27 @@ const Giveaway = ({
const [giveawayInfo, setGiveawayInfo] = useState<ApiGiveawayInfo | undefined>(); const [giveawayInfo, setGiveawayInfo] = useState<ApiGiveawayInfo | undefined>();
const lang = useLang(); const lang = useLang();
const { giveaway, giveawayResults } = message.content;
const isResults = Boolean(giveawayResults);
const { const {
months, quantity, channelIds, untilDate, countries, months, untilDate, prizeDescription,
} = message.content.giveaway!; } = (giveaway || giveawayResults)!;
const isOwn = isOwnMessage(message);
const quantity = isResults ? giveawayResults.winnersCount : giveaway!.quantity;
const hasEnded = getServerTime() > untilDate; const hasEnded = getServerTime() > untilDate;
const countryList = useMemo(() => { const countryList = useMemo(() => {
if (isResults) return undefined;
const translatedNames = new Intl.DisplayNames([lang.code!, 'en'].filter(Boolean), { type: 'region' }); const translatedNames = new Intl.DisplayNames([lang.code!, 'en'].filter(Boolean), { type: 'region' });
return countries?.map((countryCode) => ( return giveaway?.countries?.map((countryCode) => (
`${isoToEmoji(countryCode)}${NBSP}${translatedNames.of(countryCode)}` `${isoToEmoji(countryCode)}${NBSP}${translatedNames.of(countryCode)}`
)).join(', '); )).join(', ');
}, [countries, lang.code]); }, [giveaway, isResults, lang.code]);
const handleChannelClick = useLastCallback((channelId: string) => { const handlePeerClick = useLastCallback((channelId: string) => {
openChat({ id: channelId }); openChat({ id: channelId });
}); });
@ -95,36 +108,149 @@ const Giveaway = ({
return lang(giveawayInfo.type === 'results' ? 'BoostingGiveawayEnd' : 'BoostingGiveAwayAbout'); return lang(giveawayInfo.type === 'results' ? 'BoostingGiveawayEnd' : 'BoostingGiveAwayAbout');
}, [giveawayInfo, lang]); }, [giveawayInfo, lang]);
function renderGiveawayDescription(media: ApiGiveaway) {
const channelIds = media.channelIds;
return (
<>
<div className={styles.section}>
<strong className={styles.title}>
{renderText(lang('BoostingGiveawayPrizes'), ['simple_markdown'])}
</strong>
{prizeDescription && (
<>
<p className={styles.description}>
{renderText(
lang('BoostingGiveawayMsgPrizes', [quantity, prizeDescription], undefined, quantity),
['simple_markdown'],
)}
</p>
<div className={styles.separator}>{lang('BoostingGiveawayMsgWithDivider')}</div>
</>
)}
<p className={styles.description}>
{renderText(lang('Chat.Giveaway.Info.Subscriptions', quantity), ['simple_markdown'])}
<br />
{renderText(lang(
'ActionGiftPremiumSubtitle',
lang('Chat.Giveaway.Info.Months', months),
), ['simple_markdown'])}
</p>
</div>
<div className={styles.section}>
<strong className={styles.title}>
{renderText(lang('BoostingGiveawayMsgParticipants'), ['simple_markdown'])}
</strong>
<p className={styles.description}>
{renderText(lang('BoostingGiveawayMsgAllSubsPlural', channelIds.length), ['simple_markdown'])}
</p>
<div className={styles.peers}>
{channelIds.map((peerId) => (
<PickerSelectedItem
peerId={peerId}
forceShowSelf
fluid
withPeerColors={!isOwn}
className={styles.peer}
clickArg={peerId}
onClick={handlePeerClick}
/>
))}
</div>
{countryList && (
<span>{renderText(lang('Chat.Giveaway.Message.CountriesFrom', countryList))}</span>
)}
</div>
<div className={styles.section}>
<strong className={styles.title}>
{renderText(lang('BoostingWinnersDate'), ['simple_markdown'])}
</strong>
<p className={styles.description}>
{formatDateTimeToString(untilDate * 1000, lang.code, true)}
</p>
</div>
</>
);
}
function renderGiveawayResultsDescription(media: ApiGiveawayResults) {
const winnerIds = media.winnerIds;
return (
<>
<div className={styles.section}>
<strong className={styles.title}>
{renderText(lang('BoostingGiveawayResultsMsgWinnersSelected'), ['simple_markdown'])}
</strong>
<p className={styles.description}>
{renderText(lang('BoostingGiveawayResultsMsgWinnersTitle', winnerIds.length), ['simple_markdown'])}
</p>
<strong className={styles.title}>
{lang('lng_prizes_results_winners')}
</strong>
<div className={styles.peers}>
{winnerIds.map((peerId) => (
<PickerSelectedItem
peerId={peerId}
forceShowSelf
fluid
withPeerColors={!isOwn}
className={styles.peer}
clickArg={peerId}
onClick={handlePeerClick}
/>
))}
</div>
</div>
<div className={styles.section}>
<p className={styles.description}>
{lang('BoostingGiveawayResultsMsgAllWinnersReceivedLinks')}
</p>
</div>
</>
);
}
function renderGiveawayInfo() { function renderGiveawayInfo() {
if (!sender || !giveawayInfo) return undefined; if (!sender || !giveawayInfo) return undefined;
const isResults = giveawayInfo.type === 'results'; const isResultsInfo = giveawayInfo.type === 'results';
const chatTitle = isApiPeerChat(sender) ? getChatTitle(lang, sender) : getUserFullName(sender); const chatTitle = isApiPeerChat(sender) ? getChatTitle(lang, sender) : getUserFullName(sender);
const duration = lang('Chat.Giveaway.Info.Months', months); const duration = lang('Chat.Giveaway.Info.Months', months);
const endDate = formatDateAtTime(lang, untilDate * 1000); const endDate = formatDateAtTime(lang, untilDate * 1000);
const otherChannelsCount = channelIds.length ? channelIds.length - 1 : 0; const otherChannelsCount = giveaway?.channelIds ? giveaway.channelIds.length - 1 : 0;
const otherChannelsString = lang('Chat.Giveaway.Info.OtherChannels', otherChannelsCount); const otherChannelsString = lang('Chat.Giveaway.Info.OtherChannels', otherChannelsCount);
const isSeveral = otherChannelsCount > 0; const isSeveral = otherChannelsCount > 0;
const firstKey = isResults ? 'BoostingGiveawayHowItWorksTextEnd' : 'BoostingGiveawayHowItWorksText'; const firstKey = isResultsInfo ? 'BoostingGiveawayHowItWorksTextEnd' : 'BoostingGiveawayHowItWorksText';
const firstParagraph = lang(firstKey, [chatTitle, quantity, duration], undefined, quantity); const firstParagraph = lang(firstKey, [chatTitle, quantity, duration], undefined, quantity);
const additionalPrizes = prizeDescription
? lang('BoostingGiveawayHowItWorksIncludeText', [chatTitle, quantity, prizeDescription], undefined, quantity)
: undefined;
let secondKey = ''; let secondKey = '';
if (isResults) { if (isResultsInfo) {
secondKey = isSeveral ? 'BoostingGiveawayHowItWorksSubTextSeveralEnd' : 'BoostingGiveawayHowItWorksSubTextEnd'; secondKey = isSeveral ? 'BoostingGiveawayHowItWorksSubTextSeveralEnd' : 'BoostingGiveawayHowItWorksSubTextEnd';
} else { } else {
secondKey = isSeveral ? 'BoostingGiveawayHowItWorksSubTextSeveral' : 'BoostingGiveawayHowItWorksSubText'; secondKey = isSeveral ? 'BoostingGiveawayHowItWorksSubTextSeveral' : 'BoostingGiveawayHowItWorksSubText';
} }
let secondParagraph = lang(secondKey, [endDate, quantity, chatTitle, otherChannelsCount], undefined, quantity); let secondParagraph = lang(secondKey, [endDate, quantity, chatTitle, otherChannelsCount], undefined, quantity);
if (isResults && giveawayInfo.activatedCount) { if (isResultsInfo && giveawayInfo.activatedCount) {
secondParagraph += ` ${lang('BoostingGiveawayUsedLinksPlural', giveawayInfo.activatedCount)}`; secondParagraph += ` ${lang('BoostingGiveawayUsedLinksPlural', giveawayInfo.activatedCount)}`;
} }
let result = '';
if (isResultsInfo) {
if (giveawayInfo.isRefunded) {
result = lang('BoostingGiveawayCanceledByPayment');
} else {
result = lang(giveawayInfo.isWinner ? 'BoostingGiveawayYouWon' : 'BoostingGiveawayYouNotWon');
}
}
let lastParagraph = ''; let lastParagraph = '';
if (isResults && giveawayInfo.isRefunded) { if (isResultsInfo) {
lastParagraph = lang('BoostingGiveawayCanceledByPayment'); // Nothing
} else if (isResults) {
lastParagraph = lang(giveawayInfo.isWinner ? 'BoostingGiveawayYouWon' : 'BoostingGiveawayYouNotWon');
} else if (giveawayInfo.disallowedCountry) { } else if (giveawayInfo.disallowedCountry) {
lastParagraph = lang('BoostingGiveawayNotEligibleCountry'); lastParagraph = lang('BoostingGiveawayNotEligibleCountry');
} else if (giveawayInfo.adminDisallowedChatId) { } else if (giveawayInfo.adminDisallowedChatId) {
@ -148,78 +274,55 @@ const Giveaway = ({
return ( return (
<> <>
{result && (
<p className={styles.result}>
{renderText(result, ['simple_markdown'])}
</p>
)}
<p> <p>
{renderText(firstParagraph, ['simple_markdown'])} {renderText(firstParagraph, ['simple_markdown'])}
</p> </p>
{additionalPrizes && (
<p>
{renderText(additionalPrizes, ['simple_markdown'])}
</p>
)}
<p> <p>
{renderText(secondParagraph, ['simple_markdown'])} {renderText(secondParagraph, ['simple_markdown'])}
</p> </p>
<p> {lastParagraph && (
{renderText(lastParagraph, ['simple_markdown'])} <p>
</p> {renderText(lastParagraph, ['simple_markdown'])}
</p>
)}
</> </>
); );
} }
return ( return (
<div className={styles.root}> <div className={styles.root}>
<div className={styles.gift}> <div className={buildClassName(styles.sticker, isResults && styles.resultSticker)}>
<AnimatedIconFromSticker {isResults ? (
key={message.id} <AnimatedIcon
sticker={giftSticker} size={RESULT_STICKER_SIZE}
play={canPlayAnimatedEmojis && hasEnded} tgsUrl={LOCAL_TGS_URLS.PartyPopper}
noLoop nonInteractive
nonInteractive noLoop
size={GIFT_STICKER_SIZE} />
/> ) : (
<AnimatedIconFromSticker
sticker={giftSticker}
play={canPlayAnimatedEmojis && hasEnded}
noLoop
nonInteractive
size={GIFT_STICKER_SIZE}
/>
)}
<span className={styles.count}> <span className={styles.count}>
{`x${quantity}`} {`x${quantity}`}
</span> </span>
</div> </div>
<div className={styles.section}> {isResults ? renderGiveawayResultsDescription(giveawayResults) : renderGiveawayDescription(giveaway!)}
<strong className={styles.title}>
{renderText(lang('BoostingGiveawayPrizes'), ['simple_markdown'])}
</strong>
<p className={styles.description}>
{renderText(lang('Chat.Giveaway.Info.Subscriptions', quantity), ['simple_markdown'])}
<br />
{renderText(lang(
'ActionGiftPremiumSubtitle',
lang('Chat.Giveaway.Info.Months', months),
), ['simple_markdown'])}
</p>
</div>
<div className={styles.section}>
<strong className={styles.title}>
{renderText(lang('BoostingGiveawayMsgParticipants'), ['simple_markdown'])}
</strong>
<p className={styles.description}>
{renderText(lang('BoostingGiveawayMsgAllSubsPlural', channelIds.length), ['simple_markdown'])}
</p>
<div className={styles.channels}>
{channelIds.map((channelId) => (
<PickerSelectedItem
peerId={channelId}
forceShowSelf
fluid
className={styles.channel}
clickArg={channelId}
onClick={handleChannelClick}
/>
))}
</div>
{Boolean(countries?.length) && (
<span>{renderText(lang('Chat.Giveaway.Message.CountriesFrom', countryList))}</span>
)}
</div>
<div className={styles.section}>
<strong className={styles.title}>
{renderText(lang('BoostingWinnersDate'), ['simple_markdown'])}
</strong>
<p className={styles.description}>
{formatDateTimeToString(untilDate * 1000, lang.code, true)}
</p>
</div>
<Button <Button
className={styles.button} className={styles.button}
color="adaptive" color="adaptive"
@ -243,15 +346,17 @@ const Giveaway = ({
export default memo(withGlobal<OwnProps>( export default memo(withGlobal<OwnProps>(
(global, { message }): StateProps => { (global, { message }): StateProps => {
const duration = message.content.giveaway!.months; const { giveaway } = message.content;
const chat = selectChat(global, message.chatId)!; const chat = selectChat(global, message.chatId)!;
const sender = selectChat(global, message.content.giveaway?.channelIds[0]!) const sender = selectChat(global, giveaway?.channelIds[0]!)
|| selectForwardedSender(global, message) || chat; || selectForwardedSender(global, message) || chat;
const sticker = giveaway && selectGiftStickerForDuration(global, giveaway.months);
return { return {
chat, chat,
sender, sender,
giftSticker: selectGiftStickerForDuration(global, duration), giftSticker: sticker,
canPlayAnimatedEmojis: selectCanPlayAnimatedEmojis(global), canPlayAnimatedEmojis: selectCanPlayAnimatedEmojis(global),
}; };
}, },

View File

@ -639,6 +639,7 @@ const Message: FC<OwnProps & StateProps> = ({
voice, document, sticker, contact, voice, document, sticker, contact,
poll, webPage, invoice, location, poll, webPage, invoice, location,
action, game, storyData, giveaway, action, game, storyData, giveaway,
giveawayResults,
} = getMessageContent(message); } = getMessageContent(message);
const { replyToMsgId, replyToPeerId, isQuote } = messageReplyInfo || {}; const { replyToMsgId, replyToPeerId, isQuote } = messageReplyInfo || {};
@ -1146,7 +1147,7 @@ const Message: FC<OwnProps & StateProps> = ({
{poll && ( {poll && (
<Poll message={message} poll={poll} onSendVote={handleVoteSend} /> <Poll message={message} poll={poll} onSendVote={handleVoteSend} />
)} )}
{giveaway && ( {(giveaway || giveawayResults) && (
<Giveaway message={message} /> <Giveaway message={message} />
)} )}
{game && ( {game && (

View File

@ -34,7 +34,8 @@ export function buildContentClassName(
} = {}, } = {},
) { ) {
const { const {
text, photo, video, audio, voice, document, poll, webPage, contact, location, invoice, storyData, giveaway, text, photo, video, audio, voice, document, poll, webPage, contact, location, invoice, storyData,
giveaway, giveawayResults,
} = getMessageContent(message); } = getMessageContent(message);
const classNames = [MESSAGE_CONTENT_CLASS_NAME]; const classNames = [MESSAGE_CONTENT_CLASS_NAME];
@ -87,7 +88,7 @@ export function buildContentClassName(
classNames.push('contact'); classNames.push('contact');
} else if (poll) { } else if (poll) {
classNames.push('poll'); classNames.push('poll');
} else if (giveaway) { } else if (giveaway || giveawayResults) {
classNames.push('giveaway'); classNames.push('giveaway');
} else if (webPage) { } else if (webPage) {
classNames.push('web-page'); classNames.push('web-page');

View File

@ -1,9 +1,11 @@
import React, { memo } from '../../../lib/teact/teact'; import React, { memo } from '../../../lib/teact/teact';
import { getActions } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { ApiPeer } from '../../../api/types';
import type { TabState } from '../../../global/types'; import type { TabState } from '../../../global/types';
import { TME_LINK_PREFIX } from '../../../config'; import { TME_LINK_PREFIX } from '../../../config';
import { selectChatMessage, selectSender } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import { formatDateTimeToString } from '../../../util/dateFormat'; import { formatDateTimeToString } from '../../../util/dateFormat';
import renderText from '../../common/helpers/renderText'; import renderText from '../../common/helpers/renderText';
@ -21,16 +23,21 @@ import styles from './GiftCodeModal.module.scss';
import PremiumLogo from '../../../assets/premium/PremiumLogo.svg'; import PremiumLogo from '../../../assets/premium/PremiumLogo.svg';
export type OwnProps = { export type OwnProps = {
currentUserId?: string;
modal: TabState['giftCodeModal']; modal: TabState['giftCodeModal'];
}; };
export type StateProps = {
currentUserId?: string;
messageSender?: ApiPeer;
};
const GIFTCODE_PATH = 'giftcode'; const GIFTCODE_PATH = 'giftcode';
const GiftCodeModal = ({ const GiftCodeModal = ({
currentUserId, currentUserId,
modal, modal,
}: OwnProps) => { messageSender,
}: OwnProps & StateProps) => {
const { const {
closeGiftCodeModal, openChat, applyGiftCode, focusMessage, closeGiftCodeModal, openChat, applyGiftCode, focusMessage,
} = getActions(); } = getActions();
@ -65,6 +72,8 @@ const GiftCodeModal = ({
if (!modal) return undefined; if (!modal) return undefined;
const { slug, info } = modal; const { slug, info } = modal;
const fromId = info.fromId || messageSender?.id;
return ( return (
<> <>
<img className={styles.logo} src={PremiumLogo} alt="" draggable={false} /> <img className={styles.logo} src={PremiumLogo} alt="" draggable={false} />
@ -74,13 +83,13 @@ const GiftCodeModal = ({
<tr> <tr>
<td className={styles.title}>{lang('BoostingFrom')}</td> <td className={styles.title}>{lang('BoostingFrom')}</td>
<td> <td>
{info.fromId ? ( {fromId ? (
<PickerSelectedItem <PickerSelectedItem
peerId={info.fromId} peerId={fromId}
className={styles.chatItem} className={styles.chatItem}
forceShowSelf forceShowSelf
fluid fluid
clickArg={info.fromId} clickArg={fromId}
onClick={handleOpenChat} onClick={handleOpenChat}
/> />
) : lang('BoostingNoRecipient')} ) : lang('BoostingNoRecipient')}
@ -157,4 +166,15 @@ const GiftCodeModal = ({
); );
}; };
export default memo(GiftCodeModal); export default memo(withGlobal<OwnProps>(
(global, { modal }): StateProps => {
const { message } = modal || {};
const chatMessage = message && selectChatMessage(global, message.chatId, message.messageId);
const sender = chatMessage && selectSender(global, chatMessage);
return {
currentUserId: global.currentUserId,
messageSender: sender,
};
},
)(GiftCodeModal));

View File

@ -5,6 +5,7 @@ import React, {
import { getActions, withGlobal } from '../../global'; import { getActions, withGlobal } from '../../global';
import type { import type {
ApiMediaAreaChannelPost,
ApiPeer, ApiStealthMode, ApiStory, ApiTypeStory, ApiPeer, ApiStealthMode, ApiStory, ApiTypeStory,
} from '../../api/types'; } from '../../api/types';
import type { IDimensions } from '../../global/types'; import type { IDimensions } from '../../global/types';
@ -843,7 +844,11 @@ export default memo(withGlobal<OwnProps>((global, {
viewModal || forwardedStoryId || tabState.reactionPicker?.storyId || isReportModalOpen || isPrivacyModalOpen viewModal || forwardedStoryId || tabState.reactionPicker?.storyId || isReportModalOpen || isPrivacyModalOpen
|| isPremiumModalOpen || isDeleteModalOpen || safeLinkModalUrl || isStealthModalOpen || mapModal, || isPremiumModalOpen || isDeleteModalOpen || safeLinkModalUrl || isStealthModalOpen || mapModal,
); );
const forwardSenderId = story && 'forwardInfo' in story ? story.forwardInfo?.fromPeerId : undefined;
const forwardInfo = (story && 'forwardInfo' in story) ? story.forwardInfo : undefined;
const mediaAreas = (story && 'mediaAreas' in story) ? story.mediaAreas : undefined;
const forwardSenderId = forwardInfo?.fromPeerId
|| mediaAreas?.find((area): area is ApiMediaAreaChannelPost => area.type === 'channelPost')?.channelId;
const forwardSender = forwardSenderId ? selectPeer(global, forwardSenderId) : undefined; const forwardSender = forwardSenderId ? selectPeer(global, forwardSenderId) : undefined;
return { return {

View File

@ -1,10 +1,13 @@
import React, { memo, useMemo } from '../../lib/teact/teact'; import React, { memo, useMemo } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global'; import { getActions, withGlobal } from '../../global';
import type { ApiAvailableReaction, ApiStoryView, ApiUser } from '../../api/types'; import type {
ApiAvailableReaction, ApiPeer, ApiTypeStoryView, ApiUser,
} from '../../api/types';
import type { IconName } from '../../types/icons';
import { getUserFullName } from '../../global/helpers'; import { getUserFullName, isUserId } from '../../global/helpers';
import { selectUser } from '../../global/selectors'; import { selectPeer } from '../../global/selectors';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { formatDateAtTime } from '../../util/dateFormat'; import { formatDateAtTime } from '../../util/dateFormat';
import { REM } from '../common/helpers/mediaDimensions'; import { REM } from '../common/helpers/mediaDimensions';
@ -12,6 +15,7 @@ import { REM } from '../common/helpers/mediaDimensions';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import GroupChatInfo from '../common/GroupChatInfo';
import PrivateChatInfo from '../common/PrivateChatInfo'; import PrivateChatInfo from '../common/PrivateChatInfo';
import ReactionStaticEmoji from '../common/ReactionStaticEmoji'; import ReactionStaticEmoji from '../common/ReactionStaticEmoji';
import ListItem, { type MenuItemContextAction } from '../ui/ListItem'; import ListItem, { type MenuItemContextAction } from '../ui/ListItem';
@ -19,38 +23,64 @@ import ListItem, { type MenuItemContextAction } from '../ui/ListItem';
import styles from './StoryViewModal.module.scss'; import styles from './StoryViewModal.module.scss';
type OwnProps = { type OwnProps = {
storyView: ApiStoryView; storyView: ApiTypeStoryView;
}; };
type StateProps = { type StateProps = {
user?: ApiUser; peer?: ApiPeer;
availableReactions?: ApiAvailableReaction[]; availableReactions?: ApiAvailableReaction[];
}; };
const CLOSE_ANIMATION_DURATION = 100; const CLOSE_ANIMATION_DURATION = 100;
const DEFAULT_REACTION_SIZE = 1.5 * REM; const DEFAULT_REACTION_SIZE = 1.5 * REM;
const BULLET = '\u2022';
const StoryView = ({ const StoryView = ({
storyView, storyView,
user, peer,
availableReactions, availableReactions,
}: OwnProps & StateProps) => { }: OwnProps & StateProps) => {
const { const {
openChat, closeStoryViewer, unblockUser, blockUser, deleteContact, updateStoryView, openChat,
closeStoryViewer,
unblockUser,
blockUser,
deleteContact,
updateStoryView,
focusMessage,
openStoryViewer,
closeStoryViewModal,
} = getActions(); } = getActions();
const lang = useLang(); const lang = useLang();
const handleClick = useLastCallback(() => { const handleClick = useLastCallback(() => {
const { type } = storyView;
if (type === 'repost') {
closeStoryViewModal();
openStoryViewer({
peerId: storyView.peerId,
storyId: storyView.storyId,
});
return;
}
closeStoryViewer(); closeStoryViewer();
setTimeout(() => { setTimeout(() => {
openChat({ id: storyView.userId }); if (type === 'user') {
openChat({ id: storyView.peerId });
} else if (type === 'forward') {
focusMessage({ chatId: storyView.peerId, messageId: storyView.messageId });
}
}, CLOSE_ANIMATION_DURATION); }, CLOSE_ANIMATION_DURATION);
}); });
const contextActions = useMemo(() => { const contextActions = useMemo(() => {
const { userId, areStoriesBlocked, isUserBlocked } = storyView; if (!isUserId(storyView.peerId)) return undefined;
const { peerId, areStoriesBlocked, isUserBlocked } = storyView;
const user = peer as ApiUser;
const { isContact } = user || {}; const { isContact } = user || {};
const fullName = getUserFullName(user); const fullName = getUserFullName(user);
@ -60,8 +90,8 @@ const StoryView = ({
if (!areStoriesBlocked) { if (!areStoriesBlocked) {
actions.push({ actions.push({
handler: () => { handler: () => {
blockUser({ userId, isOnlyStories: true }); blockUser({ userId: peerId, isOnlyStories: true });
updateStoryView({ userId, areStoriesBlocked: true }); updateStoryView({ userId: peerId, areStoriesBlocked: true });
}, },
title: lang('StoryHideFrom', fullName), title: lang('StoryHideFrom', fullName),
icon: 'hand-stop', icon: 'hand-stop',
@ -69,8 +99,8 @@ const StoryView = ({
} else { } else {
actions.push({ actions.push({
handler: () => { handler: () => {
unblockUser({ userId, isOnlyStories: true }); unblockUser({ userId: peerId, isOnlyStories: true });
updateStoryView({ userId, areStoriesBlocked: false }); updateStoryView({ userId: peerId, areStoriesBlocked: false });
}, },
title: lang('StoryShowBackTo', fullName), title: lang('StoryShowBackTo', fullName),
icon: 'play-story', icon: 'play-story',
@ -81,7 +111,7 @@ const StoryView = ({
if (isContact) { if (isContact) {
actions.push({ actions.push({
handler: () => { handler: () => {
deleteContact({ userId }); deleteContact({ userId: peerId });
}, },
title: lang('DeleteContact'), title: lang('DeleteContact'),
icon: 'delete-user', icon: 'delete-user',
@ -91,11 +121,11 @@ const StoryView = ({
actions.push({ actions.push({
handler: () => { handler: () => {
if (isUserBlocked) { if (isUserBlocked) {
unblockUser({ userId }); unblockUser({ userId: peerId });
updateStoryView({ userId, isUserBlocked: false }); updateStoryView({ userId: peerId, isUserBlocked: false });
} else { } else {
blockUser({ userId }); blockUser({ userId: peerId });
updateStoryView({ userId, isUserBlocked: true }); updateStoryView({ userId: peerId, isUserBlocked: true });
} }
}, },
title: lang(isUserBlocked ? 'Unblock' : 'BlockUser'), title: lang(isUserBlocked ? 'Unblock' : 'BlockUser'),
@ -105,11 +135,25 @@ const StoryView = ({
} }
return actions; return actions;
}, [lang, storyView, user]); }, [lang, storyView, peer]);
const statusIcon: IconName = storyView.type === 'user' ? 'message-read'
: storyView.type === 'forward' ? 'forward' : 'loop';
const shouldColorStatus = storyView.type === 'forward' || storyView.type === 'repost';
const status = useMemo(() => {
const isModified = storyView.type === 'repost' && storyView.story.forwardInfo?.isModified;
const parts = [formatDateAtTime(lang, storyView.date * 1000)];
if (isModified) {
parts.push(lang('lng_edited'));
}
return parts.join(` ${BULLET} `);
}, [lang, storyView]);
return ( return (
<ListItem <ListItem
key={storyView.userId} key={storyView.peerId}
className={buildClassName( className={buildClassName(
'chat-item-clickable small-icon', 'chat-item-clickable small-icon',
styles.opacityFadeIn, styles.opacityFadeIn,
@ -117,7 +161,7 @@ const StoryView = ({
)} )}
// eslint-disable-next-line react/jsx-no-bind // eslint-disable-next-line react/jsx-no-bind
onClick={() => handleClick()} onClick={() => handleClick()}
rightElement={storyView.reaction ? ( rightElement={storyView.type === 'user' && storyView.reaction ? (
<ReactionStaticEmoji <ReactionStaticEmoji
reaction={storyView.reaction} reaction={storyView.reaction}
className={styles.viewReaction} className={styles.viewReaction}
@ -130,23 +174,34 @@ const StoryView = ({
withPortalForMenu withPortalForMenu
menuBubbleClassName={styles.menuBubble} menuBubbleClassName={styles.menuBubble}
> >
<PrivateChatInfo {isUserId(storyView.peerId) ? (
userId={storyView.userId} <PrivateChatInfo
noStatusOrTyping className={buildClassName(shouldColorStatus && styles.withColoredStatus)}
status={formatDateAtTime(lang, storyView.date * 1000)} userId={storyView.peerId}
statusIcon="message-read" noStatusOrTyping
withStory status={status}
forceShowSelf statusIcon={statusIcon}
/> withStory
forceShowSelf
/>
) : (
<GroupChatInfo
className={buildClassName(shouldColorStatus && styles.withColoredStatus)}
chatId={storyView.peerId}
status={status}
statusIcon={statusIcon}
withStory
/>
)}
</ListItem> </ListItem>
); );
}; };
export default memo(withGlobal<OwnProps>((global, { storyView }) => { export default memo(withGlobal<OwnProps>((global, { storyView }) => {
const user = selectUser(global, storyView.userId); const peer = selectPeer(global, storyView.peerId);
return { return {
user, peer,
availableReactions: global.availableReactions, availableReactions: global.availableReactions,
}; };
})(StoryView)); })(StoryView));

View File

@ -96,6 +96,7 @@
.footer { .footer {
border-top: 0.0625rem solid var(--color-borders); border-top: 0.0625rem solid var(--color-borders);
padding-block: 0.25rem;
} }
.closeButton { .closeButton {
@ -118,6 +119,10 @@
max-width: min(25rem, 80vw); max-width: min(25rem, 80vw);
} }
.with-colored-status :global(.status-icon) {
color: var(--color-text-green);
}
@keyframes fadeIn { @keyframes fadeIn {
from { from {
opacity: 0; opacity: 0;

View File

@ -4,7 +4,7 @@ import React, {
} from '../../lib/teact/teact'; } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global'; import { getActions, withGlobal } from '../../global';
import type { ApiStory, ApiStoryView } from '../../api/types'; import type { ApiStory, ApiTypeStoryView } from '../../api/types';
import { import {
STORY_MIN_REACTIONS_SORT, STORY_MIN_REACTIONS_SORT,
@ -41,7 +41,7 @@ import styles from './StoryViewModal.module.scss';
interface StateProps { interface StateProps {
story?: ApiStory; story?: ApiStory;
isLoading?: boolean; isLoading?: boolean;
viewsById?: Record<string, ApiStoryView>; views?: ApiTypeStoryView[];
nextOffset?: string; nextOffset?: string;
viewersExpirePeriod: number; viewersExpirePeriod: number;
isCurrentUserPremium?: boolean; isCurrentUserPremium?: boolean;
@ -52,7 +52,7 @@ const REFETCH_DEBOUNCE = 250;
function StoryViewModal({ function StoryViewModal({
story, story,
viewersExpirePeriod, viewersExpirePeriod,
viewsById, views,
nextOffset, nextOffset,
isLoading, isLoading,
isCurrentUserPremium, isCurrentUserPremium,
@ -92,19 +92,13 @@ function StoryViewModal({
refetchViews(); refetchViews();
}, [areJustContacts, areReactionsFirst, query, refetchViews]); }, [areJustContacts, areReactionsFirst, query, refetchViews]);
const sortedViewIds = useMemo(() => { const sortedViews = useMemo(() => {
if (!viewsById) { return views?.sort(prepareComparator(areReactionsFirst));
return undefined; }, [areReactionsFirst, views]);
}
return Object.values(viewsById) const placeholderCount = !sortedViews?.length ? Math.min(viewsCount, 8) : 1;
.sort(prepareComparator(areReactionsFirst))
.map((view) => view.userId);
}, [areReactionsFirst, viewsById]);
const placeholderCount = !sortedViewIds?.length ? Math.min(viewsCount, 8) : 1; const notAllAvailable = Boolean(sortedViews?.length) && sortedViews!.length < viewsCount && isExpired;
const notAllAvailable = Boolean(sortedViewIds?.length) && sortedViewIds!.length < viewsCount && isExpired;
const handleLoadMore = useLastCallback(() => { const handleLoadMore = useLastCallback(() => {
if (!story?.id || nextOffset === undefined) return; if (!story?.id || nextOffset === undefined) return;
@ -207,7 +201,7 @@ function StoryViewModal({
className={buildClassName(styles.content, !isAtBeginning && styles.topScrolled, 'custom-scroll')} className={buildClassName(styles.content, !isAtBeginning && styles.topScrolled, 'custom-scroll')}
onScroll={handleScroll} onScroll={handleScroll}
> >
{isExpired && !isLoading && !query && Boolean(!sortedViewIds?.length) && ( {isExpired && !isLoading && !query && Boolean(!sortedViews?.length) && (
<div className={buildClassName(styles.info, styles.centeredInfo)}> <div className={buildClassName(styles.info, styles.centeredInfo)}>
{renderText( {renderText(
lang(isCurrentUserPremium ? 'ServerErrorViewers' : 'ExpiredViewsStub'), lang(isCurrentUserPremium ? 'ServerErrorViewers' : 'ExpiredViewsStub'),
@ -215,18 +209,22 @@ function StoryViewModal({
)} )}
</div> </div>
)} )}
{!isLoading && Boolean(query.length) && !sortedViewIds?.length && ( {!isLoading && Boolean(query.length) && !sortedViews?.length && (
<div className={styles.info}> <div className={styles.info}>
{lang('Story.ViewList.EmptyTextSearch')} {lang('Story.ViewList.EmptyTextSearch')}
</div> </div>
)} )}
<InfiniteScroll <InfiniteScroll
items={sortedViewIds} items={sortedViews}
onLoadMore={handleLoadMore} onLoadMore={handleLoadMore}
> >
{sortedViewIds?.map((id) => ( {sortedViews?.map((view) => {
<StoryView key={id} storyView={viewsById![id]} /> const additionalKeyId = view.type === 'forward' ? view.messageId
))} : view.type === 'repost' ? view.storyId : 'user';
return (
<StoryView key={`${view.peerId}-${view.date}-${additionalKeyId}`} storyView={view} />
);
})}
{isLoading && Array.from({ length: placeholderCount }).map((_, i) => ( {isLoading && Array.from({ length: placeholderCount }).map((_, i) => (
<ListItem <ListItem
// eslint-disable-next-line react/no-array-index-key // eslint-disable-next-line react/no-array-index-key
@ -258,12 +256,14 @@ function StoryViewModal({
} }
function prepareComparator(areReactionsFirst?: boolean) { function prepareComparator(areReactionsFirst?: boolean) {
return (a: ApiStoryView, b: ApiStoryView) => { return (a: ApiTypeStoryView, b: ApiTypeStoryView) => {
if (areReactionsFirst) { if (areReactionsFirst) {
if (a.reaction && !b.reaction) { const reactionA = a.type === 'user' && a.reaction;
const reactionB = b.type === 'user' && b.reaction;
if (reactionA && !reactionB) {
return -1; return -1;
} }
if (!a.reaction && b.reaction) { if (!reactionA && reactionB) {
return 1; return 1;
} }
} }
@ -276,13 +276,13 @@ export default memo(withGlobal((global) => {
const { appConfig } = global; const { appConfig } = global;
const { storyViewer: { viewModal } } = selectTabState(global); const { storyViewer: { viewModal } } = selectTabState(global);
const { const {
storyId, viewsById, nextOffset, isLoading, storyId, views, nextOffset, isLoading,
} = viewModal || {}; } = viewModal || {};
const story = storyId ? selectPeerStory(global, global.currentUserId!, storyId) : undefined; const story = storyId ? selectPeerStory(global, global.currentUserId!, storyId) : undefined;
return { return {
storyId, storyId,
viewsById, views,
viewersExpirePeriod: appConfig!.storyExpirePeriod + appConfig!.storyViewersExpirePeriod, viewersExpirePeriod: appConfig!.storyExpirePeriod + appConfig!.storyViewersExpirePeriod,
story: story && 'content' in story ? story : undefined, story: story && 'content' in story ? story : undefined,
nextOffset, nextOffset,

View File

@ -25,7 +25,7 @@ const STORY_ASPECT_RATIO = 9 / 16;
const MediaAreaOverlay = ({ const MediaAreaOverlay = ({
story, isActive, className, story, isActive, className,
}: OwnProps) => { }: OwnProps) => {
const { openMapModal } = getActions(); const { openMapModal, focusMessage, closeStoryViewer } = getActions();
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
@ -58,8 +58,20 @@ const MediaAreaOverlay = ({
}, [isActive, windowSize]); }, [isActive, windowSize]);
const handleMediaAreaClick = (mediaArea: ApiMediaArea) => { const handleMediaAreaClick = (mediaArea: ApiMediaArea) => {
if (mediaArea.type === 'geoPoint' || mediaArea.type === 'venue') { switch (mediaArea.type) {
openMapModal({ geoPoint: mediaArea.geo }); case 'geoPoint':
case 'venue': {
openMapModal({ geoPoint: mediaArea.geo });
break;
}
case 'channelPost': {
focusMessage({
chatId: mediaArea.channelId,
messageId: mediaArea.messageId,
});
closeStoryViewer();
break;
}
} }
}; };
@ -74,13 +86,16 @@ const MediaAreaOverlay = ({
switch (mediaArea.type) { switch (mediaArea.type) {
case 'geoPoint': case 'geoPoint':
case 'venue': case 'venue':
case 'channelPost': {
const isShiny = isActive && (mediaArea.type === 'geoPoint' || mediaArea.type === 'venue');
return ( return (
<div <div
className={buildClassName(styles.mediaArea, isActive && styles.shiny)} className={buildClassName(styles.mediaArea, isShiny && styles.shiny)}
style={prepareStyle(mediaArea)} style={prepareStyle(mediaArea)}
onClick={() => handleMediaAreaClick(mediaArea)} onClick={() => handleMediaAreaClick(mediaArea)}
/> />
); );
}
case 'suggestedReaction': case 'suggestedReaction':
return ( return (
<MediaAreaSuggestedReaction <MediaAreaSuggestedReaction

View File

@ -646,7 +646,7 @@ addActionHandler('applyBoost', async (global, actions, payload): Promise<void> =
}); });
addActionHandler('checkGiftCode', async (global, actions, payload): Promise<void> => { addActionHandler('checkGiftCode', async (global, actions, payload): Promise<void> => {
const { slug, tabId = getCurrentTabId() } = payload; const { slug, message, tabId = getCurrentTabId() } = payload;
const result = await callApi('checkGiftCode', { const result = await callApi('checkGiftCode', {
slug, slug,
@ -667,6 +667,7 @@ addActionHandler('checkGiftCode', async (global, actions, payload): Promise<void
giftCodeModal: { giftCodeModal: {
slug, slug,
info: result.code, info: result.code,
message,
}, },
}, tabId); }, tabId);
setGlobal(global); setGlobal(global);

View File

@ -91,14 +91,14 @@ addActionHandler('loadMessagePublicForwards', async (global, actions, payload):
const dcId = fullInfo.statisticsDcId; const dcId = fullInfo.statisticsDcId;
const stats = selectTabState(global, tabId).statistics.currentMessage || {}; const stats = selectTabState(global, tabId).statistics.currentMessage || {};
if (stats?.publicForwards && !stats.nextRate) return; if (stats?.publicForwards && !stats.nextOffset) return;
const publicForwards = await callApi('fetchMessagePublicForwards', { const publicForwards = await callApi('fetchMessagePublicForwards', {
chat, messageId, dcId, offsetRate: stats?.nextRate, chat, messageId, dcId, offset: stats.nextOffset,
}); });
const { const {
forwards, forwards,
nextRate, nextOffset,
count, count,
} = publicForwards || {}; } = publicForwards || {};
@ -113,7 +113,7 @@ addActionHandler('loadMessagePublicForwards', async (global, actions, payload):
publicForwardsData: (stats.publicForwardsData || []).concat( publicForwardsData: (stats.publicForwardsData || []).concat(
shouldOmitFirstElement ? forwards.slice(1) : (forwards || []), shouldOmitFirstElement ? forwards.slice(1) : (forwards || []),
), ),
nextRate, nextOffset,
}, tabId); }, tabId);
setGlobal(global); setGlobal(global);
}); });
@ -185,16 +185,16 @@ addActionHandler('loadStoryPublicForwards', async (global, actions, payload): Pr
const dcId = fullInfo.statisticsDcId; const dcId = fullInfo.statisticsDcId;
const stats = selectTabState(global, tabId).statistics.currentStory || {}; const stats = selectTabState(global, tabId).statistics.currentStory || {};
if (stats?.publicForwards && !stats.nextOffsetId) return; if (stats?.publicForwards && !stats.nextOffset) return;
const { const {
publicForwards, publicForwards,
users, users,
chats, chats,
count, count,
nextOffsetId, nextOffset,
} = await callApi('fetchStoryPublicForwards', { } = await callApi('fetchStoryPublicForwards', {
chat, storyId, dcId, offsetId: stats.nextOffsetId, chat, storyId, dcId, offset: stats.nextOffset,
}) || {}; }) || {};
global = getGlobal(); global = getGlobal();
@ -211,7 +211,7 @@ addActionHandler('loadStoryPublicForwards', async (global, actions, payload): Pr
publicForwardsData: (stats.publicForwardsData || []).concat( publicForwardsData: (stats.publicForwardsData || []).concat(
publicForwards || [], publicForwards || [],
), ),
nextOffsetId, nextOffset,
}, tabId); }, tabId);
setGlobal(global); setGlobal(global);
}); });

View File

@ -1,3 +1,4 @@
import type { ApiStoryView } from '../../../api/types';
import type { ActionReturnType } from '../../types'; import type { ActionReturnType } from '../../types';
import { DEBUG, PREVIEW_AVATAR_COUNT } from '../../../config'; import { DEBUG, PREVIEW_AVATAR_COUNT } from '../../../config';
@ -353,14 +354,15 @@ addActionHandler('loadStoryViews', async (global, actions, payload): Promise<voi
return; return;
} }
const viewsById = buildCollectionByKey(result.views, 'userId');
global = getGlobal(); global = getGlobal();
global = addUsers(global, buildCollectionByKey(result.users, 'id')); global = addUsers(global, buildCollectionByKey(result.users, 'id'));
if (!isPreload) global = updateStoryViews(global, storyId, viewsById, result.nextOffset, tabId); global = addChats(global, buildCollectionByKey(result.chats, 'id'));
if (!isPreload) global = updateStoryViews(global, storyId, result.views, result.nextOffset, tabId);
if (isPreload && result.views?.length) { if (isPreload && result.views?.length) {
const recentViewerIds = result.views.map((view) => view.userId); const recentViewerIds = result.views
.filter((view): view is ApiStoryView => 'date' in view)
.map((view) => view.peerId);
global = updatePeerStoryViews(global, peerId, storyId, { global = updatePeerStoryViews(global, peerId, storyId, {
recentViewerIds, recentViewerIds,
viewsCount: result.viewsCount, viewsCount: result.viewsCount,

View File

@ -1,4 +1,3 @@
import type { ApiStoryView } from '../../../api/types';
import type { ActionReturnType } from '../../types'; import type { ActionReturnType } from '../../types';
import { copyTextToClipboard } from '../../../util/clipboard'; import { copyTextToClipboard } from '../../../util/clipboard';
@ -374,7 +373,7 @@ addActionHandler('clearStoryViews', (global, actions, payload): ActionReturnType
...tabState.storyViewer, ...tabState.storyViewer,
viewModal: { viewModal: {
...tabState.storyViewer.viewModal, ...tabState.storyViewer.viewModal,
viewsById: {}, views: undefined,
isLoading, isLoading,
nextOffset: '', nextOffset: '',
}, },
@ -389,24 +388,26 @@ addActionHandler('updateStoryView', (global, actions, payload): ActionReturnType
const tabState = selectTabState(global, tabId); const tabState = selectTabState(global, tabId);
const { viewModal } = tabState.storyViewer; const { viewModal } = tabState.storyViewer;
if (!viewModal?.storyId) return undefined;
if (!viewModal?.viewsById?.[userId]) return global; const updatedViews = viewModal?.views?.map((view) => {
if (view.peerId === userId) {
return {
...view,
isUserBlocked: isUserBlocked || undefined,
areStoriesBlocked: areStoriesBlocked || undefined,
};
}
const updatedViewsById: Record<string, ApiStoryView> = { return view;
...viewModal.viewsById, });
[userId]: {
...viewModal.viewsById[userId],
isUserBlocked: isUserBlocked || undefined,
areStoriesBlocked: areStoriesBlocked || undefined,
},
};
return updateTabState(global, { return updateTabState(global, {
storyViewer: { storyViewer: {
...tabState.storyViewer, ...tabState.storyViewer,
viewModal: { viewModal: {
...viewModal, ...viewModal,
viewsById: updatedViewsById, views: updatedViews,
}, },
}, },
}, tabId); }, tabId);

View File

@ -121,6 +121,7 @@ export function getMessageSummaryDescription(
game, game,
storyData, storyData,
giveaway, giveaway,
giveawayResults,
} = message.content; } = message.content;
let hasUsedTruncatedText = false; let hasUsedTruncatedText = false;
@ -195,6 +196,10 @@ export function getMessageSummaryDescription(
summary = lang('BoostingGiveawayChannelStarted'); summary = lang('BoostingGiveawayChannelStarted');
} }
if (giveawayResults) {
summary = lang('Message.GiveawayEndedWinners', giveawayResults.winnersCount);
}
if (storyData) { if (storyData) {
if (storyData.isMention) { if (storyData.isMention) {
// eslint-disable-next-line eslint-multitab-tt/no-immediate-global // eslint-disable-next-line eslint-multitab-tt/no-immediate-global

View File

@ -55,12 +55,12 @@ export function getMessageTranscription(message: ApiMessage) {
export function hasMessageText(message: ApiMessage | ApiStory) { export function hasMessageText(message: ApiMessage | ApiStory) {
const { const {
text, sticker, photo, video, audio, voice, document, poll, webPage, contact, invoice, location, text, sticker, photo, video, audio, voice, document, poll, webPage, contact, invoice, location,
game, action, storyData, giveaway, game, action, storyData, giveaway, giveawayResults,
} = message.content; } = message.content;
return Boolean(text) || !( return Boolean(text) || !(
sticker || photo || video || audio || voice || document || contact || poll || webPage || invoice || location sticker || photo || video || audio || voice || document || contact || poll || webPage || invoice || location
|| game || action?.phoneCall || storyData || giveaway || game || action?.phoneCall || storyData || giveaway || giveawayResults
); );
} }

View File

@ -5,9 +5,9 @@ import type {
ApiStory, ApiStory,
ApiStoryDeleted, ApiStoryDeleted,
ApiStorySkipped, ApiStorySkipped,
ApiStoryView,
ApiStoryViews, ApiStoryViews,
ApiTypeStory, ApiTypeStory,
ApiTypeStoryView,
} from '../../api/types'; } from '../../api/types';
import type { GlobalState, TabArgs } from '../types'; import type { GlobalState, TabArgs } from '../types';
@ -204,16 +204,16 @@ export function updatePeersWithStories<T extends GlobalState>(
export function updateStoryViews<T extends GlobalState>( export function updateStoryViews<T extends GlobalState>(
global: T, global: T,
storyId: number, storyId: number,
viewsById: Record<string, ApiStoryView>, views: ApiTypeStoryView[],
nextOffset?: string, nextOffset?: string,
...[tabId = getCurrentTabId()]: TabArgs<T> ...[tabId = getCurrentTabId()]: TabArgs<T>
): T { ): T {
const tabState = selectTabState(global, tabId); const tabState = selectTabState(global, tabId);
const { viewModal } = tabState.storyViewer; const { viewModal } = tabState.storyViewer;
const newViewsById = viewModal?.storyId === storyId ? { const newViews = viewModal?.storyId === storyId && viewModal.views ? [
...viewModal.viewsById, ...viewModal.views,
...viewsById, ...views,
} : viewsById; ] : views;
global = updateStoryViewsLoading(global, false, tabId); global = updateStoryViewsLoading(global, false, tabId);
@ -223,7 +223,7 @@ export function updateStoryViews<T extends GlobalState>(
viewModal: { viewModal: {
...viewModal, ...viewModal,
storyId, storyId,
viewsById: newViewsById, views: newViews,
nextOffset, nextOffset,
isLoading: false, isLoading: false,
}, },

View File

@ -546,7 +546,7 @@ export function selectAllowedMessageActions<T extends GlobalState>(global: T, me
|| getServerTime() - message.date < MESSAGE_EDIT_ALLOWED_TIME || getServerTime() - message.date < MESSAGE_EDIT_ALLOWED_TIME
) && !( ) && !(
content.sticker || content.contact || content.poll || content.action || content.audio content.sticker || content.contact || content.poll || content.action || content.audio
|| (content.video?.isRound) || content.location || content.invoice || content.giveaway || (content.video?.isRound) || content.location || content.invoice || content.giveaway || content.giveawayResults
) )
&& !isForwarded && !isForwarded
&& !message.viaBotId && !message.viaBotId

View File

@ -56,10 +56,10 @@ import type {
ApiSticker, ApiSticker,
ApiStickerSet, ApiStickerSet,
ApiStickerSetInfo, ApiStickerSetInfo,
ApiStoryView,
ApiThemeParameters, ApiThemeParameters,
ApiThreadInfo, ApiThreadInfo,
ApiTranscription, ApiTranscription,
ApiTypeStoryView,
ApiTypingStatus, ApiTypingStatus,
ApiUpdate, ApiUpdate,
ApiUpdateAuthorizationStateType, ApiUpdateAuthorizationStateType,
@ -378,7 +378,7 @@ export type TabState = {
isStealthModalOpen?: boolean; isStealthModalOpen?: boolean;
viewModal?: { viewModal?: {
storyId: number; storyId: number;
viewsById?: Record<string, ApiStoryView>; views?: ApiTypeStoryView[];
nextOffset?: string; nextOffset?: string;
isLoading?: boolean; isLoading?: boolean;
}; };
@ -657,6 +657,10 @@ export type TabState = {
giftCodeModal?: { giftCodeModal?: {
slug: string; slug: string;
message?: {
chatId: string;
messageId: number;
};
info: ApiCheckedGiftCode; info: ApiCheckedGiftCode;
}; };
@ -1878,6 +1882,10 @@ export interface ActionPayloads {
checkGiftCode: { checkGiftCode: {
slug: string; slug: string;
message?: {
chatId: string;
messageId: number;
};
} & WithTabId; } & WithTabId;
applyGiftCode: { applyGiftCode: {
slug: string; slug: string;

View File

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

File diff suppressed because one or more lines are too long

View File

@ -78,10 +78,10 @@ userStatusLastMonth#77ebc742 = UserStatus;
chatEmpty#29562865 id:long = Chat; chatEmpty#29562865 id:long = Chat;
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat; chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
chatForbidden#6592a1a7 id:long title:string = Chat; chatForbidden#6592a1a7 id:long title:string = Chat;
channel#8e87ccd8 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 = 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; 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; 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#723027bd 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 = ChatFull; channelFull#f2bcb6f 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 = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
chatParticipantAdmin#a0933f5b user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantAdmin#a0933f5b user_id:long inviter_id:long date:int = ChatParticipant;
@ -106,7 +106,8 @@ messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia; messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia; messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia; messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia;
messageMediaGiveaway#58260664 flags:# only_new_subscribers:flags.0?true channels:Vector<long> countries_iso2:flags.1?Vector<string> quantity:int months:int until_date:int = MessageMedia; messageMediaGiveaway#daad85b0 flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.2?true channels:Vector<long> countries_iso2:flags.1?Vector<string> prize_description:flags.3?string quantity:int months:int until_date:int = MessageMedia;
messageMediaGiveawayResults#c6991068 flags:# only_new_subscribers:flags.0?true refunded:flags.2?true channel_id:long additional_peers_count:flags.3?int launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector<long> months:int prize_description:flags.1?string until_date:int = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction; messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction; messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction;
messageActionChatEditTitle#b5a1ce5a title:string = MessageAction; messageActionChatEditTitle#b5a1ce5a title:string = MessageAction;
@ -143,9 +144,9 @@ messageActionGiftPremium#c83d6aec flags:# currency:string amount:long months:int
messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction; messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction;
messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction; messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction;
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction; messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
messageActionRequestedPeer#fe77345d button_id:int peer:Peer = MessageAction; messageActionRequestedPeer#31518e9b button_id:int peers:Vector<Peer> = MessageAction;
messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction; messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction;
messageActionGiftCode#d2cfdb0e flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string = MessageAction; messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long = MessageAction;
messageActionGiveawayLaunch#332ba9ed = MessageAction; messageActionGiveawayLaunch#332ba9ed = MessageAction;
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction; messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = 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; 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;
@ -342,6 +343,8 @@ updateSentStoryReaction#7d627683 peer:Peer story_id:int reaction:Reaction = Upda
updateBotChatBoost#904dd49c peer:Peer boost:Boost qts:int = Update; updateBotChatBoost#904dd49c peer:Peer boost:Boost qts:int = Update;
updateChannelViewForumAsMessages#7b68920 channel_id:long enabled:Bool = Update; updateChannelViewForumAsMessages#7b68920 channel_id:long enabled:Bool = Update;
updatePeerWallpaper#ae3f101d flags:# wallpaper_overridden:flags.1?true peer:Peer wallpaper:flags.0?WallPaper = Update; updatePeerWallpaper#ae3f101d flags:# wallpaper_overridden:flags.1?true peer:Peer wallpaper:flags.0?WallPaper = Update;
updateBotMessageReaction#ac21d3ce peer:Peer msg_id:int date:int actor:Peer old_reactions:Vector<Reaction> new_reactions:Vector<Reaction> qts:int = Update;
updateBotMessageReactions#9cb7759 peer:Peer msg_id:int date:int reactions:Vector<ReactionCount> qts:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference; updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference; updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
@ -492,7 +495,8 @@ inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet;
inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet; inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet; inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = InputStickerSet; inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = 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 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; 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;
messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet; messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet;
messages.stickerSetNotModified#d3f924eb = messages.StickerSet; messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
botCommand#c27ac8c7 command:string description:string = BotCommand; botCommand#c27ac8c7 command:string description:string = BotCommand;
@ -512,7 +516,7 @@ inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = Keyboard
keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton; keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
keyboardButtonWebView#13767230 text:string url:string = KeyboardButton; keyboardButtonWebView#13767230 text:string url:string = KeyboardButton;
keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton; keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton;
keyboardButtonRequestPeer#d0b468c text:string button_id:int peer_type:RequestPeerType = KeyboardButton; keyboardButtonRequestPeer#53d7bfd8 text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton;
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow; keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
replyKeyboardHide#a03e5b85 flags:# selective:flags.2?true = ReplyMarkup; 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; replyKeyboardForceReply#86b40b08 flags:# single_use:flags.1?true selective:flags.2?true placeholder:flags.3?string = ReplyMarkup;
@ -786,8 +790,10 @@ channelAdminLogEventActionEditTopic#f06fe208 prev_topic:ForumTopic new_topic:For
channelAdminLogEventActionDeleteTopic#ae168909 topic:ForumTopic = ChannelAdminLogEventAction; channelAdminLogEventActionDeleteTopic#ae168909 topic:ForumTopic = ChannelAdminLogEventAction;
channelAdminLogEventActionPinTopic#5d8d353b flags:# prev_topic:flags.0?ForumTopic new_topic:flags.1?ForumTopic = ChannelAdminLogEventAction; channelAdminLogEventActionPinTopic#5d8d353b flags:# prev_topic:flags.0?ForumTopic new_topic:flags.1?ForumTopic = ChannelAdminLogEventAction;
channelAdminLogEventActionToggleAntiSpam#64f36dfc new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionToggleAntiSpam#64f36dfc new_value:Bool = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeColor#3c2b247b prev_value:int new_value:int = ChannelAdminLogEventAction; channelAdminLogEventActionChangePeerColor#5796e780 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeBackgroundEmoji#445fc434 prev_value:long new_value:long = ChannelAdminLogEventAction; channelAdminLogEventActionChangeProfilePeerColor#5e477b25 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeWallpaper#31bb5d52 prev_value:WallPaper new_value:WallPaper = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_value:EmojiStatus = ChannelAdminLogEventAction;
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent; channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults; channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults;
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true = ChannelAdminLogEventsFilter; channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true = ChannelAdminLogEventsFilter;
@ -902,7 +908,7 @@ inputWallPaperNoFile#967a462e id:long = InputWallPaper;
account.wallPapersNotModified#1c199183 = account.WallPapers; account.wallPapersNotModified#1c199183 = account.WallPapers;
account.wallPapers#cdc3858c hash:long wallpapers:Vector<WallPaper> = account.WallPapers; account.wallPapers#cdc3858c hash:long wallpapers:Vector<WallPaper> = account.WallPapers;
codeSettings#ad253d78 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true allow_missed_call:flags.5?true allow_firebase:flags.7?true logout_tokens:flags.6?Vector<bytes> token:flags.8?string app_sandbox:flags.8?Bool = CodeSettings; codeSettings#ad253d78 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true allow_missed_call:flags.5?true allow_firebase:flags.7?true logout_tokens:flags.6?Vector<bytes> token:flags.8?string app_sandbox:flags.8?Bool = CodeSettings;
wallPaperSettings#1dc1bca4 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int second_background_color:flags.4?int third_background_color:flags.5?int fourth_background_color:flags.6?int intensity:flags.3?int rotation:flags.4?int = WallPaperSettings; wallPaperSettings#372efcd0 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int second_background_color:flags.4?int third_background_color:flags.5?int fourth_background_color:flags.6?int intensity:flags.3?int rotation:flags.4?int emoticon:flags.7?string = WallPaperSettings;
autoDownloadSettings#baa57628 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true stories_preload:flags.4?true photo_size_max:int video_size_max:long file_size_max:long video_upload_maxbitrate:int small_queue_active_operations_max:int large_queue_active_operations_max:int = AutoDownloadSettings; autoDownloadSettings#baa57628 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true stories_preload:flags.4?true photo_size_max:int video_size_max:long file_size_max:long video_upload_maxbitrate:int small_queue_active_operations_max:int large_queue_active_operations_max:int = AutoDownloadSettings;
account.autoDownloadSettings#63cacf26 low:AutoDownloadSettings medium:AutoDownloadSettings high:AutoDownloadSettings = account.AutoDownloadSettings; account.autoDownloadSettings#63cacf26 low:AutoDownloadSettings medium:AutoDownloadSettings high:AutoDownloadSettings = account.AutoDownloadSettings;
emojiKeyword#d5b3b9f9 keyword:string emoticons:Vector<string> = EmojiKeyword; emojiKeyword#d5b3b9f9 keyword:string emoticons:Vector<string> = EmojiKeyword;
@ -1070,7 +1076,7 @@ help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEnti
inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose; inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose;
inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose;
inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose;
inputStorePaymentPremiumGiveaway#7c9375e6 flags:# only_new_subscribers:flags.0?true boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> prize_description:flags.4?string random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose;
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod; paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
emojiStatusEmpty#2de11aae = EmojiStatus; emojiStatusEmpty#2de11aae = EmojiStatus;
@ -1148,7 +1154,9 @@ stories.allStoriesNotModified#1158fe3e flags:# state:string stealth_mode:Stories
stories.allStories#6efc5e81 flags:# has_more:flags.0?true count:int state:string peer_stories:Vector<PeerStories> chats:Vector<Chat> users:Vector<User> stealth_mode:StoriesStealthMode = stories.AllStories; stories.allStories#6efc5e81 flags:# has_more:flags.0?true count:int state:string peer_stories:Vector<PeerStories> chats:Vector<Chat> users:Vector<User> stealth_mode:StoriesStealthMode = stories.AllStories;
stories.stories#5dd8c3c8 count:int stories:Vector<StoryItem> chats:Vector<Chat> users:Vector<User> = stories.Stories; stories.stories#5dd8c3c8 count:int stories:Vector<StoryItem> chats:Vector<Chat> users:Vector<User> = stories.Stories;
storyView#b0bdeac5 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true user_id:long date:int reaction:flags.2?Reaction = StoryView; storyView#b0bdeac5 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true user_id:long date:int reaction:flags.2?Reaction = StoryView;
stories.storyViewsList#46e9b9ec flags:# count:int reactions_count:int views:Vector<StoryView> users:Vector<User> next_offset:flags.0?string = stories.StoryViewsList; storyViewPublicForward#9083670b flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true message:Message = StoryView;
storyViewPublicRepost#bd74cf49 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true peer_id:Peer story:StoryItem = StoryView;
stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count:int reactions_count:int views:Vector<StoryView> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryViewsList;
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews; stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
inputReplyToMessage#22c0f6d5 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> quote_offset:flags.4?int = InputReplyTo; inputReplyToMessage#22c0f6d5 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> quote_offset:flags.4?int = InputReplyTo;
inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo; inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo;
@ -1159,11 +1167,13 @@ mediaAreaVenue#be82db9c coordinates:MediaAreaCoordinates geo:GeoPoint title:stri
inputMediaAreaVenue#b282217f coordinates:MediaAreaCoordinates query_id:long result_id:string = MediaArea; inputMediaAreaVenue#b282217f coordinates:MediaAreaCoordinates query_id:long result_id:string = MediaArea;
mediaAreaGeoPoint#df8b3b22 coordinates:MediaAreaCoordinates geo:GeoPoint = MediaArea; mediaAreaGeoPoint#df8b3b22 coordinates:MediaAreaCoordinates geo:GeoPoint = MediaArea;
mediaAreaSuggestedReaction#14455871 flags:# dark:flags.0?true flipped:flags.1?true coordinates:MediaAreaCoordinates reaction:Reaction = MediaArea; mediaAreaSuggestedReaction#14455871 flags:# dark:flags.0?true flipped:flags.1?true coordinates:MediaAreaCoordinates reaction:Reaction = MediaArea;
mediaAreaChannelPost#770416af coordinates:MediaAreaCoordinates channel_id:long msg_id:int = MediaArea;
inputMediaAreaChannelPost#2271f2bf coordinates:MediaAreaCoordinates channel:InputChannel msg_id:int = MediaArea;
peerStories#9a35e999 flags:# peer:Peer max_read_id:flags.0?int stories:Vector<StoryItem> = PeerStories; peerStories#9a35e999 flags:# peer:Peer max_read_id:flags.0?int stories:Vector<StoryItem> = PeerStories;
stories.peerStories#cae68768 stories:PeerStories chats:Vector<Chat> users:Vector<User> = stories.PeerStories; stories.peerStories#cae68768 stories:PeerStories chats:Vector<Chat> users:Vector<User> = stories.PeerStories;
messages.webPage#fd5e12bd webpage:WebPage chats:Vector<Chat> users:Vector<User> = messages.WebPage; messages.webPage#fd5e12bd webpage:WebPage chats:Vector<Chat> users:Vector<User> = messages.WebPage;
premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.0?string store_quantity:flags.1?int currency:string amount:long = PremiumGiftCodeOption; premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.0?string store_quantity:flags.1?int currency:string amount:long = PremiumGiftCodeOption;
payments.checkedGiftCode#b722f158 flags:# via_giveaway:flags.2?true from_id:Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode; payments.checkedGiftCode#284a1096 flags:# via_giveaway:flags.2?true from_id:flags.4?Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode;
payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo; payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo;
payments.giveawayInfoResults#cd5570 flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int = payments.GiveawayInfo; payments.giveawayInfoResults#cd5570 flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int = payments.GiveawayInfo;
prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway; prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway;
@ -1182,9 +1192,13 @@ stats.publicForwards#93037e20 flags:# count:int forwards:Vector<PublicForward> n
peerColor#b54b5acf flags:# color:flags.0?int background_emoji_id:flags.1?long = PeerColor; peerColor#b54b5acf flags:# color:flags.0?int background_emoji_id:flags.1?long = PeerColor;
help.peerColorSet#26219a58 colors:Vector<int> = help.PeerColorSet; help.peerColorSet#26219a58 colors:Vector<int> = help.PeerColorSet;
help.peerColorProfileSet#767d61eb palette_colors:Vector<int> bg_colors:Vector<int> story_colors:Vector<int> = help.PeerColorSet; help.peerColorProfileSet#767d61eb palette_colors:Vector<int> bg_colors:Vector<int> story_colors:Vector<int> = help.PeerColorSet;
help.peerColorOption#135bd42f flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet = help.PeerColorOption; help.peerColorOption#ef8430ab flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int = help.PeerColorOption;
help.peerColorsNotModified#2ba1f5ce = help.PeerColors; help.peerColorsNotModified#2ba1f5ce = help.PeerColors;
help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors; help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors;
storyReaction#6090d6d5 peer_id:Peer date:int reaction:Reaction = StoryReaction;
storyReactionPublicForward#bbab2643 message:Message = StoryReaction;
storyReactionPublicRepost#cfcd0f13 peer_id:Peer story:StoryItem = StoryReaction;
stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector<StoryReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X; initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
@ -1481,7 +1495,7 @@ folders.editPeerFolders#6847d0ab folder_peers:Vector<InputFolderPeer> = Updates;
stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats; stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats;
stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph; stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats; stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats;
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; stats.getMessagePublicForwards#5f150144 channel:InputChannel msg_id:int offset:string limit:int = stats.PublicForwards;
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats; 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.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.getStoryPublicForwards#a6437ef6 peer:InputPeer id:int offset:string limit:int = stats.PublicForwards;
@ -1502,7 +1516,7 @@ stories.getStoriesArchive#b4352016 peer:InputPeer offset_id:int limit:int = stor
stories.getStoriesByID#5774ca74 peer:InputPeer id:Vector<int> = stories.Stories; stories.getStoriesByID#5774ca74 peer:InputPeer id:Vector<int> = stories.Stories;
stories.readStories#a556dac8 peer:InputPeer max_id:int = Vector<int>; stories.readStories#a556dac8 peer:InputPeer max_id:int = Vector<int>;
stories.incrementStoryViews#b2028afb peer:InputPeer id:Vector<int> = Bool; stories.incrementStoryViews#b2028afb peer:InputPeer id:Vector<int> = Bool;
stories.getStoryViewsList#7ed23c57 flags:# just_contacts:flags.0?true reactions_first:flags.2?true peer:InputPeer q:flags.1?string id:int offset:string limit:int = stories.StoryViewsList; stories.getStoryViewsList#7ed23c57 flags:# just_contacts:flags.0?true reactions_first:flags.2?true forwards_first:flags.3?true peer:InputPeer q:flags.1?string id:int offset:string limit:int = stories.StoryViewsList;
stories.exportStoryLink#7b8def20 peer:InputPeer id:int = ExportedStoryLink; stories.exportStoryLink#7b8def20 peer:InputPeer id:int = ExportedStoryLink;
stories.report#1923fa8c peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool; stories.report#1923fa8c peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool;
stories.activateStealthMode#57bbd166 flags:# past:flags.0?true future:flags.1?true = Updates; stories.activateStealthMode#57bbd166 flags:# past:flags.0?true future:flags.1?true = Updates;

View File

@ -97,11 +97,11 @@ userStatusLastMonth#77ebc742 = UserStatus;
chatEmpty#29562865 id:long = Chat; chatEmpty#29562865 id:long = Chat;
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat; chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
chatForbidden#6592a1a7 id:long title:string = Chat; chatForbidden#6592a1a7 id:long title:string = Chat;
channel#8e87ccd8 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 = 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; 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; 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#723027bd 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 = ChatFull; channelFull#f2bcb6f 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 = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
@ -131,7 +131,8 @@ messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia; messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia; messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia; messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia;
messageMediaGiveaway#58260664 flags:# only_new_subscribers:flags.0?true channels:Vector<long> countries_iso2:flags.1?Vector<string> quantity:int months:int until_date:int = MessageMedia; messageMediaGiveaway#daad85b0 flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.2?true channels:Vector<long> countries_iso2:flags.1?Vector<string> prize_description:flags.3?string quantity:int months:int until_date:int = MessageMedia;
messageMediaGiveawayResults#c6991068 flags:# only_new_subscribers:flags.0?true refunded:flags.2?true channel_id:long additional_peers_count:flags.3?int launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector<long> months:int prize_description:flags.1?string until_date:int = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction; messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction; messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction;
@ -169,9 +170,9 @@ messageActionGiftPremium#c83d6aec flags:# currency:string amount:long months:int
messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction; messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction;
messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction; messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction;
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction; messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
messageActionRequestedPeer#fe77345d button_id:int peer:Peer = MessageAction; messageActionRequestedPeer#31518e9b button_id:int peers:Vector<Peer> = MessageAction;
messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction; messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction;
messageActionGiftCode#d2cfdb0e flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string = MessageAction; messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long = MessageAction;
messageActionGiveawayLaunch#332ba9ed = MessageAction; messageActionGiveawayLaunch#332ba9ed = MessageAction;
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction; messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction;
@ -395,6 +396,8 @@ updateSentStoryReaction#7d627683 peer:Peer story_id:int reaction:Reaction = Upda
updateBotChatBoost#904dd49c peer:Peer boost:Boost qts:int = Update; updateBotChatBoost#904dd49c peer:Peer boost:Boost qts:int = Update;
updateChannelViewForumAsMessages#7b68920 channel_id:long enabled:Bool = Update; updateChannelViewForumAsMessages#7b68920 channel_id:long enabled:Bool = Update;
updatePeerWallpaper#ae3f101d flags:# wallpaper_overridden:flags.1?true peer:Peer wallpaper:flags.0?WallPaper = Update; updatePeerWallpaper#ae3f101d flags:# wallpaper_overridden:flags.1?true peer:Peer wallpaper:flags.0?WallPaper = Update;
updateBotMessageReaction#ac21d3ce peer:Peer msg_id:int date:int actor:Peer old_reactions:Vector<Reaction> new_reactions:Vector<Reaction> qts:int = Update;
updateBotMessageReactions#9cb7759 peer:Peer msg_id:int date:int reactions:Vector<ReactionCount> qts:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -591,8 +594,9 @@ inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet;
inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet; inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet; inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = 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 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 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;
messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet; messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet;
messages.stickerSetNotModified#d3f924eb = messages.StickerSet; messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
@ -616,7 +620,7 @@ inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = Keyboard
keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton; keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
keyboardButtonWebView#13767230 text:string url:string = KeyboardButton; keyboardButtonWebView#13767230 text:string url:string = KeyboardButton;
keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton; keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton;
keyboardButtonRequestPeer#d0b468c text:string button_id:int peer_type:RequestPeerType = KeyboardButton; keyboardButtonRequestPeer#53d7bfd8 text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton;
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow; keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
@ -969,8 +973,10 @@ channelAdminLogEventActionEditTopic#f06fe208 prev_topic:ForumTopic new_topic:For
channelAdminLogEventActionDeleteTopic#ae168909 topic:ForumTopic = ChannelAdminLogEventAction; channelAdminLogEventActionDeleteTopic#ae168909 topic:ForumTopic = ChannelAdminLogEventAction;
channelAdminLogEventActionPinTopic#5d8d353b flags:# prev_topic:flags.0?ForumTopic new_topic:flags.1?ForumTopic = ChannelAdminLogEventAction; channelAdminLogEventActionPinTopic#5d8d353b flags:# prev_topic:flags.0?ForumTopic new_topic:flags.1?ForumTopic = ChannelAdminLogEventAction;
channelAdminLogEventActionToggleAntiSpam#64f36dfc new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionToggleAntiSpam#64f36dfc new_value:Bool = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeColor#3c2b247b prev_value:int new_value:int = ChannelAdminLogEventAction; channelAdminLogEventActionChangePeerColor#5796e780 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeBackgroundEmoji#445fc434 prev_value:long new_value:long = ChannelAdminLogEventAction; channelAdminLogEventActionChangeProfilePeerColor#5e477b25 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeWallpaper#31bb5d52 prev_value:WallPaper new_value:WallPaper = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_value:EmojiStatus = ChannelAdminLogEventAction;
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent; channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
@ -1147,7 +1153,7 @@ account.wallPapers#cdc3858c hash:long wallpapers:Vector<WallPaper> = account.Wal
codeSettings#ad253d78 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true allow_missed_call:flags.5?true allow_firebase:flags.7?true logout_tokens:flags.6?Vector<bytes> token:flags.8?string app_sandbox:flags.8?Bool = CodeSettings; codeSettings#ad253d78 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true allow_missed_call:flags.5?true allow_firebase:flags.7?true logout_tokens:flags.6?Vector<bytes> token:flags.8?string app_sandbox:flags.8?Bool = CodeSettings;
wallPaperSettings#1dc1bca4 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int second_background_color:flags.4?int third_background_color:flags.5?int fourth_background_color:flags.6?int intensity:flags.3?int rotation:flags.4?int = WallPaperSettings; wallPaperSettings#372efcd0 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int second_background_color:flags.4?int third_background_color:flags.5?int fourth_background_color:flags.6?int intensity:flags.3?int rotation:flags.4?int emoticon:flags.7?string = WallPaperSettings;
autoDownloadSettings#baa57628 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true stories_preload:flags.4?true photo_size_max:int video_size_max:long file_size_max:long video_upload_maxbitrate:int small_queue_active_operations_max:int large_queue_active_operations_max:int = AutoDownloadSettings; autoDownloadSettings#baa57628 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true stories_preload:flags.4?true photo_size_max:int video_size_max:long file_size_max:long video_upload_maxbitrate:int small_queue_active_operations_max:int large_queue_active_operations_max:int = AutoDownloadSettings;
@ -1426,7 +1432,7 @@ help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEnti
inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose; inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose;
inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose;
inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose;
inputStorePaymentPremiumGiveaway#7c9375e6 flags:# only_new_subscribers:flags.0?true boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> prize_description:flags.4?string random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose;
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
@ -1553,8 +1559,10 @@ stories.allStories#6efc5e81 flags:# has_more:flags.0?true count:int state:string
stories.stories#5dd8c3c8 count:int stories:Vector<StoryItem> chats:Vector<Chat> users:Vector<User> = stories.Stories; stories.stories#5dd8c3c8 count:int stories:Vector<StoryItem> chats:Vector<Chat> users:Vector<User> = stories.Stories;
storyView#b0bdeac5 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true user_id:long date:int reaction:flags.2?Reaction = StoryView; storyView#b0bdeac5 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true user_id:long date:int reaction:flags.2?Reaction = StoryView;
storyViewPublicForward#9083670b flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true message:Message = StoryView;
storyViewPublicRepost#bd74cf49 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true peer_id:Peer story:StoryItem = StoryView;
stories.storyViewsList#46e9b9ec flags:# count:int reactions_count:int views:Vector<StoryView> users:Vector<User> next_offset:flags.0?string = stories.StoryViewsList; stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count:int reactions_count:int views:Vector<StoryView> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryViewsList;
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews; stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
@ -1571,6 +1579,8 @@ mediaAreaVenue#be82db9c coordinates:MediaAreaCoordinates geo:GeoPoint title:stri
inputMediaAreaVenue#b282217f coordinates:MediaAreaCoordinates query_id:long result_id:string = MediaArea; inputMediaAreaVenue#b282217f coordinates:MediaAreaCoordinates query_id:long result_id:string = MediaArea;
mediaAreaGeoPoint#df8b3b22 coordinates:MediaAreaCoordinates geo:GeoPoint = MediaArea; mediaAreaGeoPoint#df8b3b22 coordinates:MediaAreaCoordinates geo:GeoPoint = MediaArea;
mediaAreaSuggestedReaction#14455871 flags:# dark:flags.0?true flipped:flags.1?true coordinates:MediaAreaCoordinates reaction:Reaction = MediaArea; mediaAreaSuggestedReaction#14455871 flags:# dark:flags.0?true flipped:flags.1?true coordinates:MediaAreaCoordinates reaction:Reaction = MediaArea;
mediaAreaChannelPost#770416af coordinates:MediaAreaCoordinates channel_id:long msg_id:int = MediaArea;
inputMediaAreaChannelPost#2271f2bf coordinates:MediaAreaCoordinates channel:InputChannel msg_id:int = MediaArea;
peerStories#9a35e999 flags:# peer:Peer max_read_id:flags.0?int stories:Vector<StoryItem> = PeerStories; peerStories#9a35e999 flags:# peer:Peer max_read_id:flags.0?int stories:Vector<StoryItem> = PeerStories;
@ -1580,7 +1590,7 @@ messages.webPage#fd5e12bd webpage:WebPage chats:Vector<Chat> users:Vector<User>
premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.0?string store_quantity:flags.1?int currency:string amount:long = PremiumGiftCodeOption; premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.0?string store_quantity:flags.1?int currency:string amount:long = PremiumGiftCodeOption;
payments.checkedGiftCode#b722f158 flags:# via_giveaway:flags.2?true from_id:Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode; payments.checkedGiftCode#284a1096 flags:# via_giveaway:flags.2?true from_id:flags.4?Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode;
payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo; payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo;
payments.giveawayInfoResults#cd5570 flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int = payments.GiveawayInfo; payments.giveawayInfoResults#cd5570 flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int = payments.GiveawayInfo;
@ -1614,11 +1624,17 @@ peerColor#b54b5acf flags:# color:flags.0?int background_emoji_id:flags.1?long =
help.peerColorSet#26219a58 colors:Vector<int> = help.PeerColorSet; help.peerColorSet#26219a58 colors:Vector<int> = help.PeerColorSet;
help.peerColorProfileSet#767d61eb palette_colors:Vector<int> bg_colors:Vector<int> story_colors:Vector<int> = help.PeerColorSet; help.peerColorProfileSet#767d61eb palette_colors:Vector<int> bg_colors:Vector<int> story_colors:Vector<int> = help.PeerColorSet;
help.peerColorOption#135bd42f flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet = help.PeerColorOption; help.peerColorOption#ef8430ab flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int = help.PeerColorOption;
help.peerColorsNotModified#2ba1f5ce = help.PeerColors; help.peerColorsNotModified#2ba1f5ce = help.PeerColors;
help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors; help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors;
storyReaction#6090d6d5 peer_id:Peer date:int reaction:Reaction = StoryReaction;
storyReactionPublicForward#bbab2643 message:Message = StoryReaction;
storyReactionPublicRepost#cfcd0f13 peer_id:Peer story:StoryItem = StoryReaction;
stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector<StoryReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1742,6 +1758,8 @@ account.deleteAutoSaveExceptions#53bc0020 = Bool;
account.invalidateSignInCodes#ca8ae8ba codes:Vector<string> = Bool; account.invalidateSignInCodes#ca8ae8ba codes:Vector<string> = Bool;
account.updateColor#7cefa15d flags:# for_profile:flags.1?true color:flags.2?int background_emoji_id:flags.0?long = Bool; account.updateColor#7cefa15d flags:# for_profile:flags.1?true color:flags.2?int background_emoji_id:flags.0?long = Bool;
account.getDefaultBackgroundEmojis#a60ab9ce hash:long = EmojiList; account.getDefaultBackgroundEmojis#a60ab9ce hash:long = EmojiList;
account.getChannelDefaultEmojiStatuses#7727a7d5 hash:long = account.EmojiStatuses;
account.getChannelRestrictedStatusEmojis#35a9e0d5 hash:long = EmojiList;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>; users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#b60f5918 id:InputUser = users.UserFull; users.getFullUser#b60f5918 id:InputUser = users.UserFull;
@ -1951,7 +1969,7 @@ messages.clearRecentReactions#9dfeefb4 = Bool;
messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates; messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates;
messages.setDefaultHistoryTTL#9eb51445 period:int = Bool; messages.setDefaultHistoryTTL#9eb51445 period:int = Bool;
messages.getDefaultHistoryTTL#658b7188 = DefaultHistoryTTL; messages.getDefaultHistoryTTL#658b7188 = DefaultHistoryTTL;
messages.sendBotRequestedPeer#fe38d01b peer:InputPeer msg_id:int button_id:int requested_peer:InputPeer = Updates; messages.sendBotRequestedPeer#91b2d060 peer:InputPeer msg_id:int button_id:int requested_peers:Vector<InputPeer> = Updates;
messages.getEmojiGroups#7488ce5b hash:int = messages.EmojiGroups; messages.getEmojiGroups#7488ce5b hash:int = messages.EmojiGroups;
messages.getEmojiStatusGroups#2ecd56cd hash:int = messages.EmojiGroups; messages.getEmojiStatusGroups#2ecd56cd hash:int = messages.EmojiGroups;
messages.getEmojiProfilePhotoGroups#21a548f3 hash:int = messages.EmojiGroups; messages.getEmojiProfilePhotoGroups#21a548f3 hash:int = messages.EmojiGroups;
@ -1986,7 +2004,6 @@ help.getNearestDc#1fb33026 = NearestDc;
help.getAppUpdate#522d5a7d source:string = help.AppUpdate; help.getAppUpdate#522d5a7d source:string = help.AppUpdate;
help.getInviteText#4d392343 = help.InviteText; help.getInviteText#4d392343 = help.InviteText;
help.getSupport#9cdf08cd = help.Support; help.getSupport#9cdf08cd = help.Support;
help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool; help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool;
help.getCdnConfig#52029342 = CdnConfig; help.getCdnConfig#52029342 = CdnConfig;
help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls; help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls;
@ -2063,9 +2080,10 @@ channels.toggleAntiSpam#68f3e4eb channel:InputChannel enabled:Bool = Updates;
channels.reportAntiSpamFalsePositive#a850a693 channel:InputChannel msg_id:int = Bool; channels.reportAntiSpamFalsePositive#a850a693 channel:InputChannel msg_id:int = Bool;
channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates; channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates;
channels.clickSponsoredMessage#18afbc93 channel:InputChannel random_id:bytes = Bool; channels.clickSponsoredMessage#18afbc93 channel:InputChannel random_id:bytes = Bool;
channels.updateColor#621a201f flags:# channel:InputChannel color:int background_emoji_id:flags.0?long = Updates; channels.updateColor#d8aa3671 flags:# for_profile:flags.1?true channel:InputChannel color:flags.2?int background_emoji_id:flags.0?long = Updates;
channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates; channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates;
channels.getChannelRecommendations#83b70d97 channel:InputChannel = messages.Chats; channels.getChannelRecommendations#83b70d97 channel:InputChannel = messages.Chats;
channels.updateEmojiStatus#f0d3e6a8 channel:InputChannel emoji_status:EmojiStatus = Updates;
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON; bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool; bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
@ -2155,7 +2173,7 @@ folders.editPeerFolders#6847d0ab folder_peers:Vector<InputFolderPeer> = Updates;
stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats; stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats;
stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph; stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats; stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats;
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; stats.getMessagePublicForwards#5f150144 channel:InputChannel msg_id:int offset:string limit:int = stats.PublicForwards;
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats; 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.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.getStoryPublicForwards#a6437ef6 peer:InputPeer id:int offset:string limit:int = stats.PublicForwards;
@ -2184,7 +2202,7 @@ stories.getStoriesByID#5774ca74 peer:InputPeer id:Vector<int> = stories.Stories;
stories.toggleAllStoriesHidden#7c2557c4 hidden:Bool = Bool; stories.toggleAllStoriesHidden#7c2557c4 hidden:Bool = Bool;
stories.readStories#a556dac8 peer:InputPeer max_id:int = Vector<int>; stories.readStories#a556dac8 peer:InputPeer max_id:int = Vector<int>;
stories.incrementStoryViews#b2028afb peer:InputPeer id:Vector<int> = Bool; stories.incrementStoryViews#b2028afb peer:InputPeer id:Vector<int> = Bool;
stories.getStoryViewsList#7ed23c57 flags:# just_contacts:flags.0?true reactions_first:flags.2?true peer:InputPeer q:flags.1?string id:int offset:string limit:int = stories.StoryViewsList; stories.getStoryViewsList#7ed23c57 flags:# just_contacts:flags.0?true reactions_first:flags.2?true forwards_first:flags.3?true peer:InputPeer q:flags.1?string id:int offset:string limit:int = stories.StoryViewsList;
stories.getStoriesViews#28e16cc8 peer:InputPeer id:Vector<int> = stories.StoryViews; stories.getStoriesViews#28e16cc8 peer:InputPeer id:Vector<int> = stories.StoryViews;
stories.exportStoryLink#7b8def20 peer:InputPeer id:int = ExportedStoryLink; stories.exportStoryLink#7b8def20 peer:InputPeer id:int = ExportedStoryLink;
stories.report#1923fa8c peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool; stories.report#1923fa8c peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool;
@ -2195,6 +2213,7 @@ stories.getAllReadPeerStories#9b5ae7f9 = Updates;
stories.getPeerMaxIDs#535983c3 id:Vector<InputPeer> = Vector<int>; stories.getPeerMaxIDs#535983c3 id:Vector<InputPeer> = Vector<int>;
stories.getChatsToSend#a56a8b60 = messages.Chats; stories.getChatsToSend#a56a8b60 = messages.Chats;
stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool; stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool;
stories.getStoryReactionsList#b9b2881f flags:# forwards_first:flags.2?true peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = stories.StoryReactionsList;
premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList; premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList;
premium.getMyBoosts#be77b4a = premium.MyBoosts; premium.getMyBoosts#be77b4a = premium.MyBoosts;