Introduce Web Bots (#1813)
This commit is contained in:
parent
14b603991f
commit
7b253a4103
@ -1,12 +1,24 @@
|
|||||||
import { Api as GramJs } from '../../../lib/gramjs';
|
import { Api as GramJs } from '../../../lib/gramjs';
|
||||||
import {
|
import {
|
||||||
ApiBotInlineMediaResult, ApiBotInlineResult, ApiBotInlineSwitchPm, ApiInlineResultType, ApiWebDocument,
|
ApiAttachMenuBot,
|
||||||
|
ApiAttachMenuBotIcon,
|
||||||
|
ApiBotCommand,
|
||||||
|
ApiBotInfo,
|
||||||
|
ApiBotInlineMediaResult,
|
||||||
|
ApiBotInlineResult,
|
||||||
|
ApiBotInlineSwitchPm,
|
||||||
|
ApiBotMenuButton,
|
||||||
|
ApiInlineResultType,
|
||||||
|
ApiWebDocument,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
import { buildApiPhoto, buildApiThumbnailFromStripped } from './common';
|
import { buildApiPhoto, buildApiThumbnailFromStripped } from './common';
|
||||||
import { buildVideoFromDocument } from './messages';
|
import { buildApiDocument, buildVideoFromDocument } from './messages';
|
||||||
import { buildStickerFromDocument } from './symbols';
|
import { buildStickerFromDocument } from './symbols';
|
||||||
|
import localDb from '../localDb';
|
||||||
|
import { buildApiPeerId } from './peers';
|
||||||
|
import { omitVirtualClassFields } from './helpers';
|
||||||
|
|
||||||
export function buildApiBotInlineResult(result: GramJs.BotInlineResult, queryId: string): ApiBotInlineResult {
|
export function buildApiBotInlineResult(result: GramJs.BotInlineResult, queryId: string): ApiBotInlineResult {
|
||||||
const {
|
const {
|
||||||
@ -50,6 +62,66 @@ export function buildBotSwitchPm(switchPm?: GramJs.InlineBotSwitchPM) {
|
|||||||
return switchPm ? pick(switchPm, ['text', 'startParam']) as ApiBotInlineSwitchPm : undefined;
|
return switchPm ? pick(switchPm, ['text', 'startParam']) as ApiBotInlineSwitchPm : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildApiAttachMenuBot(bot: GramJs.AttachMenuBot): ApiAttachMenuBot {
|
||||||
|
return {
|
||||||
|
id: bot.botId.toString(),
|
||||||
|
shortName: bot.shortName,
|
||||||
|
icons: bot.icons.map(buildApiAttachMenuIcon).filter(Boolean),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildApiAttachMenuIcon(icon: GramJs.AttachMenuBotIcon): ApiAttachMenuBotIcon | undefined {
|
||||||
|
if (!(icon.icon instanceof GramJs.Document)) return undefined;
|
||||||
|
|
||||||
|
const document = buildApiDocument(icon.icon);
|
||||||
|
|
||||||
|
if (!document) return undefined;
|
||||||
|
|
||||||
|
localDb.documents[String(icon.icon.id)] = icon.icon;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: icon.name,
|
||||||
|
document,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildApiWebDocument(document?: GramJs.TypeWebDocument): ApiWebDocument | undefined {
|
function buildApiWebDocument(document?: GramJs.TypeWebDocument): ApiWebDocument | undefined {
|
||||||
return document ? pick(document, ['url', 'mimeType']) : undefined;
|
return document ? pick(document, ['url', 'mimeType']) : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildApiBotInfo(botInfo: GramJs.BotInfo): ApiBotInfo {
|
||||||
|
const {
|
||||||
|
description, userId, commands, menuButton,
|
||||||
|
} = botInfo;
|
||||||
|
|
||||||
|
const botId = buildApiPeerId(userId, 'user');
|
||||||
|
const commandsArray = commands.map((command) => buildApiBotCommand(botId, command));
|
||||||
|
|
||||||
|
return {
|
||||||
|
botId,
|
||||||
|
description,
|
||||||
|
menuButton: buildApiBotMenuButton(menuButton),
|
||||||
|
commands: commandsArray.length ? commandsArray : undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildApiBotCommand(botId: string, command: GramJs.BotCommand): ApiBotCommand {
|
||||||
|
return {
|
||||||
|
botId,
|
||||||
|
...omitVirtualClassFields(command),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildApiBotMenuButton(menuButton: GramJs.TypeBotMenuButton): ApiBotMenuButton {
|
||||||
|
if (menuButton instanceof GramJs.BotMenuButton) {
|
||||||
|
return {
|
||||||
|
type: 'webApp',
|
||||||
|
text: menuButton.text,
|
||||||
|
url: menuButton.url,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'commands',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -149,7 +149,6 @@ function buildApiChatRestrictions(peerEntity: GramJs.TypeUser | GramJs.TypeChat)
|
|||||||
if (peerEntity instanceof GramJs.Chat) {
|
if (peerEntity instanceof GramJs.Chat) {
|
||||||
Object.assign(restrictions, {
|
Object.assign(restrictions, {
|
||||||
isNotJoined: peerEntity.left,
|
isNotJoined: peerEntity.left,
|
||||||
isForbidden: peerEntity.kicked,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -924,6 +924,9 @@ function buildAction(
|
|||||||
text = senderId === currentUserId ? 'ActionYouScoredInGame' : 'ActionUserScoredInGame';
|
text = senderId === currentUserId ? 'ActionYouScoredInGame' : 'ActionUserScoredInGame';
|
||||||
translationValues.push('%score%');
|
translationValues.push('%score%');
|
||||||
score = action.score;
|
score = action.score;
|
||||||
|
} else if (action instanceof GramJs.MessageActionWebViewDataSent) {
|
||||||
|
text = 'Notification.WebAppSentData';
|
||||||
|
translationValues.push(action.text);
|
||||||
} else {
|
} else {
|
||||||
text = 'ChatList.UnsupportedMessage';
|
text = 'ChatList.UnsupportedMessage';
|
||||||
}
|
}
|
||||||
@ -1067,6 +1070,22 @@ function buildReplyButtons(message: UniversalMessage): ApiReplyKeyboard | undefi
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (button instanceof GramJs.KeyboardButtonSimpleWebView) {
|
||||||
|
return {
|
||||||
|
type: 'simpleWebView',
|
||||||
|
text,
|
||||||
|
url: button.url,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button instanceof GramJs.KeyboardButtonWebView) {
|
||||||
|
return {
|
||||||
|
type: 'webView',
|
||||||
|
text,
|
||||||
|
url: button.url,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'unsupported',
|
type: 'unsupported',
|
||||||
text,
|
text,
|
||||||
|
|||||||
@ -105,13 +105,15 @@ export function buildApiNotifyException(
|
|||||||
notifySettings: GramJs.TypePeerNotifySettings, peer: GramJs.TypePeer, serverTimeOffset: number,
|
notifySettings: GramJs.TypePeerNotifySettings, peer: GramJs.TypePeer, serverTimeOffset: number,
|
||||||
) {
|
) {
|
||||||
const {
|
const {
|
||||||
silent, muteUntil, showPreviews, sound,
|
silent, muteUntil, showPreviews, otherSound,
|
||||||
} = notifySettings;
|
} = notifySettings;
|
||||||
|
|
||||||
|
const hasSound = Boolean(otherSound && !(otherSound instanceof GramJs.NotificationSoundNone));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chatId: getApiChatIdFromMtpPeer(peer),
|
chatId: getApiChatIdFromMtpPeer(peer),
|
||||||
isMuted: silent || (typeof muteUntil === 'number' && getServerTime(serverTimeOffset) < muteUntil),
|
isMuted: silent || (typeof muteUntil === 'number' && getServerTime(serverTimeOffset) < muteUntil),
|
||||||
...(sound === '' && { isSilent: true }),
|
...(!hasSound && { isSilent: true }),
|
||||||
...(showPreviews !== undefined && { shouldShowPreviews: Boolean(showPreviews) }),
|
...(showPreviews !== undefined && { shouldShowPreviews: Boolean(showPreviews) }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { Api as GramJs } from '../../../lib/gramjs';
|
import { Api as GramJs } from '../../../lib/gramjs';
|
||||||
import {
|
import {
|
||||||
ApiBotCommand, ApiUser, ApiUserStatus, ApiUserType,
|
ApiUser, ApiUserStatus, ApiUserType,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
import { buildApiPeerId } from './peers';
|
import { buildApiPeerId } from './peers';
|
||||||
|
import { buildApiBotInfo } from './bots';
|
||||||
|
|
||||||
export function buildApiUserFromFull(mtpUserFull: GramJs.users.UserFull): ApiUser {
|
export function buildApiUserFromFull(mtpUserFull: GramJs.users.UserFull): ApiUser {
|
||||||
const {
|
const {
|
||||||
@ -21,8 +22,7 @@ export function buildApiUserFromFull(mtpUserFull: GramJs.users.UserFull): ApiUse
|
|||||||
commonChatsCount,
|
commonChatsCount,
|
||||||
pinnedMessageId: pinnedMsgId,
|
pinnedMessageId: pinnedMsgId,
|
||||||
isBlocked: Boolean(blocked),
|
isBlocked: Boolean(blocked),
|
||||||
...(botInfo && { botDescription: botInfo.description }),
|
...(botInfo && { botInfo: buildApiBotInfo(botInfo) }),
|
||||||
...(botInfo && botInfo.commands.length && { botCommands: buildApiBotCommands(user.id, botInfo) }),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -57,6 +57,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
|||||||
...(mtpUser.accessHash && { accessHash: String(mtpUser.accessHash) }),
|
...(mtpUser.accessHash && { accessHash: String(mtpUser.accessHash) }),
|
||||||
...(avatarHash && { avatarHash }),
|
...(avatarHash && { avatarHash }),
|
||||||
...(mtpUser.bot && mtpUser.botInlinePlaceholder && { botPlaceholder: mtpUser.botInlinePlaceholder }),
|
...(mtpUser.bot && mtpUser.botInlinePlaceholder && { botPlaceholder: mtpUser.botInlinePlaceholder }),
|
||||||
|
...(mtpUser.bot && mtpUser.botAttachMenu && { isAttachMenuBot: mtpUser.botAttachMenu }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,14 +88,6 @@ export function buildApiUserStatus(mtpStatus?: GramJs.TypeUserStatus): ApiUserSt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildApiBotCommands(botId: string, botInfo: GramJs.BotInfo) {
|
|
||||||
return botInfo.commands.map(({ command, description }) => ({
|
|
||||||
botId,
|
|
||||||
command,
|
|
||||||
description,
|
|
||||||
})) as ApiBotCommand[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function buildApiUsersAndStatuses(mtpUsers: GramJs.TypeUser[]) {
|
export function buildApiUsersAndStatuses(mtpUsers: GramJs.TypeUser[]) {
|
||||||
const userStatusesById: Record<string, ApiUserStatus> = {};
|
const userStatusesById: Record<string, ApiUserStatus> = {};
|
||||||
const users: ApiUser[] = [];
|
const users: ApiUser[] = [];
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import {
|
|||||||
ApiSendMessageAction,
|
ApiSendMessageAction,
|
||||||
ApiSticker,
|
ApiSticker,
|
||||||
ApiVideo,
|
ApiVideo,
|
||||||
|
ApiThemeParameters,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
import localDb from '../localDb';
|
import localDb from '../localDb';
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
@ -466,6 +467,12 @@ export function buildSendMessageAction(action: ApiSendMessageAction) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildInputThemeParams(params: ApiThemeParameters) {
|
||||||
|
return new GramJs.DataJSON({
|
||||||
|
data: JSON.stringify(params),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function buildMtpPeerId(id: string, type: 'user' | 'chat' | 'channel') {
|
export function buildMtpPeerId(id: string, type: 'user' | 'chat' | 'channel') {
|
||||||
// Workaround for old-fashioned IDs stored locally
|
// Workaround for old-fashioned IDs stored locally
|
||||||
if (typeof id === 'number') {
|
if (typeof id === 'number') {
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
import BigInt from 'big-integer';
|
import BigInt from 'big-integer';
|
||||||
import { Api as GramJs } from '../../../lib/gramjs';
|
import { Api as GramJs } from '../../../lib/gramjs';
|
||||||
|
|
||||||
import { ApiChat, ApiUser } from '../../types';
|
import { ApiChat, ApiThemeParameters, ApiUser } from '../../types';
|
||||||
|
|
||||||
import localDb from '../localDb';
|
import localDb from '../localDb';
|
||||||
import { invokeRequest } from './client';
|
import { invokeRequest } from './client';
|
||||||
import { buildInputPeer, generateRandomBigInt } from '../gramjsBuilders';
|
import { buildInputPeer, buildInputThemeParams, generateRandomBigInt } from '../gramjsBuilders';
|
||||||
import { buildApiUser } from '../apiBuilders/users';
|
import { buildApiUser } from '../apiBuilders/users';
|
||||||
import { buildApiBotInlineMediaResult, buildApiBotInlineResult, buildBotSwitchPm } from '../apiBuilders/bots';
|
import {
|
||||||
|
buildApiAttachMenuBot, buildApiBotInlineMediaResult, buildApiBotInlineResult, buildBotSwitchPm,
|
||||||
|
} from '../apiBuilders/bots';
|
||||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||||
import { addEntitiesWithPhotosToLocalDb, addUserToLocalDb, deserializeBytes } from '../helpers';
|
import { addEntitiesWithPhotosToLocalDb, addUserToLocalDb, deserializeBytes } from '../helpers';
|
||||||
import { omitVirtualClassFields } from '../apiBuilders/helpers';
|
import { omitVirtualClassFields } from '../apiBuilders/helpers';
|
||||||
|
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
}
|
}
|
||||||
@ -140,6 +143,132 @@ export async function startBot({
|
|||||||
}), true);
|
}), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function requestWebView({
|
||||||
|
isSilent,
|
||||||
|
peer,
|
||||||
|
bot,
|
||||||
|
url,
|
||||||
|
startParam,
|
||||||
|
replyToMessageId,
|
||||||
|
theme,
|
||||||
|
isFromBotMenu,
|
||||||
|
}: {
|
||||||
|
isSilent?: boolean;
|
||||||
|
peer: ApiChat | ApiUser;
|
||||||
|
bot: ApiUser;
|
||||||
|
url?: string;
|
||||||
|
startParam?: string;
|
||||||
|
replyToMessageId?: number;
|
||||||
|
theme?: ApiThemeParameters;
|
||||||
|
isFromBotMenu?: boolean;
|
||||||
|
}) {
|
||||||
|
const result = await invokeRequest(new GramJs.messages.RequestWebView({
|
||||||
|
silent: isSilent || undefined,
|
||||||
|
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||||
|
bot: buildInputPeer(bot.id, bot.accessHash),
|
||||||
|
replyToMsgId: replyToMessageId,
|
||||||
|
url,
|
||||||
|
startParam,
|
||||||
|
themeParams: theme ? buildInputThemeParams(theme) : undefined,
|
||||||
|
fromBotMenu: isFromBotMenu || undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (result instanceof GramJs.WebViewResultUrl) {
|
||||||
|
return {
|
||||||
|
url: result.url,
|
||||||
|
queryId: result.queryId.toString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function requestSimpleWebView({
|
||||||
|
bot, url, theme,
|
||||||
|
}: {
|
||||||
|
bot: ApiUser;
|
||||||
|
url: string;
|
||||||
|
theme?: ApiThemeParameters;
|
||||||
|
}) {
|
||||||
|
const result = await invokeRequest(new GramJs.messages.RequestSimpleWebView({
|
||||||
|
url,
|
||||||
|
bot: buildInputPeer(bot.id, bot.accessHash),
|
||||||
|
themeParams: theme ? buildInputThemeParams(theme) : undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return result?.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prolongWebView({
|
||||||
|
isSilent,
|
||||||
|
peer,
|
||||||
|
bot,
|
||||||
|
queryId,
|
||||||
|
replyToMessageId,
|
||||||
|
}: {
|
||||||
|
isSilent?: boolean;
|
||||||
|
peer: ApiChat | ApiUser;
|
||||||
|
bot: ApiUser;
|
||||||
|
queryId: string;
|
||||||
|
replyToMessageId?: number;
|
||||||
|
}) {
|
||||||
|
return invokeRequest(new GramJs.messages.ProlongWebView({
|
||||||
|
silent: isSilent || undefined,
|
||||||
|
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||||
|
bot: buildInputPeer(bot.id, bot.accessHash),
|
||||||
|
queryId: BigInt(queryId),
|
||||||
|
replyToMsgId: replyToMessageId,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendWebViewData({
|
||||||
|
bot, buttonText, data,
|
||||||
|
}: {
|
||||||
|
bot: ApiUser;
|
||||||
|
buttonText: string;
|
||||||
|
data: string;
|
||||||
|
}) {
|
||||||
|
const randomId = generateRandomBigInt();
|
||||||
|
await invokeRequest(new GramJs.messages.SendWebViewData({
|
||||||
|
bot: buildInputPeer(bot.id, bot.accessHash),
|
||||||
|
buttonText,
|
||||||
|
data,
|
||||||
|
randomId,
|
||||||
|
}), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadAttachMenuBots({
|
||||||
|
hash,
|
||||||
|
}: {
|
||||||
|
hash?: string;
|
||||||
|
}) {
|
||||||
|
const result = await invokeRequest(new GramJs.messages.GetAttachMenuBots({
|
||||||
|
hash: hash ? BigInt(hash) : undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (result instanceof GramJs.AttachMenuBots) {
|
||||||
|
addEntitiesWithPhotosToLocalDb(result.users);
|
||||||
|
return {
|
||||||
|
hash: result.hash.toString(),
|
||||||
|
bots: buildCollectionByKey(result.bots.map(buildApiAttachMenuBot), 'id'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toggleBotInAttachMenu({
|
||||||
|
bot,
|
||||||
|
isEnabled,
|
||||||
|
}: {
|
||||||
|
bot: ApiUser;
|
||||||
|
isEnabled: boolean;
|
||||||
|
}) {
|
||||||
|
return invokeRequest(new GramJs.messages.ToggleBotInAttachMenu({
|
||||||
|
bot: buildInputPeer(bot.id, bot.accessHash),
|
||||||
|
enabled: isEnabled,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
function processInlineBotResult(queryId: string, results: GramJs.TypeBotInlineResult[]) {
|
function processInlineBotResult(queryId: string, results: GramJs.TypeBotInlineResult[]) {
|
||||||
return results.map((result) => {
|
return results.map((result) => {
|
||||||
if (result instanceof GramJs.BotInlineMediaResult) {
|
if (result instanceof GramJs.BotInlineMediaResult) {
|
||||||
|
|||||||
@ -64,6 +64,7 @@ export {
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
answerCallbackButton, fetchTopInlineBots, fetchInlineBot, fetchInlineBotResults, sendInlineBotResult, startBot,
|
answerCallbackButton, fetchTopInlineBots, fetchInlineBot, fetchInlineBotResults, sendInlineBotResult, startBot,
|
||||||
|
requestWebView, requestSimpleWebView, sendWebViewData, prolongWebView, loadAttachMenuBots, toggleBotInAttachMenu,
|
||||||
} from './bots';
|
} from './bots';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@ -248,6 +248,9 @@ async function parseMedia(
|
|||||||
case ApiMediaFormat.Lottie: {
|
case ApiMediaFormat.Lottie: {
|
||||||
return new Blob([data], { type: mimeType });
|
return new Blob([data], { type: mimeType });
|
||||||
}
|
}
|
||||||
|
case ApiMediaFormat.Text: {
|
||||||
|
return data.toString();
|
||||||
|
}
|
||||||
case ApiMediaFormat.Progressive: {
|
case ApiMediaFormat.Progressive: {
|
||||||
return data.buffer;
|
return data.buffer;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ import { buildApiConfig } from '../apiBuilders/appConfig';
|
|||||||
import { addEntitiesWithPhotosToLocalDb } from '../helpers';
|
import { addEntitiesWithPhotosToLocalDb } from '../helpers';
|
||||||
|
|
||||||
const MAX_INT_32 = 2 ** 31 - 1;
|
const MAX_INT_32 = 2 ** 31 - 1;
|
||||||
const BETA_LANG_CODES = ['ar', 'fa', 'id', 'ko', 'uz'];
|
const BETA_LANG_CODES = ['ar', 'fa', 'id', 'ko', 'uz', 'en'];
|
||||||
|
|
||||||
export function updateProfile({
|
export function updateProfile({
|
||||||
firstName,
|
firstName,
|
||||||
|
|||||||
@ -44,11 +44,13 @@ import { buildApiNotifyException, buildPrivacyKey, buildPrivacyRules } from './a
|
|||||||
import { buildApiPhoto } from './apiBuilders/common';
|
import { buildApiPhoto } from './apiBuilders/common';
|
||||||
import {
|
import {
|
||||||
buildApiGroupCall,
|
buildApiGroupCall,
|
||||||
buildApiGroupCallParticipant, buildPhoneCall,
|
buildApiGroupCallParticipant,
|
||||||
|
buildPhoneCall,
|
||||||
getGroupCallId,
|
getGroupCallId,
|
||||||
} from './apiBuilders/calls';
|
} from './apiBuilders/calls';
|
||||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './apiBuilders/peers';
|
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './apiBuilders/peers';
|
||||||
import { buildApiEmojiInteraction } from './apiBuilders/symbols';
|
import { buildApiEmojiInteraction } from './apiBuilders/symbols';
|
||||||
|
import { buildApiBotMenuButton } from './apiBuilders/bots';
|
||||||
|
|
||||||
type Update = (
|
type Update = (
|
||||||
(GramJs.TypeUpdate | GramJs.TypeUpdates) & { _entities?: (GramJs.TypeUser | GramJs.TypeChat)[] }
|
(GramJs.TypeUpdate | GramJs.TypeUpdates) & { _entities?: (GramJs.TypeUser | GramJs.TypeChat)[] }
|
||||||
@ -915,6 +917,23 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
|||||||
callId: update.phoneCallId.toString(),
|
callId: update.phoneCallId.toString(),
|
||||||
data: Array.from(update.data),
|
data: Array.from(update.data),
|
||||||
});
|
});
|
||||||
|
} else if (update instanceof GramJs.UpdateWebViewResultSent) {
|
||||||
|
const { queryId } = update;
|
||||||
|
|
||||||
|
onUpdate({
|
||||||
|
'@type': 'updateWebViewResultSent',
|
||||||
|
queryId: queryId.toString(),
|
||||||
|
});
|
||||||
|
} else if (update instanceof GramJs.UpdateBotMenuButton) {
|
||||||
|
const { botId, button } = update;
|
||||||
|
|
||||||
|
const id = buildApiPeerId(botId, 'user');
|
||||||
|
|
||||||
|
onUpdate({
|
||||||
|
'@type': 'updateBotMenuButton',
|
||||||
|
botId: id,
|
||||||
|
button: buildApiBotMenuButton(button),
|
||||||
|
});
|
||||||
} else if (DEBUG) {
|
} else if (DEBUG) {
|
||||||
const params = typeof update === 'object' && 'className' in update ? update.className : update;
|
const params = typeof update === 'object' && 'className' in update ? update.className : update;
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
|||||||
@ -44,3 +44,22 @@ export interface ApiBotCommand {
|
|||||||
command: string;
|
command: string;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ApiBotMenuButtonCommands = {
|
||||||
|
type: 'commands';
|
||||||
|
};
|
||||||
|
|
||||||
|
type ApiBotMenuButtonWebApp = {
|
||||||
|
type: 'webApp';
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ApiBotMenuButton = ApiBotMenuButtonWebApp | ApiBotMenuButtonCommands;
|
||||||
|
|
||||||
|
export interface ApiBotInfo {
|
||||||
|
botId: string;
|
||||||
|
commands?: ApiBotCommand[];
|
||||||
|
description: string;
|
||||||
|
menuButton: ApiBotMenuButton;
|
||||||
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ export enum ApiMediaFormat {
|
|||||||
Lottie,
|
Lottie,
|
||||||
Progressive,
|
Progressive,
|
||||||
Stream,
|
Stream,
|
||||||
|
Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApiParsedMedia = string | Blob | ArrayBuffer;
|
export type ApiParsedMedia = string | Blob | ArrayBuffer;
|
||||||
|
|||||||
@ -395,6 +395,18 @@ interface ApiKeyboardButtonUrl {
|
|||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ApiKeyboardButtonSimpleWebView {
|
||||||
|
type: 'simpleWebView';
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ApiKeyboardButtonWebView {
|
||||||
|
type: 'webView';
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface ApiKeyboardButtonCallback {
|
interface ApiKeyboardButtonCallback {
|
||||||
type: 'callback';
|
type: 'callback';
|
||||||
text: string;
|
text: string;
|
||||||
@ -407,7 +419,7 @@ interface ApiKeyboardButtonRequestPoll {
|
|||||||
isQuiz?: boolean;
|
isQuiz?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ApiKeyboardButtonSwitchInline {
|
interface ApiKeyboardButtonSwitchBotInline {
|
||||||
type: 'switchBotInline';
|
type: 'switchBotInline';
|
||||||
text: string;
|
text: string;
|
||||||
query: string;
|
query: string;
|
||||||
@ -426,8 +438,10 @@ export type ApiKeyboardButton = (
|
|||||||
| ApiKeyboardButtonUrl
|
| ApiKeyboardButtonUrl
|
||||||
| ApiKeyboardButtonCallback
|
| ApiKeyboardButtonCallback
|
||||||
| ApiKeyboardButtonRequestPoll
|
| ApiKeyboardButtonRequestPoll
|
||||||
| ApiKeyboardButtonSwitchInline
|
| ApiKeyboardButtonSwitchBotInline
|
||||||
| ApiKeyboardButtonUserProfile
|
| ApiKeyboardButtonUserProfile
|
||||||
|
| ApiKeyboardButtonWebView
|
||||||
|
| ApiKeyboardButtonSimpleWebView
|
||||||
);
|
);
|
||||||
|
|
||||||
export type ApiKeyboardButtons = ApiKeyboardButton[][];
|
export type ApiKeyboardButtons = ApiKeyboardButton[][];
|
||||||
@ -448,6 +462,15 @@ export type ApiSendMessageAction = {
|
|||||||
type: 'cancel' | 'typing' | 'recordAudio' | 'chooseSticker' | 'playingGame';
|
type: 'cancel' | 'typing' | 'recordAudio' | 'chooseSticker' | 'playingGame';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ApiThemeParameters = {
|
||||||
|
bg_color: string;
|
||||||
|
text_color: string;
|
||||||
|
hint_color: string;
|
||||||
|
link_color: string;
|
||||||
|
button_color: string;
|
||||||
|
button_text_color: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const MAIN_THREAD_ID = -1;
|
export const MAIN_THREAD_ID = -1;
|
||||||
|
|
||||||
// `Symbol` can not be transferred from worker
|
// `Symbol` can not be transferred from worker
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
ApiGroupCall, ApiPhoneCall,
|
ApiGroupCall, ApiPhoneCall,
|
||||||
} from './calls';
|
} from './calls';
|
||||||
|
import { ApiBotMenuButton } from './bots';
|
||||||
|
|
||||||
export type ApiUpdateReady = {
|
export type ApiUpdateReady = {
|
||||||
'@type': 'updateApiReady';
|
'@type': 'updateApiReady';
|
||||||
@ -486,6 +487,17 @@ export type ApiUpdatePhoneCallConnectionState = {
|
|||||||
connectionState: RTCPeerConnectionState;
|
connectionState: RTCPeerConnectionState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ApiUpdateWebViewResultSent = {
|
||||||
|
'@type': 'updateWebViewResultSent';
|
||||||
|
queryId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ApiUpdateBotMenuButton = {
|
||||||
|
'@type': 'updateBotMenuButton';
|
||||||
|
botId: string;
|
||||||
|
button: ApiBotMenuButton;
|
||||||
|
};
|
||||||
|
|
||||||
export type ApiUpdate = (
|
export type ApiUpdate = (
|
||||||
ApiUpdateReady | ApiUpdateSession |
|
ApiUpdateReady | ApiUpdateSession |
|
||||||
ApiUpdateAuthorizationState | ApiUpdateAuthorizationError | ApiUpdateConnectionState | ApiUpdateCurrentUser |
|
ApiUpdateAuthorizationState | ApiUpdateAuthorizationError | ApiUpdateConnectionState | ApiUpdateCurrentUser |
|
||||||
@ -501,14 +513,14 @@ export type ApiUpdate = (
|
|||||||
ApiUpdateFavoriteStickers | ApiUpdateStickerSet |
|
ApiUpdateFavoriteStickers | ApiUpdateStickerSet |
|
||||||
ApiUpdateNewScheduledMessage | ApiUpdateScheduledMessageSendSucceeded | ApiUpdateScheduledMessage |
|
ApiUpdateNewScheduledMessage | ApiUpdateScheduledMessageSendSucceeded | ApiUpdateScheduledMessage |
|
||||||
ApiUpdateDeleteScheduledMessages | ApiUpdateResetMessages |
|
ApiUpdateDeleteScheduledMessages | ApiUpdateResetMessages |
|
||||||
ApiUpdateTwoFaError | ApiUpdateTwoFaStateWaitCode |
|
ApiUpdateTwoFaError | ApiUpdateTwoFaStateWaitCode | ApiUpdateWebViewResultSent |
|
||||||
ApiUpdateNotifySettings | ApiUpdateNotifyExceptions | ApiUpdatePeerBlocked | ApiUpdatePrivacy |
|
ApiUpdateNotifySettings | ApiUpdateNotifyExceptions | ApiUpdatePeerBlocked | ApiUpdatePrivacy |
|
||||||
ApiUpdateServerTimeOffset | ApiUpdateShowInvite | ApiUpdateMessageReactions |
|
ApiUpdateServerTimeOffset | ApiUpdateShowInvite | ApiUpdateMessageReactions |
|
||||||
ApiUpdateGroupCallParticipants | ApiUpdateGroupCallConnection | ApiUpdateGroupCall | ApiUpdateGroupCallStreams |
|
ApiUpdateGroupCallParticipants | ApiUpdateGroupCallConnection | ApiUpdateGroupCall | ApiUpdateGroupCallStreams |
|
||||||
ApiUpdateGroupCallConnectionState | ApiUpdateGroupCallLeavePresentation | ApiUpdateGroupCallChatId |
|
ApiUpdateGroupCallConnectionState | ApiUpdateGroupCallLeavePresentation | ApiUpdateGroupCallChatId |
|
||||||
ApiUpdatePendingJoinRequests | ApiUpdatePaymentVerificationNeeded | ApiUpdatePaymentStateCompleted |
|
ApiUpdatePendingJoinRequests | ApiUpdatePaymentVerificationNeeded | ApiUpdatePaymentStateCompleted |
|
||||||
ApiUpdatePhoneCall | ApiUpdatePhoneCallSignalingData | ApiUpdatePhoneCallMediaState |
|
ApiUpdatePhoneCall | ApiUpdatePhoneCallSignalingData | ApiUpdatePhoneCallMediaState |
|
||||||
ApiUpdatePhoneCallConnectionState
|
ApiUpdatePhoneCallConnectionState | ApiUpdateBotMenuButton
|
||||||
);
|
);
|
||||||
|
|
||||||
export type OnApiUpdate = (update: ApiUpdate) => void;
|
export type OnApiUpdate = (update: ApiUpdate) => void;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { ApiPhoto } from './messages';
|
import { ApiDocument, ApiPhoto } from './messages';
|
||||||
import { ApiBotCommand } from './bots';
|
import { ApiBotInfo } from './bots';
|
||||||
|
|
||||||
export interface ApiUser {
|
export interface ApiUser {
|
||||||
id: string;
|
id: string;
|
||||||
@ -24,6 +24,7 @@ export interface ApiUser {
|
|||||||
isFullyLoaded: boolean;
|
isFullyLoaded: boolean;
|
||||||
};
|
};
|
||||||
fakeType?: ApiFakeType;
|
fakeType?: ApiFakeType;
|
||||||
|
isAttachMenuBot?: boolean;
|
||||||
|
|
||||||
// Obtained from GetFullUser / UserFullInfo
|
// Obtained from GetFullUser / UserFullInfo
|
||||||
fullInfo?: ApiUserFullInfo;
|
fullInfo?: ApiUserFullInfo;
|
||||||
@ -33,9 +34,8 @@ export interface ApiUserFullInfo {
|
|||||||
isBlocked?: boolean;
|
isBlocked?: boolean;
|
||||||
bio?: string;
|
bio?: string;
|
||||||
commonChatsCount?: number;
|
commonChatsCount?: number;
|
||||||
botDescription?: string;
|
|
||||||
pinnedMessageId?: number;
|
pinnedMessageId?: number;
|
||||||
botCommands?: ApiBotCommand[];
|
botInfo?: ApiBotInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApiFakeType = 'fake' | 'scam';
|
export type ApiFakeType = 'fake' | 'scam';
|
||||||
@ -50,3 +50,14 @@ export interface ApiUserStatus {
|
|||||||
wasOnline?: number;
|
wasOnline?: number;
|
||||||
expires?: number;
|
expires?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiAttachMenuBot {
|
||||||
|
id: string;
|
||||||
|
shortName: string;
|
||||||
|
icons: ApiAttachMenuBotIcon[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiAttachMenuBotIcon {
|
||||||
|
name: string;
|
||||||
|
document: ApiDocument;
|
||||||
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -6,6 +6,9 @@ export { default as Notifications } from '../components/main/Notifications';
|
|||||||
export { default as SafeLinkModal } from '../components/main/SafeLinkModal';
|
export { default as SafeLinkModal } from '../components/main/SafeLinkModal';
|
||||||
export { default as HistoryCalendar } from '../components/main/HistoryCalendar';
|
export { default as HistoryCalendar } from '../components/main/HistoryCalendar';
|
||||||
export { default as NewContactModal } from '../components/main/NewContactModal';
|
export { default as NewContactModal } from '../components/main/NewContactModal';
|
||||||
|
export { default as WebAppModal } from '../components/main/WebAppModal';
|
||||||
|
export { default as BotTrustModal } from '../components/main/BotTrustModal';
|
||||||
|
export { default as BotAttachModal } from '../components/main/BotAttachModal';
|
||||||
|
|
||||||
export { default as CalendarModal } from '../components/common/CalendarModal';
|
export { default as CalendarModal } from '../components/common/CalendarModal';
|
||||||
export { default as DeleteMessageModal } from '../components/common/DeleteMessageModal';
|
export { default as DeleteMessageModal } from '../components/common/DeleteMessageModal';
|
||||||
|
|||||||
@ -54,7 +54,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const senderTitle = message?.forwardInfo?.hiddenUserName || (sender && getSenderTitle(lang, sender));
|
const senderTitle = sender ? getSenderTitle(lang, sender) : message?.forwardInfo?.hiddenUserName;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
16
src/components/main/BotAttachModal.async.tsx
Normal file
16
src/components/main/BotAttachModal.async.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React, { FC, memo } from '../../lib/teact/teact';
|
||||||
|
import { Bundles } from '../../util/moduleLoader';
|
||||||
|
|
||||||
|
import { OwnProps } from './BotAttachModal';
|
||||||
|
|
||||||
|
import useModuleLoader from '../../hooks/useModuleLoader';
|
||||||
|
|
||||||
|
const BotAttachModalAsync: FC<OwnProps> = (props) => {
|
||||||
|
const { bot } = props;
|
||||||
|
const BotAttachModal = useModuleLoader(Bundles.Extra, 'BotAttachModal', !bot);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
return BotAttachModal ? <BotAttachModal {...props} /> : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(BotAttachModalAsync);
|
||||||
34
src/components/main/BotAttachModal.tsx
Normal file
34
src/components/main/BotAttachModal.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React, { FC } from '../../lib/teact/teact';
|
||||||
|
import { getActions } from '../../global';
|
||||||
|
|
||||||
|
import { ApiUser } from '../../api/types';
|
||||||
|
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
|
import ConfirmDialog from '../ui/ConfirmDialog';
|
||||||
|
|
||||||
|
export type OwnProps = {
|
||||||
|
bot?: ApiUser;
|
||||||
|
};
|
||||||
|
|
||||||
|
const BotAttachModal: FC<OwnProps> = ({
|
||||||
|
bot,
|
||||||
|
}) => {
|
||||||
|
const { closeBotAttachRequestModal, confirmBotAttachRequest } = getActions();
|
||||||
|
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
|
const name = bot?.firstName;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmDialog
|
||||||
|
isOpen={Boolean(bot)}
|
||||||
|
onClose={closeBotAttachRequestModal}
|
||||||
|
confirmHandler={confirmBotAttachRequest}
|
||||||
|
title={name}
|
||||||
|
textParts={lang('WebApp.AddToAttachmentText', name)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BotAttachModal;
|
||||||
16
src/components/main/BotTrustModal.async.tsx
Normal file
16
src/components/main/BotTrustModal.async.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React, { FC, memo } from '../../lib/teact/teact';
|
||||||
|
import { Bundles } from '../../util/moduleLoader';
|
||||||
|
|
||||||
|
import { OwnProps } from './BotTrustModal';
|
||||||
|
|
||||||
|
import useModuleLoader from '../../hooks/useModuleLoader';
|
||||||
|
|
||||||
|
const BotTrustModalAsync: FC<OwnProps> = (props) => {
|
||||||
|
const { bot } = props;
|
||||||
|
const BotTrustModal = useModuleLoader(Bundles.Extra, 'BotTrustModal', !bot);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
return BotTrustModal ? <BotTrustModal {...props} /> : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(BotTrustModalAsync);
|
||||||
47
src/components/main/BotTrustModal.tsx
Normal file
47
src/components/main/BotTrustModal.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
|
||||||
|
import { getActions } from '../../global';
|
||||||
|
|
||||||
|
import { ApiUser } from '../../api/types';
|
||||||
|
|
||||||
|
import { getUserFullName } from '../../global/helpers';
|
||||||
|
import renderText from '../common/helpers/renderText';
|
||||||
|
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
|
|
||||||
|
import ConfirmDialog from '../ui/ConfirmDialog';
|
||||||
|
|
||||||
|
export type OwnProps = {
|
||||||
|
bot?: ApiUser;
|
||||||
|
type?: 'game' | 'webApp';
|
||||||
|
};
|
||||||
|
|
||||||
|
const BotTrustModal: FC<OwnProps> = ({ bot, type }) => {
|
||||||
|
const { cancelBotTrustRequest, markBotTrusted } = getActions();
|
||||||
|
const lang = useLang();
|
||||||
|
// Keep props a little bit longer, to show correct text on closing animation
|
||||||
|
const previousBot = usePrevious(bot, false);
|
||||||
|
const previousType = usePrevious(type, false);
|
||||||
|
const currentBot = bot || previousBot;
|
||||||
|
const currentType = type || previousType;
|
||||||
|
|
||||||
|
const handleBotTrustAccept = useCallback(() => {
|
||||||
|
markBotTrusted({ botId: bot!.id });
|
||||||
|
}, [markBotTrusted, bot]);
|
||||||
|
|
||||||
|
const title = currentType === 'game' ? lang('AppName') : lang('BotOpenPageTitle');
|
||||||
|
const text = currentType === 'game' ? lang('BotPermissionGameAlert', getUserFullName(currentBot))
|
||||||
|
: lang('BotOpenPageMessage', getUserFullName(currentBot));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmDialog
|
||||||
|
isOpen={Boolean(bot)}
|
||||||
|
onClose={cancelBotTrustRequest}
|
||||||
|
confirmHandler={handleBotTrustAccept}
|
||||||
|
title={title}
|
||||||
|
textParts={renderText(text, ['br', 'simple_markdown'])}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(BotTrustModal);
|
||||||
@ -4,7 +4,9 @@ import React, {
|
|||||||
import { getActions, withGlobal } from '../../global';
|
import { getActions, withGlobal } from '../../global';
|
||||||
|
|
||||||
import { LangCode } from '../../types';
|
import { LangCode } from '../../types';
|
||||||
import { ApiMessage, ApiUpdateAuthorizationStateType, ApiUpdateConnectionStateType } from '../../api/types';
|
import {
|
||||||
|
ApiChat, ApiMessage, ApiUpdateAuthorizationStateType, ApiUpdateConnectionStateType,
|
||||||
|
} from '../../api/types';
|
||||||
import { GlobalState } from '../../global/types';
|
import { GlobalState } from '../../global/types';
|
||||||
|
|
||||||
import '../../global/actions/all';
|
import '../../global/actions/all';
|
||||||
@ -54,10 +56,14 @@ import ActiveCallHeader from '../calls/ActiveCallHeader.async';
|
|||||||
import PhoneCall from '../calls/phone/PhoneCall.async';
|
import PhoneCall from '../calls/phone/PhoneCall.async';
|
||||||
import NewContactModal from './NewContactModal.async';
|
import NewContactModal from './NewContactModal.async';
|
||||||
import RatePhoneCallModal from '../calls/phone/RatePhoneCallModal.async';
|
import RatePhoneCallModal from '../calls/phone/RatePhoneCallModal.async';
|
||||||
|
import WebAppModal from './WebAppModal.async';
|
||||||
|
import BotTrustModal from './BotTrustModal.async';
|
||||||
|
import BotAttachModal from './BotAttachModal.async';
|
||||||
|
|
||||||
import './Main.scss';
|
import './Main.scss';
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
|
chat?: ApiChat;
|
||||||
connectionState?: ApiUpdateConnectionStateType;
|
connectionState?: ApiUpdateConnectionStateType;
|
||||||
authState?: ApiUpdateAuthorizationStateType;
|
authState?: ApiUpdateAuthorizationStateType;
|
||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
@ -84,6 +90,9 @@ type StateProps = {
|
|||||||
openedGame?: GlobalState['openedGame'];
|
openedGame?: GlobalState['openedGame'];
|
||||||
gameTitle?: string;
|
gameTitle?: string;
|
||||||
isRatePhoneCallModalOpen?: boolean;
|
isRatePhoneCallModalOpen?: boolean;
|
||||||
|
webApp?: GlobalState['webApp'];
|
||||||
|
botTrustRequest?: GlobalState['botTrustRequest'];
|
||||||
|
botAttachRequest?: GlobalState['botAttachRequest'];
|
||||||
};
|
};
|
||||||
|
|
||||||
const NOTIFICATION_INTERVAL = 1000;
|
const NOTIFICATION_INTERVAL = 1000;
|
||||||
@ -120,6 +129,9 @@ const Main: FC<StateProps> = ({
|
|||||||
openedGame,
|
openedGame,
|
||||||
gameTitle,
|
gameTitle,
|
||||||
isRatePhoneCallModalOpen,
|
isRatePhoneCallModalOpen,
|
||||||
|
botTrustRequest,
|
||||||
|
botAttachRequest,
|
||||||
|
webApp,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
sync,
|
sync,
|
||||||
@ -138,6 +150,7 @@ const Main: FC<StateProps> = ({
|
|||||||
openStickerSetShortName,
|
openStickerSetShortName,
|
||||||
checkVersionNotification,
|
checkVersionNotification,
|
||||||
loadAppConfig,
|
loadAppConfig,
|
||||||
|
loadAttachMenuBots,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
if (DEBUG && !DEBUG_isLogged) {
|
if (DEBUG && !DEBUG_isLogged) {
|
||||||
@ -163,10 +176,11 @@ const Main: FC<StateProps> = ({
|
|||||||
loadNotificationExceptions();
|
loadNotificationExceptions();
|
||||||
loadTopInlineBots();
|
loadTopInlineBots();
|
||||||
loadEmojiKeywords({ language: BASE_EMOJI_KEYWORD_LANG });
|
loadEmojiKeywords({ language: BASE_EMOJI_KEYWORD_LANG });
|
||||||
|
loadAttachMenuBots();
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
lastSyncTime, loadAnimatedEmojis, loadEmojiKeywords, loadNotificationExceptions, loadNotificationSettings,
|
lastSyncTime, loadAnimatedEmojis, loadEmojiKeywords, loadNotificationExceptions, loadNotificationSettings,
|
||||||
loadTopInlineBots, updateIsOnline, loadAvailableReactions, loadAppConfig,
|
loadTopInlineBots, updateIsOnline, loadAvailableReactions, loadAppConfig, loadAttachMenuBots,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Language-based API calls
|
// Language-based API calls
|
||||||
@ -366,10 +380,13 @@ const Main: FC<StateProps> = ({
|
|||||||
isByPhoneNumber={newContactByPhoneNumber}
|
isByPhoneNumber={newContactByPhoneNumber}
|
||||||
/>
|
/>
|
||||||
<GameModal openedGame={openedGame} gameTitle={gameTitle} />
|
<GameModal openedGame={openedGame} gameTitle={gameTitle} />
|
||||||
|
<WebAppModal webApp={webApp} />
|
||||||
<DownloadManager />
|
<DownloadManager />
|
||||||
<PhoneCall isActive={isPhoneCallActive} />
|
<PhoneCall isActive={isPhoneCallActive} />
|
||||||
<UnreadCount isForAppBadge />
|
<UnreadCount isForAppBadge />
|
||||||
<RatePhoneCallModal isOpen={isRatePhoneCallModalOpen} />
|
<RatePhoneCallModal isOpen={isRatePhoneCallModalOpen} />
|
||||||
|
<BotTrustModal bot={botTrustRequest?.bot} type={botTrustRequest?.type} />
|
||||||
|
<BotAttachModal bot={botAttachRequest?.bot} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -433,6 +450,9 @@ export default memo(withGlobal(
|
|||||||
openedGame,
|
openedGame,
|
||||||
gameTitle,
|
gameTitle,
|
||||||
isRatePhoneCallModalOpen: Boolean(global.ratingPhoneCall),
|
isRatePhoneCallModalOpen: Boolean(global.ratingPhoneCall),
|
||||||
|
botTrustRequest: global.botTrustRequest,
|
||||||
|
botAttachRequest: global.botAttachRequest,
|
||||||
|
webApp: global.webApp,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(Main));
|
)(Main));
|
||||||
|
|||||||
16
src/components/main/WebAppModal.async.tsx
Normal file
16
src/components/main/WebAppModal.async.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React, { FC, memo } from '../../lib/teact/teact';
|
||||||
|
import { Bundles } from '../../util/moduleLoader';
|
||||||
|
|
||||||
|
import { OwnProps } from './WebAppModal';
|
||||||
|
|
||||||
|
import useModuleLoader from '../../hooks/useModuleLoader';
|
||||||
|
|
||||||
|
const WebAppModalAsync: FC<OwnProps> = (props) => {
|
||||||
|
const { webApp } = props;
|
||||||
|
const WebAppModal = useModuleLoader(Bundles.Extra, 'WebAppModal', !webApp);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
return WebAppModal ? <WebAppModal {...props} /> : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(WebAppModalAsync);
|
||||||
69
src/components/main/WebAppModal.scss
Normal file
69
src/components/main/WebAppModal.scss
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
.WebAppModal {
|
||||||
|
.modal-header {
|
||||||
|
border-bottom: 1px solid var(--color-dividers);
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-dialog {
|
||||||
|
height: 75%;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
border-bottom-right-radius: var(--border-radius-default);
|
||||||
|
border-bottom-left-radius: var(--border-radius-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
.web-app-frame {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
&.with-button {
|
||||||
|
height: calc(100% - 56px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.web-app-button {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
transform: translateY(100%);
|
||||||
|
transition: 0.25s ease-in-out transform;
|
||||||
|
|
||||||
|
&.visible {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.hidden {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Spinner {
|
||||||
|
position: absolute;
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.modal-dialog {
|
||||||
|
background-color: var(--color-background);
|
||||||
|
border-radius: 0;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
max-height: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
292
src/components/main/WebAppModal.tsx
Normal file
292
src/components/main/WebAppModal.tsx
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
import React, {
|
||||||
|
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||||
|
} from '../../lib/teact/teact';
|
||||||
|
import { getActions, withGlobal } from '../../global';
|
||||||
|
|
||||||
|
import { ApiChat } from '../../api/types';
|
||||||
|
import { GlobalState } from '../../global/types';
|
||||||
|
import { ThemeKey } from '../../types';
|
||||||
|
|
||||||
|
import windowSize from '../../util/windowSize';
|
||||||
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
|
import { selectCurrentChat, selectTheme } from '../../global/selectors';
|
||||||
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
import { extractCurrentThemeParams, validateHexColor } from '../../util/themeStyle';
|
||||||
|
|
||||||
|
import useInterval from '../../hooks/useInterval';
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
|
import useOnChange from '../../hooks/useOnChange';
|
||||||
|
import useWebAppFrame, { WebAppInboundEvent } from './hooks/useWebAppFrame';
|
||||||
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
|
|
||||||
|
import Modal from '../ui/Modal';
|
||||||
|
import Button from '../ui/Button';
|
||||||
|
import DropdownMenu from '../ui/DropdownMenu';
|
||||||
|
import MenuItem from '../ui/MenuItem';
|
||||||
|
import Spinner from '../ui/Spinner';
|
||||||
|
|
||||||
|
import './WebAppModal.scss';
|
||||||
|
|
||||||
|
type WebAppButton = {
|
||||||
|
isVisible: boolean;
|
||||||
|
isActive: boolean;
|
||||||
|
text: string;
|
||||||
|
color: string;
|
||||||
|
textColor: string;
|
||||||
|
isProgressVisible: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OwnProps = {
|
||||||
|
webApp?: GlobalState['webApp'];
|
||||||
|
};
|
||||||
|
|
||||||
|
type StateProps = {
|
||||||
|
isInstalled?: boolean;
|
||||||
|
chat?: ApiChat;
|
||||||
|
theme?: ThemeKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MAIN_BUTTON_ANIMATION_TIME = 250;
|
||||||
|
const PROLONG_INTERVAL = 45000; // 45s
|
||||||
|
const ANIMATION_WAIT = 400;
|
||||||
|
|
||||||
|
const WebAppModal: FC<OwnProps & StateProps> = ({
|
||||||
|
webApp,
|
||||||
|
chat,
|
||||||
|
isInstalled,
|
||||||
|
theme,
|
||||||
|
}) => {
|
||||||
|
const {
|
||||||
|
closeWebApp, sendWebViewData, prolongWebView, toggleBotInAttachMenu,
|
||||||
|
} = getActions();
|
||||||
|
const [mainButton, setMainButton] = useState<WebAppButton | undefined>();
|
||||||
|
const lang = useLang();
|
||||||
|
const {
|
||||||
|
url, bot, buttonText, queryId,
|
||||||
|
} = webApp || {};
|
||||||
|
const isOpen = Boolean(url);
|
||||||
|
const isSimple = !queryId;
|
||||||
|
|
||||||
|
const handleEvent = useCallback((event: WebAppInboundEvent) => {
|
||||||
|
const { eventType } = event;
|
||||||
|
if (eventType === 'web_app_close') {
|
||||||
|
closeWebApp();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventType === 'web_app_data_send') {
|
||||||
|
const { eventData } = event;
|
||||||
|
closeWebApp();
|
||||||
|
sendWebViewData({
|
||||||
|
bot: bot!,
|
||||||
|
buttonText: buttonText!,
|
||||||
|
data: eventData.data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventType === 'web_app_setup_main_button') {
|
||||||
|
const { eventData } = event;
|
||||||
|
const themeParams = extractCurrentThemeParams();
|
||||||
|
// Validate colors if they are present
|
||||||
|
const color = !eventData.color || validateHexColor(eventData.color) ? eventData.color
|
||||||
|
: themeParams.button_color;
|
||||||
|
const textColor = !eventData.text_color || validateHexColor(eventData.text_color) ? eventData.text_color
|
||||||
|
: themeParams.text_color;
|
||||||
|
setMainButton({
|
||||||
|
isVisible: eventData.is_visible && Boolean(eventData.text?.trim().length),
|
||||||
|
isActive: eventData.is_active,
|
||||||
|
text: eventData.text || '',
|
||||||
|
color,
|
||||||
|
textColor,
|
||||||
|
isProgressVisible: eventData.is_progress_visible,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [bot, buttonText, closeWebApp, sendWebViewData]);
|
||||||
|
|
||||||
|
const {
|
||||||
|
ref, reloadFrame, sendEvent, sendViewport, sendTheme,
|
||||||
|
} = useWebAppFrame(isOpen, isSimple, handleEvent);
|
||||||
|
|
||||||
|
const shouldShowMainButton = mainButton?.isVisible && mainButton.text.trim().length > 0;
|
||||||
|
|
||||||
|
useInterval(() => {
|
||||||
|
prolongWebView({
|
||||||
|
bot: bot!,
|
||||||
|
queryId: queryId!,
|
||||||
|
peer: chat!,
|
||||||
|
});
|
||||||
|
}, queryId ? PROLONG_INTERVAL : undefined, true);
|
||||||
|
|
||||||
|
const handleMainButtonClick = useCallback(() => {
|
||||||
|
sendEvent({
|
||||||
|
eventType: 'main_button_pressed',
|
||||||
|
});
|
||||||
|
}, [sendEvent]);
|
||||||
|
|
||||||
|
const handleRefreshClick = useCallback(() => {
|
||||||
|
reloadFrame(webApp!.url);
|
||||||
|
}, [reloadFrame, webApp]);
|
||||||
|
|
||||||
|
// Notify view that height changed
|
||||||
|
useOnChange(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
sendViewport();
|
||||||
|
}, ANIMATION_WAIT);
|
||||||
|
}, [mainButton?.isVisible, sendViewport]);
|
||||||
|
|
||||||
|
// Notify view that theme changed
|
||||||
|
useOnChange(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
sendTheme();
|
||||||
|
}, ANIMATION_WAIT);
|
||||||
|
}, [theme, sendTheme]);
|
||||||
|
|
||||||
|
// Prevent refresh when rotating device
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) return undefined;
|
||||||
|
windowSize.disableRefresh();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
windowSize.enableRefresh();
|
||||||
|
};
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
const handleToggleClick = useCallback(() => {
|
||||||
|
toggleBotInAttachMenu({
|
||||||
|
botId: bot!.id,
|
||||||
|
isEnabled: !isInstalled,
|
||||||
|
});
|
||||||
|
}, [bot, isInstalled, toggleBotInAttachMenu]);
|
||||||
|
|
||||||
|
const MoreMenuButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => {
|
||||||
|
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||||
|
<Button
|
||||||
|
round
|
||||||
|
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||||
|
size="smaller"
|
||||||
|
color="translucent"
|
||||||
|
className={isMenuOpen ? 'active' : ''}
|
||||||
|
onClick={onTrigger}
|
||||||
|
ariaLabel="More actions"
|
||||||
|
>
|
||||||
|
<i className="icon-more" />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const header = useMemo(() => {
|
||||||
|
return (
|
||||||
|
<div className="modal-header">
|
||||||
|
<Button
|
||||||
|
round
|
||||||
|
color="translucent"
|
||||||
|
size="smaller"
|
||||||
|
ariaLabel={lang('Close')}
|
||||||
|
onClick={closeWebApp}
|
||||||
|
>
|
||||||
|
<i className="icon-close" />
|
||||||
|
</Button>
|
||||||
|
<div className="modal-title">{bot?.firstName}</div>
|
||||||
|
<DropdownMenu
|
||||||
|
className="web-app-more-menu"
|
||||||
|
trigger={MoreMenuButton}
|
||||||
|
positionX="right"
|
||||||
|
>
|
||||||
|
<MenuItem icon="reload" onClick={handleRefreshClick}>{lang('WebApp.ReloadPage')}</MenuItem>
|
||||||
|
{bot?.isAttachMenuBot && (
|
||||||
|
<MenuItem icon={isInstalled ? 'stop' : 'install'} onClick={handleToggleClick} destructive={isInstalled}>
|
||||||
|
{lang(isInstalled ? 'WebApp.RemoveBot' : 'WebApp.AddToAttachmentAdd')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [
|
||||||
|
MoreMenuButton, bot, closeWebApp, handleRefreshClick, handleToggleClick, lang, isInstalled,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const prevMainButtonColor = usePrevious(mainButton?.color, true);
|
||||||
|
const prevMainButtonTextColor = usePrevious(mainButton?.textColor, true);
|
||||||
|
const prevMainButtonIsActive = usePrevious(mainButton && Boolean(mainButton.isActive), true);
|
||||||
|
const prevMainButtonText = usePrevious(mainButton?.text, true);
|
||||||
|
|
||||||
|
const mainButtonCurrentColor = mainButton?.color || prevMainButtonColor;
|
||||||
|
const mainButtonCurrentTextColor = mainButton?.textColor || prevMainButtonTextColor;
|
||||||
|
const mainButtonCurrentIsActive = mainButton?.isActive !== undefined ? mainButton.isActive : prevMainButtonIsActive;
|
||||||
|
const mainButtonCurrentText = mainButton?.text || prevMainButtonText;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) setMainButton(undefined);
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
const [shouldDecreaseWebFrameSize, setShouldDecreaseWebFrameSize] = useState(false);
|
||||||
|
const [shouldHideButton, setShouldHideButton] = useState(true);
|
||||||
|
|
||||||
|
const buttonChangeTimeout = useRef<ReturnType<typeof setTimeout>>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (buttonChangeTimeout.current) clearTimeout(buttonChangeTimeout.current);
|
||||||
|
if (!shouldShowMainButton) {
|
||||||
|
setShouldDecreaseWebFrameSize(false);
|
||||||
|
buttonChangeTimeout.current = setTimeout(() => {
|
||||||
|
setShouldHideButton(true);
|
||||||
|
}, MAIN_BUTTON_ANIMATION_TIME);
|
||||||
|
} else {
|
||||||
|
setShouldHideButton(false);
|
||||||
|
buttonChangeTimeout.current = setTimeout(() => {
|
||||||
|
setShouldDecreaseWebFrameSize(true);
|
||||||
|
}, MAIN_BUTTON_ANIMATION_TIME);
|
||||||
|
}
|
||||||
|
}, [setShouldDecreaseWebFrameSize, shouldShowMainButton]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
className="WebAppModal"
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={closeWebApp}
|
||||||
|
header={header}
|
||||||
|
hasCloseButton
|
||||||
|
>
|
||||||
|
{isOpen && (
|
||||||
|
<>
|
||||||
|
<iframe
|
||||||
|
ref={ref}
|
||||||
|
className={buildClassName('web-app-frame', shouldDecreaseWebFrameSize && 'with-button')}
|
||||||
|
src={url}
|
||||||
|
title={`${bot?.firstName} Web App`}
|
||||||
|
sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
|
||||||
|
allow="camera; microphone; geolocation;"
|
||||||
|
allowFullScreen
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className={buildClassName(
|
||||||
|
'web-app-button',
|
||||||
|
shouldShowMainButton && 'visible',
|
||||||
|
shouldHideButton && 'hidden',
|
||||||
|
)}
|
||||||
|
style={`background-color: ${mainButtonCurrentColor}; color: ${mainButtonCurrentTextColor}`}
|
||||||
|
disabled={!mainButtonCurrentIsActive}
|
||||||
|
onClick={handleMainButtonClick}
|
||||||
|
>
|
||||||
|
{mainButtonCurrentText}
|
||||||
|
{mainButton?.isProgressVisible && <Spinner color="white" />}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(withGlobal<OwnProps>(
|
||||||
|
(global, { webApp }): StateProps => {
|
||||||
|
const { bot } = webApp || {};
|
||||||
|
const isInstalled = Boolean(bot && global.attachMenu.bots[bot.id]);
|
||||||
|
const chat = selectCurrentChat(global);
|
||||||
|
const theme = selectTheme(global);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isInstalled,
|
||||||
|
chat,
|
||||||
|
theme,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
)(WebAppModal));
|
||||||
148
src/components/main/hooks/useWebAppFrame.ts
Normal file
148
src/components/main/hooks/useWebAppFrame.ts
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
import useWindowSize from '../../../hooks/useWindowSize';
|
||||||
|
import { useCallback, useEffect, useRef } from '../../../lib/teact/teact';
|
||||||
|
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
||||||
|
|
||||||
|
export type WebAppInboundEvent = {
|
||||||
|
eventType: 'web_app_data_send';
|
||||||
|
eventData: {
|
||||||
|
data: string;
|
||||||
|
};
|
||||||
|
} | {
|
||||||
|
eventType: 'web_app_setup_main_button';
|
||||||
|
eventData: {
|
||||||
|
is_visible: boolean;
|
||||||
|
is_active: boolean;
|
||||||
|
text: string;
|
||||||
|
color: string;
|
||||||
|
text_color: string;
|
||||||
|
is_progress_visible: boolean;
|
||||||
|
};
|
||||||
|
} | {
|
||||||
|
eventType: 'web_app_request_viewport';
|
||||||
|
} | {
|
||||||
|
eventType: 'web_app_request_theme';
|
||||||
|
} | {
|
||||||
|
eventType: 'web_app_ready';
|
||||||
|
} | {
|
||||||
|
eventType: 'web_app_expand';
|
||||||
|
} | {
|
||||||
|
eventType: 'web_app_close';
|
||||||
|
};
|
||||||
|
|
||||||
|
type WebAppOutboundEvent = {
|
||||||
|
eventType: 'viewport_changed';
|
||||||
|
eventData: {
|
||||||
|
height: number;
|
||||||
|
width?: number;
|
||||||
|
is_expanded?: boolean;
|
||||||
|
};
|
||||||
|
} | {
|
||||||
|
eventType: 'theme_changed';
|
||||||
|
eventData: {
|
||||||
|
theme_params: {
|
||||||
|
bg_color: string;
|
||||||
|
text_color: string;
|
||||||
|
hint_color: string;
|
||||||
|
link_color: string;
|
||||||
|
button_color: string;
|
||||||
|
button_text_color: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} | {
|
||||||
|
eventType: 'main_button_pressed';
|
||||||
|
};
|
||||||
|
|
||||||
|
const useWebAppFrame = (isOpen: boolean, isSimpleView: boolean, onEvent: (event: WebAppInboundEvent) => void) => {
|
||||||
|
// eslint-disable-next-line no-null/no-null
|
||||||
|
const ref = useRef<HTMLIFrameElement>(null);
|
||||||
|
const ignoreEventsRef = useRef<boolean>(false);
|
||||||
|
const windowSize = useWindowSize();
|
||||||
|
|
||||||
|
const reloadFrame = useCallback((url: string) => {
|
||||||
|
if (!ref.current) return;
|
||||||
|
const frame = ref.current;
|
||||||
|
frame.src = 'about:blank';
|
||||||
|
frame.addEventListener('load', () => {
|
||||||
|
frame.src = url;
|
||||||
|
}, { once: true });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const sendEvent = useCallback((event: WebAppOutboundEvent) => {
|
||||||
|
if (!ref.current?.contentWindow) return;
|
||||||
|
ref.current.contentWindow.postMessage(JSON.stringify(event), '*');
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const sendViewport = useCallback(() => {
|
||||||
|
if (!ref.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { width, height } = ref.current.getBoundingClientRect();
|
||||||
|
sendEvent({
|
||||||
|
eventType: 'viewport_changed',
|
||||||
|
eventData: {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
is_expanded: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, [sendEvent]);
|
||||||
|
|
||||||
|
const sendTheme = useCallback(() => {
|
||||||
|
sendEvent({
|
||||||
|
eventType: 'theme_changed',
|
||||||
|
eventData: {
|
||||||
|
theme_params: extractCurrentThemeParams(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, [sendEvent]);
|
||||||
|
|
||||||
|
const handleMessage = useCallback((event: MessageEvent<string>) => {
|
||||||
|
if (ignoreEventsRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(event.data) as WebAppInboundEvent;
|
||||||
|
// Handle some app requests here to simplify hook usage
|
||||||
|
if (data.eventType === 'web_app_request_viewport') {
|
||||||
|
sendViewport();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.eventType === 'web_app_request_theme') {
|
||||||
|
sendTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.eventType === 'web_app_data_send') {
|
||||||
|
if (!isSimpleView) return; // Allowed only in simple view
|
||||||
|
ignoreEventsRef.current = true;
|
||||||
|
}
|
||||||
|
onEvent(data);
|
||||||
|
} catch (err) {
|
||||||
|
// Ignore other messages
|
||||||
|
}
|
||||||
|
}, [isSimpleView, onEvent, sendTheme, sendViewport]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (windowSize) {
|
||||||
|
sendViewport();
|
||||||
|
}
|
||||||
|
}, [sendViewport, windowSize]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener('message', handleMessage);
|
||||||
|
return () => window.removeEventListener('message', handleMessage);
|
||||||
|
}, [handleMessage]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpen && ref.current?.contentWindow) {
|
||||||
|
sendViewport();
|
||||||
|
ignoreEventsRef.current = false;
|
||||||
|
}
|
||||||
|
}, [isOpen, sendViewport]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
ref, sendEvent, reloadFrame, sendViewport, sendTheme,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useWebAppFrame;
|
||||||
@ -208,7 +208,7 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
|
|||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="smaller"
|
||||||
ariaLabel="Volume"
|
ariaLabel="Volume"
|
||||||
withClickPropagation
|
noPreventDefault
|
||||||
>
|
>
|
||||||
<i className={volumeIcon} onClick={handleVolumeClick} />
|
<i className={volumeIcon} onClick={handleVolumeClick} />
|
||||||
{!IS_IOS && (
|
{!IS_IOS && (
|
||||||
|
|||||||
@ -410,7 +410,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
canReportChat,
|
canReportChat,
|
||||||
canDeleteChat: getCanDeleteChat(chat),
|
canDeleteChat: getCanDeleteChat(chat),
|
||||||
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
|
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
|
||||||
botCommands: chatBot?.fullInfo?.botCommands,
|
botCommands: chatBot?.fullInfo?.botInfo?.commands,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(HeaderMenuContainer));
|
)(HeaderMenuContainer));
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
|
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
|
||||||
|
import { getActions } from '../../global';
|
||||||
|
|
||||||
import { ApiMessage } from '../../api/types';
|
import { ApiMessage } from '../../api/types';
|
||||||
|
|
||||||
import { getPictogramDimensions } from '../common/helpers/mediaDimensions';
|
import { getPictogramDimensions } from '../common/helpers/mediaDimensions';
|
||||||
import { getMessageMediaHash } from '../../global/helpers';
|
import { getMessageMediaHash, getMessageSingleInlineButton } from '../../global/helpers';
|
||||||
|
import { renderMessageSummary } from '../common/helpers/renderMessageText';
|
||||||
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
import { IS_TOUCH_ENV } from '../../util/environment';
|
||||||
|
|
||||||
import useMedia from '../../hooks/useMedia';
|
import useMedia from '../../hooks/useMedia';
|
||||||
import useWebpThumbnail from '../../hooks/useWebpThumbnail';
|
import useWebpThumbnail from '../../hooks/useWebpThumbnail';
|
||||||
|
|
||||||
import ConfirmDialog from '../ui/ConfirmDialog';
|
|
||||||
import Button from '../ui/Button';
|
|
||||||
import RippleEffect from '../ui/RippleEffect';
|
|
||||||
import buildClassName from '../../util/buildClassName';
|
|
||||||
import useFlag from '../../hooks/useFlag';
|
import useFlag from '../../hooks/useFlag';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import { renderMessageSummary } from '../common/helpers/renderMessageText';
|
|
||||||
|
|
||||||
|
import RippleEffect from '../ui/RippleEffect';
|
||||||
|
import ConfirmDialog from '../ui/ConfirmDialog';
|
||||||
|
import Button from '../ui/Button';
|
||||||
import PinnedMessageNavigation from './PinnedMessageNavigation';
|
import PinnedMessageNavigation from './PinnedMessageNavigation';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
@ -31,6 +33,7 @@ type OwnProps = {
|
|||||||
const HeaderPinnedMessage: FC<OwnProps> = ({
|
const HeaderPinnedMessage: FC<OwnProps> = ({
|
||||||
message, count, index, customTitle, className, onUnpinMessage, onClick, onAllPinnedClick,
|
message, count, index, customTitle, className, onUnpinMessage, onClick, onAllPinnedClick,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { clickBotInlineButton } = getActions();
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const mediaThumbnail = useWebpThumbnail(message);
|
const mediaThumbnail = useWebpThumbnail(message);
|
||||||
const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'pictogram'));
|
const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'pictogram'));
|
||||||
@ -46,6 +49,16 @@ const HeaderPinnedMessage: FC<OwnProps> = ({
|
|||||||
}
|
}
|
||||||
}, [closeUnpinDialog, onUnpinMessage, message.id]);
|
}, [closeUnpinDialog, onUnpinMessage, message.id]);
|
||||||
|
|
||||||
|
const inlineButton = getMessageSingleInlineButton(message);
|
||||||
|
|
||||||
|
const handleInlineButtonClick = useCallback(() => {
|
||||||
|
if (inlineButton) {
|
||||||
|
clickBotInlineButton({ messageId: message.id, button: inlineButton });
|
||||||
|
}
|
||||||
|
}, [clickBotInlineButton, inlineButton, message.id]);
|
||||||
|
|
||||||
|
const [noHoverColor, markNoHoverColor, unmarkNoHoverColor] = useFlag();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={buildClassName('HeaderPinnedMessage-wrapper', className)}>
|
<div className={buildClassName('HeaderPinnedMessage-wrapper', className)}>
|
||||||
{count > 1 && (
|
{count > 1 && (
|
||||||
@ -79,7 +92,11 @@ const HeaderPinnedMessage: FC<OwnProps> = ({
|
|||||||
confirmLabel="Unpin"
|
confirmLabel="Unpin"
|
||||||
confirmHandler={handleUnpinMessage}
|
confirmHandler={handleUnpinMessage}
|
||||||
/>
|
/>
|
||||||
<div className="HeaderPinnedMessage" onClick={onClick} dir={lang.isRtl ? 'rtl' : undefined}>
|
<div
|
||||||
|
className={buildClassName('HeaderPinnedMessage', noHoverColor && 'no-hover')}
|
||||||
|
onClick={onClick}
|
||||||
|
dir={lang.isRtl ? 'rtl' : undefined}
|
||||||
|
>
|
||||||
<PinnedMessageNavigation
|
<PinnedMessageNavigation
|
||||||
count={count}
|
count={count}
|
||||||
index={index}
|
index={index}
|
||||||
@ -90,9 +107,20 @@ const HeaderPinnedMessage: FC<OwnProps> = ({
|
|||||||
{customTitle || `${lang('PinnedMessage')} ${index > 0 ? `#${count - index}` : ''}`}
|
{customTitle || `${lang('PinnedMessage')} ${index > 0 ? `#${count - index}` : ''}`}
|
||||||
</div>
|
</div>
|
||||||
<p dir="auto">{text}</p>
|
<p dir="auto">{text}</p>
|
||||||
|
<RippleEffect />
|
||||||
</div>
|
</div>
|
||||||
|
{inlineButton && (
|
||||||
<RippleEffect />
|
<Button
|
||||||
|
size="tiny"
|
||||||
|
className="inline-button"
|
||||||
|
onClick={handleInlineButtonClick}
|
||||||
|
shouldStopPropagation
|
||||||
|
onMouseEnter={!IS_TOUCH_ENV ? markNoHoverColor : undefined}
|
||||||
|
onMouseLeave={!IS_TOUCH_ENV ? unmarkNoHoverColor : undefined}
|
||||||
|
>
|
||||||
|
{inlineButton.text}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -591,7 +591,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
let botDescription: string | undefined;
|
let botDescription: string | undefined;
|
||||||
if (selectIsChatBotNotStarted(global, chatId)) {
|
if (selectIsChatBotNotStarted(global, chatId)) {
|
||||||
if (chatBot.fullInfo) {
|
if (chatBot.fullInfo) {
|
||||||
botDescription = chatBot.fullInfo.botDescription || 'NoMessages';
|
botDescription = chatBot.fullInfo.botInfo?.description || 'NoMessages';
|
||||||
} else {
|
} else {
|
||||||
botDescription = 'Updating bot info...';
|
botDescription = 'Updating bot info...';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -421,8 +421,9 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
&:hover {
|
&:hover:not(.no-hover) {
|
||||||
background-color: var(--color-interactive-element-hover);
|
background-color: var(--color-interactive-element-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,6 +466,8 @@
|
|||||||
margin-inline-start: 0.375rem;
|
margin-inline-start: 0.375rem;
|
||||||
margin-top: 0.125rem;
|
margin-top: 0.125rem;
|
||||||
max-width: 15rem;
|
max-width: 15rem;
|
||||||
|
min-width: 8rem;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
@media (min-width: 1440px) and (max-width: 1500px) {
|
@media (min-width: 1440px) and (max-width: 1500px) {
|
||||||
max-width: 14rem;
|
max-width: 14rem;
|
||||||
@ -500,6 +503,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline-button {
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
border-radius: 1.5rem;
|
||||||
|
padding: 0 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: none;
|
||||||
|
height: 2rem;
|
||||||
|
max-width: 10rem;
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.emoji-small {
|
.emoji-small {
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
|
|||||||
@ -15,6 +15,11 @@
|
|||||||
top: -2.875rem;
|
top: -2.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bubble {
|
||||||
|
max-height: 20rem;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.is-pointer-env & {
|
.is-pointer-env & {
|
||||||
> .backdrop {
|
> .backdrop {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -31,3 +36,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bot-attach-context-menu {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|||||||
@ -2,9 +2,13 @@ import React, {
|
|||||||
FC, memo, useCallback, useEffect,
|
FC, memo, useCallback, useEffect,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
|
|
||||||
|
import { GlobalState } from '../../../global/types';
|
||||||
|
import { ISettings } from '../../../types';
|
||||||
|
|
||||||
import { CONTENT_TYPES_WITH_PREVIEW } from '../../../config';
|
import { CONTENT_TYPES_WITH_PREVIEW } from '../../../config';
|
||||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||||
import { openSystemFilesDialog } from '../../../util/systemFilesDialog';
|
import { openSystemFilesDialog } from '../../../util/systemFilesDialog';
|
||||||
|
|
||||||
import useMouseInside from '../../../hooks/useMouseInside';
|
import useMouseInside from '../../../hooks/useMouseInside';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useFlag from '../../../hooks/useFlag';
|
import useFlag from '../../../hooks/useFlag';
|
||||||
@ -12,23 +16,39 @@ import useFlag from '../../../hooks/useFlag';
|
|||||||
import ResponsiveHoverButton from '../../ui/ResponsiveHoverButton';
|
import ResponsiveHoverButton from '../../ui/ResponsiveHoverButton';
|
||||||
import Menu from '../../ui/Menu';
|
import Menu from '../../ui/Menu';
|
||||||
import MenuItem from '../../ui/MenuItem';
|
import MenuItem from '../../ui/MenuItem';
|
||||||
|
import AttachmentMenuBotItem from './AttachmentMenuBotItem';
|
||||||
|
|
||||||
import './AttachMenu.scss';
|
import './AttachMenu.scss';
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
|
chatId: string;
|
||||||
isButtonVisible: boolean;
|
isButtonVisible: boolean;
|
||||||
canAttachMedia: boolean;
|
canAttachMedia: boolean;
|
||||||
canAttachPolls: boolean;
|
canAttachPolls: boolean;
|
||||||
|
isScheduled?: boolean;
|
||||||
|
isPrivateChat?: boolean;
|
||||||
|
attachMenuBots: GlobalState['attachMenu']['bots'];
|
||||||
onFileSelect: (files: File[], isQuick: boolean) => void;
|
onFileSelect: (files: File[], isQuick: boolean) => void;
|
||||||
onPollCreate: () => void;
|
onPollCreate: () => void;
|
||||||
|
theme: ISettings['theme'];
|
||||||
};
|
};
|
||||||
|
|
||||||
const AttachMenu: FC<OwnProps> = ({
|
const AttachMenu: FC<OwnProps> = ({
|
||||||
isButtonVisible, canAttachMedia, canAttachPolls, onFileSelect, onPollCreate,
|
chatId,
|
||||||
|
isButtonVisible,
|
||||||
|
canAttachMedia,
|
||||||
|
canAttachPolls,
|
||||||
|
attachMenuBots,
|
||||||
|
isScheduled,
|
||||||
|
isPrivateChat,
|
||||||
|
onFileSelect,
|
||||||
|
onPollCreate,
|
||||||
|
theme,
|
||||||
}) => {
|
}) => {
|
||||||
const [isAttachMenuOpen, openAttachMenu, closeAttachMenu] = useFlag();
|
const [isAttachMenuOpen, openAttachMenu, closeAttachMenu] = useFlag();
|
||||||
const [handleMouseEnter, handleMouseLeave, markMouseInside] = useMouseInside(isAttachMenuOpen, closeAttachMenu);
|
const [handleMouseEnter, handleMouseLeave, markMouseInside] = useMouseInside(isAttachMenuOpen, closeAttachMenu);
|
||||||
|
|
||||||
|
const [isAttachmentBotMenuOpen, markAttachmentBotMenuOpen, unmarkAttachmentBotMenuOpen] = useFlag();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAttachMenuOpen) {
|
if (isAttachMenuOpen) {
|
||||||
markMouseInside();
|
markMouseInside();
|
||||||
@ -84,7 +104,7 @@ const AttachMenu: FC<OwnProps> = ({
|
|||||||
</ResponsiveHoverButton>
|
</ResponsiveHoverButton>
|
||||||
<Menu
|
<Menu
|
||||||
id="attach-menu-controls"
|
id="attach-menu-controls"
|
||||||
isOpen={isAttachMenuOpen}
|
isOpen={isAttachMenuOpen || isAttachmentBotMenuOpen}
|
||||||
autoClose
|
autoClose
|
||||||
positionX="right"
|
positionX="right"
|
||||||
positionY="bottom"
|
positionY="bottom"
|
||||||
@ -105,15 +125,23 @@ const AttachMenu: FC<OwnProps> = ({
|
|||||||
)}
|
)}
|
||||||
{canAttachMedia && (
|
{canAttachMedia && (
|
||||||
<>
|
<>
|
||||||
<MenuItem icon="photo" onClick={handleQuickSelect}>
|
<MenuItem icon="photo" onClick={handleQuickSelect}>{lang('AttachmentMenu.PhotoOrVideo')}</MenuItem>
|
||||||
{lang('AttachmentMenu.PhotoOrVideo')}
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem icon="document" onClick={handleDocumentSelect}>{lang('AttachDocument')}</MenuItem>
|
<MenuItem icon="document" onClick={handleDocumentSelect}>{lang('AttachDocument')}</MenuItem>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{canAttachPolls && (
|
{canAttachPolls && (
|
||||||
<MenuItem icon="poll" onClick={onPollCreate}>{lang('Poll')}</MenuItem>
|
<MenuItem icon="poll" onClick={onPollCreate}>{lang('Poll')}</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{canAttachMedia && !isScheduled && isPrivateChat && Object.values(attachMenuBots).map((bot) => (
|
||||||
|
<AttachmentMenuBotItem
|
||||||
|
bot={bot}
|
||||||
|
chatId={chatId}
|
||||||
|
theme={theme}
|
||||||
|
onMenuOpened={markAttachmentBotMenuOpen}
|
||||||
|
onMenuClosed={unmarkAttachmentBotMenuOpen}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
.root {
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&.compact {
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
width: 1.75rem;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&.compact {
|
||||||
|
width: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/components/middle/composer/AttachmentMenuBotIcon.tsx
Normal file
49
src/components/middle/composer/AttachmentMenuBotIcon.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import React, { FC, memo, useMemo } from '../../../lib/teact/teact';
|
||||||
|
|
||||||
|
import { ISettings } from '../../../types';
|
||||||
|
import { ApiDocument, ApiMediaFormat } from '../../../api/types';
|
||||||
|
|
||||||
|
import { IS_COMPACT_MENU } from '../../../util/environment';
|
||||||
|
import useMedia from '../../../hooks/useMedia';
|
||||||
|
import { getDocumentMediaHash } from '../../../global/helpers';
|
||||||
|
import buildClassName from '../../../util/buildClassName';
|
||||||
|
|
||||||
|
import styles from './AttachmentMenuBotIcon.module.scss';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
icon: ApiDocument;
|
||||||
|
theme: ISettings['theme'];
|
||||||
|
};
|
||||||
|
|
||||||
|
const ADDITIONAL_STROKE_WIDTH = '0.5px';
|
||||||
|
const DARK_THEME_COLOR = 'rgb(170, 170, 170)';
|
||||||
|
const LIGHT_THEME_COLOR = 'rgb(112, 117, 121)';
|
||||||
|
const COLOR_REPLACE_PATTERN = /#fff/gi;
|
||||||
|
|
||||||
|
const AttachmentMenuBotIcon: FC<OwnProps> = ({
|
||||||
|
icon, theme,
|
||||||
|
}) => {
|
||||||
|
const mediaData = useMedia(getDocumentMediaHash(icon), false, ApiMediaFormat.Text);
|
||||||
|
|
||||||
|
const iconSvg = useMemo(() => {
|
||||||
|
if (!mediaData) return '';
|
||||||
|
const color = theme === 'dark' ? DARK_THEME_COLOR : LIGHT_THEME_COLOR;
|
||||||
|
|
||||||
|
const mediaDataWithReplacedColors = mediaData.replace(COLOR_REPLACE_PATTERN, color);
|
||||||
|
const doc = new DOMParser().parseFromString(mediaDataWithReplacedColors, 'image/svg+xml');
|
||||||
|
doc.querySelectorAll('path').forEach((l) => {
|
||||||
|
l.style.stroke = color;
|
||||||
|
l.style.strokeWidth = ADDITIONAL_STROKE_WIDTH;
|
||||||
|
});
|
||||||
|
|
||||||
|
return `data:image/svg+xml;utf8,${doc.documentElement.outerHTML}`;
|
||||||
|
}, [mediaData, theme]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<i className={buildClassName(styles.root, IS_COMPACT_MENU && styles.compact)}>
|
||||||
|
<img src={iconSvg} alt="" className={buildClassName(styles.image, IS_COMPACT_MENU && styles.compact)} />
|
||||||
|
</i>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(AttachmentMenuBotIcon);
|
||||||
100
src/components/middle/composer/AttachmentMenuBotItem.tsx
Normal file
100
src/components/middle/composer/AttachmentMenuBotItem.tsx
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import React, {
|
||||||
|
FC, memo, useCallback, useMemo, useState,
|
||||||
|
} from '../../../lib/teact/teact';
|
||||||
|
import { getActions } from '../../../global';
|
||||||
|
|
||||||
|
import { IAnchorPosition, ISettings } from '../../../types';
|
||||||
|
import { ApiAttachMenuBot } from '../../../api/types';
|
||||||
|
|
||||||
|
import useFlag from '../../../hooks/useFlag';
|
||||||
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
|
import Portal from '../../ui/Portal';
|
||||||
|
import Menu from '../../ui/Menu';
|
||||||
|
import MenuItem from '../../ui/MenuItem';
|
||||||
|
import AttachmentMenuBotIcon from './AttachmentMenuBotIcon';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
bot: ApiAttachMenuBot;
|
||||||
|
theme: ISettings['theme'];
|
||||||
|
chatId: string;
|
||||||
|
onMenuOpened: VoidFunction;
|
||||||
|
onMenuClosed: VoidFunction;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AttachmentMenuBotItem: FC<OwnProps> = ({
|
||||||
|
bot,
|
||||||
|
theme,
|
||||||
|
chatId,
|
||||||
|
onMenuOpened,
|
||||||
|
onMenuClosed,
|
||||||
|
}) => {
|
||||||
|
const { callAttachMenuBot, toggleBotInAttachMenu } = getActions();
|
||||||
|
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
|
const icon = useMemo(() => {
|
||||||
|
return bot.icons.find(({ name }) => name === 'default_static')?.document;
|
||||||
|
}, [bot.icons]);
|
||||||
|
|
||||||
|
const [isMenuOpen, openMenu, closeMenu] = useFlag();
|
||||||
|
const [menuPosition, setMenuPosition] = useState<IAnchorPosition | undefined>(undefined);
|
||||||
|
|
||||||
|
const handleContextMenu = useCallback((e: React.UIEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const rect = e.currentTarget.getBoundingClientRect();
|
||||||
|
setMenuPosition({ x: rect.right, y: rect.bottom });
|
||||||
|
onMenuOpened();
|
||||||
|
openMenu();
|
||||||
|
}, [onMenuOpened, openMenu]);
|
||||||
|
|
||||||
|
const handleCloseMenu = useCallback(() => {
|
||||||
|
closeMenu();
|
||||||
|
onMenuClosed();
|
||||||
|
}, [closeMenu, onMenuClosed]);
|
||||||
|
|
||||||
|
const handleCloseAnimationEnd = useCallback(() => {
|
||||||
|
setMenuPosition(undefined);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleRemoveBot = useCallback(() => {
|
||||||
|
toggleBotInAttachMenu({
|
||||||
|
botId: bot.id,
|
||||||
|
isEnabled: false,
|
||||||
|
});
|
||||||
|
}, [bot.id, toggleBotInAttachMenu]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
key={bot.id}
|
||||||
|
customIcon={icon && <AttachmentMenuBotIcon icon={icon} theme={theme} />}
|
||||||
|
icon={!icon ? 'bots' : undefined}
|
||||||
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
|
onClick={() => callAttachMenuBot({
|
||||||
|
botId: bot.id,
|
||||||
|
chatId,
|
||||||
|
})}
|
||||||
|
onContextMenu={handleContextMenu}
|
||||||
|
>
|
||||||
|
{bot.shortName}
|
||||||
|
{menuPosition && (
|
||||||
|
<Portal>
|
||||||
|
<Menu
|
||||||
|
isOpen={isMenuOpen}
|
||||||
|
positionX="right"
|
||||||
|
style={`left: ${menuPosition.x}px;top: ${menuPosition.y}px;`}
|
||||||
|
className="bot-attach-context-menu"
|
||||||
|
autoClose
|
||||||
|
onClose={handleCloseMenu}
|
||||||
|
onCloseAnimationEnd={handleCloseAnimationEnd}
|
||||||
|
>
|
||||||
|
<MenuItem icon="stop" destructive onClick={handleRemoveBot}>{lang('WebApp.RemoveBot')}</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</Portal>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(AttachmentMenuBotItem);
|
||||||
61
src/components/middle/composer/BotMenuButton.tsx
Normal file
61
src/components/middle/composer/BotMenuButton.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import React, {
|
||||||
|
FC, memo, useEffect, useRef,
|
||||||
|
} from '../../../lib/teact/teact';
|
||||||
|
|
||||||
|
import buildClassName from '../../../util/buildClassName';
|
||||||
|
|
||||||
|
import Button from '../../ui/Button';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
isOpen?: boolean;
|
||||||
|
onClick: VoidFunction;
|
||||||
|
text: string;
|
||||||
|
isDisabled?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const BotMenuButton: FC<OwnProps> = ({
|
||||||
|
isOpen,
|
||||||
|
onClick,
|
||||||
|
text,
|
||||||
|
isDisabled,
|
||||||
|
}) => {
|
||||||
|
// eslint-disable-next-line no-null/no-null
|
||||||
|
const textRef = useRef<HTMLSpanElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const textEl = textRef.current;
|
||||||
|
if (!textEl) return;
|
||||||
|
|
||||||
|
const width = textEl.scrollWidth + 1; // Make width slightly bigger prevent ellipsis in some cases
|
||||||
|
|
||||||
|
const composerEl = textEl.closest('.Composer') as HTMLElement;
|
||||||
|
composerEl.style.setProperty('--bot-menu-text-width', `${width}px`);
|
||||||
|
}, [isOpen, text]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const textEl = textRef.current;
|
||||||
|
if (!textEl) return undefined;
|
||||||
|
|
||||||
|
const composerEl = textEl.closest('.Composer') as HTMLElement;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
composerEl.style.removeProperty('--bot-menu-text-width');
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={buildClassName('bot-menu', isOpen && 'open')}
|
||||||
|
round
|
||||||
|
color="translucent"
|
||||||
|
disabled={isDisabled}
|
||||||
|
onClick={onClick}
|
||||||
|
ariaLabel="Open bot command keyboard"
|
||||||
|
>
|
||||||
|
<i className={buildClassName('bot-menu-icon', 'icon-webapp', isOpen && 'open')} />
|
||||||
|
<span ref={textRef} className="bot-menu-text">{text}</span>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(BotMenuButton);
|
||||||
@ -277,6 +277,53 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.bot-menu {
|
||||||
|
--icon-width: 1.25rem;
|
||||||
|
--icon-gap: 0.25rem;
|
||||||
|
--padding-sides: 0.5rem;
|
||||||
|
background: var(--color-primary) !important;
|
||||||
|
height: 2rem;
|
||||||
|
margin: 0 0.5rem 0.75rem;
|
||||||
|
color: white !important;
|
||||||
|
text-transform: none;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 0 var(--padding-sides);
|
||||||
|
width: 2rem;
|
||||||
|
max-width: clamp(0px, 12rem, 25vw);
|
||||||
|
/* stylelint-disable-next-line plugin/no-low-performance-animation-properties */
|
||||||
|
transition: 0.25s ease-out width, 0.25s ease-out border-radius;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
width: calc(var(--bot-menu-text-width) + var(--padding-sides) * 2 + var(--icon-gap) + var(--icon-width));
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
margin-bottom: 0.4375rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bot-menu-icon {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
margin-right: var(--icon-gap);
|
||||||
|
transition: 0.25s ease-out transform;
|
||||||
|
transform: translateX(-0.15rem);
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bot-menu-text {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
&.bot-commands {
|
&.bot-commands {
|
||||||
color: var(--color-primary) !important;
|
color: var(--color-primary) !important;
|
||||||
|
|
||||||
|
|||||||
@ -18,11 +18,15 @@ import {
|
|||||||
ApiUser,
|
ApiUser,
|
||||||
MAIN_THREAD_ID,
|
MAIN_THREAD_ID,
|
||||||
ApiBotCommand,
|
ApiBotCommand,
|
||||||
|
ApiBotMenuButton,
|
||||||
} from '../../../api/types';
|
} from '../../../api/types';
|
||||||
import { InlineBotSettings } from '../../../types';
|
import { InlineBotSettings, ISettings } from '../../../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BASE_EMOJI_KEYWORD_LANG, EDITABLE_INPUT_ID, REPLIES_USER_ID, SEND_MESSAGE_ACTION_INTERVAL,
|
BASE_EMOJI_KEYWORD_LANG,
|
||||||
|
EDITABLE_INPUT_ID,
|
||||||
|
REPLIES_USER_ID,
|
||||||
|
SEND_MESSAGE_ACTION_INTERVAL,
|
||||||
EDITABLE_INPUT_CSS_SELECTOR,
|
EDITABLE_INPUT_CSS_SELECTOR,
|
||||||
} from '../../../config';
|
} from '../../../config';
|
||||||
import { IS_VOICE_RECORDING_SUPPORTED, IS_SINGLE_COLUMN_LAYOUT, IS_IOS } from '../../../util/environment';
|
import { IS_VOICE_RECORDING_SUPPORTED, IS_SINGLE_COLUMN_LAYOUT, IS_IOS } from '../../../util/environment';
|
||||||
@ -43,6 +47,7 @@ import {
|
|||||||
selectEditingScheduledDraft,
|
selectEditingScheduledDraft,
|
||||||
selectEditingDraft,
|
selectEditingDraft,
|
||||||
selectRequestedText,
|
selectRequestedText,
|
||||||
|
selectTheme,
|
||||||
} from '../../../global/selectors';
|
} from '../../../global/selectors';
|
||||||
import {
|
import {
|
||||||
getAllowedAttachmentOptions,
|
getAllowedAttachmentOptions,
|
||||||
@ -105,6 +110,7 @@ import PollModal from './PollModal.async';
|
|||||||
import DropArea, { DropAreaState } from './DropArea.async';
|
import DropArea, { DropAreaState } from './DropArea.async';
|
||||||
import WebPagePreview from './WebPagePreview';
|
import WebPagePreview from './WebPagePreview';
|
||||||
import SendAsMenu from './SendAsMenu.async';
|
import SendAsMenu from './SendAsMenu.async';
|
||||||
|
import BotMenuButton from './BotMenuButton';
|
||||||
|
|
||||||
import './Composer.scss';
|
import './Composer.scss';
|
||||||
|
|
||||||
@ -147,12 +153,16 @@ type StateProps =
|
|||||||
isInlineBotLoading: boolean;
|
isInlineBotLoading: boolean;
|
||||||
inlineBots?: Record<string, false | InlineBotSettings>;
|
inlineBots?: Record<string, false | InlineBotSettings>;
|
||||||
botCommands?: ApiBotCommand[] | false;
|
botCommands?: ApiBotCommand[] | false;
|
||||||
|
botMenuButton?: ApiBotMenuButton;
|
||||||
chatBotCommands?: ApiBotCommand[];
|
chatBotCommands?: ApiBotCommand[];
|
||||||
sendAsUser?: ApiUser;
|
sendAsUser?: ApiUser;
|
||||||
sendAsChat?: ApiChat;
|
sendAsChat?: ApiChat;
|
||||||
sendAsId?: string;
|
sendAsId?: string;
|
||||||
editingDraft?: ApiFormattedText;
|
editingDraft?: ApiFormattedText;
|
||||||
requestedText?: string;
|
requestedText?: string;
|
||||||
|
attachMenuBots: GlobalState['attachMenu']['bots'];
|
||||||
|
isPrivateChat?: boolean;
|
||||||
|
theme: ISettings['theme'];
|
||||||
}
|
}
|
||||||
& Pick<GlobalState, 'connectionState'>;
|
& Pick<GlobalState, 'connectionState'>;
|
||||||
|
|
||||||
@ -221,6 +231,10 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
sendAsId,
|
sendAsId,
|
||||||
editingDraft,
|
editingDraft,
|
||||||
requestedText,
|
requestedText,
|
||||||
|
botMenuButton,
|
||||||
|
attachMenuBots,
|
||||||
|
isPrivateChat,
|
||||||
|
theme,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
sendMessage,
|
sendMessage,
|
||||||
@ -238,6 +252,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
loadSendAs,
|
loadSendAs,
|
||||||
loadFullChat,
|
loadFullChat,
|
||||||
resetOpenChatWithText,
|
resetOpenChatWithText,
|
||||||
|
callAttachMenuBot,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
@ -616,6 +631,13 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
resetComposer, stopRecordingVoice, showDialog, slowMode, isAdmin, sendMessage, forwardMessages, lang, htmlRef,
|
resetComposer, stopRecordingVoice, showDialog, slowMode, isAdmin, sendMessage, forwardMessages, lang, htmlRef,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const handleClickBotMenu = useCallback(() => {
|
||||||
|
if (botMenuButton?.type !== 'webApp') return;
|
||||||
|
callAttachMenuBot({
|
||||||
|
botId: chatId, chatId, isFromBotMenu: true, url: botMenuButton.url,
|
||||||
|
});
|
||||||
|
}, [botMenuButton, callAttachMenuBot, chatId]);
|
||||||
|
|
||||||
const handleActivateBotCommandMenu = useCallback(() => {
|
const handleActivateBotCommandMenu = useCallback(() => {
|
||||||
closeSymbolMenu();
|
closeSymbolMenu();
|
||||||
openBotCommandMenu();
|
openBotCommandMenu();
|
||||||
@ -927,6 +949,8 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
: mainButtonState === MainButtonState.Schedule ? handleSendScheduled
|
: mainButtonState === MainButtonState.Schedule ? handleSendScheduled
|
||||||
: handleSend;
|
: handleSend;
|
||||||
|
|
||||||
|
const isBotMenuButtonCommands = botMenuButton && botMenuButton?.type === 'commands';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
{canAttachMedia && isReady && (
|
{canAttachMedia && isReady && (
|
||||||
@ -1016,7 +1040,17 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
disabled={!canAttachEmbedLinks}
|
disabled={!canAttachEmbedLinks}
|
||||||
/>
|
/>
|
||||||
<div className="message-input-wrapper">
|
<div className="message-input-wrapper">
|
||||||
{isChatWithBot && botCommands !== false && !activeVoiceRecording && !editingMessage && (
|
{isChatWithBot && botMenuButton && botMenuButton.type === 'webApp' && !editingMessage
|
||||||
|
&& (
|
||||||
|
<BotMenuButton
|
||||||
|
isOpen={!html && !activeVoiceRecording}
|
||||||
|
onClick={handleClickBotMenu}
|
||||||
|
text={botMenuButton.text}
|
||||||
|
isDisabled={Boolean(activeVoiceRecording)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isChatWithBot && isBotMenuButtonCommands && botCommands !== false && !activeVoiceRecording
|
||||||
|
&& !editingMessage && (
|
||||||
<ResponsiveHoverButton
|
<ResponsiveHoverButton
|
||||||
className={buildClassName('bot-commands', isBotCommandMenuOpen && 'activated')}
|
className={buildClassName('bot-commands', isBotCommandMenuOpen && 'activated')}
|
||||||
round
|
round
|
||||||
@ -1129,11 +1163,16 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
addRecentEmoji={addRecentEmoji}
|
addRecentEmoji={addRecentEmoji}
|
||||||
/>
|
/>
|
||||||
<AttachMenu
|
<AttachMenu
|
||||||
|
chatId={chatId}
|
||||||
isButtonVisible={!activeVoiceRecording && !editingMessage}
|
isButtonVisible={!activeVoiceRecording && !editingMessage}
|
||||||
canAttachMedia={canAttachMedia}
|
canAttachMedia={canAttachMedia}
|
||||||
canAttachPolls={canAttachPolls}
|
canAttachPolls={canAttachPolls}
|
||||||
onFileSelect={handleFileSelect}
|
onFileSelect={handleFileSelect}
|
||||||
onPollCreate={openPollModal}
|
onPollCreate={openPollModal}
|
||||||
|
isScheduled={shouldSchedule}
|
||||||
|
isPrivateChat={isPrivateChat}
|
||||||
|
attachMenuBots={attachMenuBots}
|
||||||
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
{botKeyboardMessageId && (
|
{botKeyboardMessageId && (
|
||||||
<BotKeyboardMenu
|
<BotKeyboardMenu
|
||||||
@ -1215,6 +1254,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const chatBot = chatId !== REPLIES_USER_ID ? selectChatBot(global, chatId) : undefined;
|
const chatBot = chatId !== REPLIES_USER_ID ? selectChatBot(global, chatId) : undefined;
|
||||||
const isChatWithBot = Boolean(chatBot);
|
const isChatWithBot = Boolean(chatBot);
|
||||||
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
|
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
|
||||||
|
const isPrivateChat = Boolean(selectUser(global, chatId));
|
||||||
const messageWithActualBotKeyboard = isChatWithBot && selectNewestMessageWithBotKeyboardButtons(global, chatId);
|
const messageWithActualBotKeyboard = isChatWithBot && selectNewestMessageWithBotKeyboardButtons(global, chatId);
|
||||||
const scheduledIds = selectScheduledIds(global, chatId);
|
const scheduledIds = selectScheduledIds(global, chatId);
|
||||||
const { language, shouldSuggestStickers } = global.settings.byKey;
|
const { language, shouldSuggestStickers } = global.settings.byKey;
|
||||||
@ -1242,6 +1282,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
chat,
|
chat,
|
||||||
isChatWithBot,
|
isChatWithBot,
|
||||||
isChatWithSelf,
|
isChatWithSelf,
|
||||||
|
isPrivateChat,
|
||||||
canScheduleUntilOnline: selectCanScheduleUntilOnline(global, chatId),
|
canScheduleUntilOnline: selectCanScheduleUntilOnline(global, chatId),
|
||||||
isChannel: chat ? isChatChannel(chat) : undefined,
|
isChannel: chat ? isChatChannel(chat) : undefined,
|
||||||
isRightColumnShown: selectIsRightColumnShown(global),
|
isRightColumnShown: selectIsRightColumnShown(global),
|
||||||
@ -1268,13 +1309,16 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
emojiKeywords: emojiKeywords?.keywords,
|
emojiKeywords: emojiKeywords?.keywords,
|
||||||
inlineBots: global.inlineBots.byUsername,
|
inlineBots: global.inlineBots.byUsername,
|
||||||
isInlineBotLoading: global.inlineBots.isLoading,
|
isInlineBotLoading: global.inlineBots.isLoading,
|
||||||
chatBotCommands: chat?.fullInfo?.botCommands,
|
chatBotCommands: chat?.fullInfo && chat.fullInfo.botCommands,
|
||||||
botCommands: chatBot?.fullInfo ? (chatBot.fullInfo.botCommands || false) : undefined,
|
botCommands: chatBot?.fullInfo ? (chatBot.fullInfo.botInfo?.commands || false) : undefined,
|
||||||
|
botMenuButton: chatBot?.fullInfo?.botInfo?.menuButton,
|
||||||
sendAsUser,
|
sendAsUser,
|
||||||
sendAsChat,
|
sendAsChat,
|
||||||
sendAsId,
|
sendAsId,
|
||||||
editingDraft,
|
editingDraft,
|
||||||
requestedText,
|
requestedText,
|
||||||
|
attachMenuBots: global.attachMenu.bots,
|
||||||
|
theme: selectTheme(global),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(Composer));
|
)(Composer));
|
||||||
|
|||||||
@ -96,6 +96,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Remove this monster with context menu refactor
|
||||||
|
.Button.bot-menu:not(.open) ~ &,
|
||||||
.Button.bot-commands ~ &,
|
.Button.bot-commands ~ &,
|
||||||
.Button.send-as-button ~ & {
|
.Button.send-as-button ~ & {
|
||||||
.is-pointer-env & > .backdrop {
|
.is-pointer-env & > .backdrop {
|
||||||
@ -104,6 +106,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Button.bot-menu.open ~ & {
|
||||||
|
.is-pointer-env & > .backdrop {
|
||||||
|
left: calc(var(--bot-menu-text-width, 0) + 3rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bubble {
|
.bubble {
|
||||||
width: calc(var(--symbol-menu-width) + 0.25rem); // Reserve width for scrollbar
|
width: calc(var(--symbol-menu-width) + 0.25rem); // Reserve width for scrollbar
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
.InlineButtons {
|
.InlineButtons {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
max-width: var(--max-width);
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -63,6 +64,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline-button-text {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.row:first-of-type .Button {
|
.row:first-of-type .Button {
|
||||||
margin-top: 0.25rem !important;
|
margin-top: 0.25rem !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,10 +29,11 @@ const InlineButtons: FC<OwnProps> = ({ message, onClick }) => {
|
|||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
onClick={() => onClick({ messageId: message.id, button })}
|
onClick={() => onClick({ messageId: message.id, button })}
|
||||||
>
|
>
|
||||||
{renderText(lang(button.text))}
|
<span className="inline-button-text">{renderText(lang(button.text))}</span>
|
||||||
{['buy', 'receipt'].includes(button.type) && <i className="icon-card" />}
|
{['buy', 'receipt'].includes(button.type) && <i className="icon-card" />}
|
||||||
{button.type === 'url' && !RE_TME_LINK.test(button.url) && <i className="icon-arrow-right" />}
|
{button.type === 'url' && !RE_TME_LINK.test(button.url) && <i className="icon-arrow-right" />}
|
||||||
{button.type === 'switchBotInline' && <i className="icon-share-filled" />}
|
{button.type === 'switchBotInline' && <i className="icon-share-filled" />}
|
||||||
|
{['webView', 'simpleWebView'].includes(button.type) && <i className="icon-webapp" />}
|
||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -53,6 +53,7 @@ import {
|
|||||||
selectIsMessageProtected,
|
selectIsMessageProtected,
|
||||||
selectLocalAnimatedEmojiEffect,
|
selectLocalAnimatedEmojiEffect,
|
||||||
selectDefaultReaction,
|
selectDefaultReaction,
|
||||||
|
selectReplySender,
|
||||||
} from '../../../global/selectors';
|
} from '../../../global/selectors';
|
||||||
import {
|
import {
|
||||||
getMessageContent,
|
getMessageContent,
|
||||||
@ -992,7 +993,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
message, album, withSenderName, withAvatar, threadId, messageListType, isLastInDocumentGroup,
|
message, album, withSenderName, withAvatar, threadId, messageListType, isLastInDocumentGroup,
|
||||||
} = ownProps;
|
} = ownProps;
|
||||||
const {
|
const {
|
||||||
id, chatId, viaBotId, replyToChatId, replyToMessageId, isOutgoing, threadInfo,
|
id, chatId, viaBotId, replyToChatId, replyToMessageId, isOutgoing, threadInfo, forwardInfo,
|
||||||
} = message;
|
} = message;
|
||||||
|
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
@ -1014,7 +1015,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const replyMessage = replyToMessageId && !shouldHideReply
|
const replyMessage = replyToMessageId && !shouldHideReply
|
||||||
? selectChatMessage(global, isRepliesChat && replyToChatId ? replyToChatId : chatId, replyToMessageId)
|
? selectChatMessage(global, isRepliesChat && replyToChatId ? replyToChatId : chatId, replyToMessageId)
|
||||||
: undefined;
|
: undefined;
|
||||||
const replyMessageSender = replyMessage && selectSender(global, replyMessage);
|
const replyMessageSender = replyMessage && selectReplySender(global, replyMessage, Boolean(forwardInfo));
|
||||||
|
|
||||||
const uploadProgress = selectUploadProgress(global, message);
|
const uploadProgress = selectUploadProgress(global, message);
|
||||||
const isFocused = messageListType === 'thread' && (
|
const isFocused = messageListType === 'thread' && (
|
||||||
|
|||||||
@ -37,7 +37,9 @@ export type OwnProps = {
|
|||||||
faded?: boolean;
|
faded?: boolean;
|
||||||
tabIndex?: number;
|
tabIndex?: number;
|
||||||
isRtl?: boolean;
|
isRtl?: boolean;
|
||||||
withClickPropagation?: boolean;
|
noPreventDefault?: boolean;
|
||||||
|
shouldStopPropagation?: boolean;
|
||||||
|
style?: string;
|
||||||
onClick?: (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
onClick?: (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
||||||
onContextMenu?: (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
onContextMenu?: (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
||||||
onMouseDown?: (e: ReactMouseEvent<HTMLButtonElement>) => void;
|
onMouseDown?: (e: ReactMouseEvent<HTMLButtonElement>) => void;
|
||||||
@ -79,7 +81,9 @@ const Button: FC<OwnProps> = ({
|
|||||||
faded,
|
faded,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
isRtl,
|
isRtl,
|
||||||
withClickPropagation,
|
noPreventDefault,
|
||||||
|
shouldStopPropagation,
|
||||||
|
style,
|
||||||
}) => {
|
}) => {
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
let elementRef = useRef<HTMLButtonElement | HTMLAnchorElement>(null);
|
let elementRef = useRef<HTMLButtonElement | HTMLAnchorElement>(null);
|
||||||
@ -111,18 +115,21 @@ const Button: FC<OwnProps> = ({
|
|||||||
onClick(e);
|
onClick(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldStopPropagation) e.stopPropagation();
|
||||||
|
|
||||||
setIsClicked(true);
|
setIsClicked(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsClicked(false);
|
setIsClicked(false);
|
||||||
}, CLICKED_TIMEOUT);
|
}, CLICKED_TIMEOUT);
|
||||||
}, [disabled, onClick]);
|
}, [disabled, onClick, shouldStopPropagation]);
|
||||||
|
|
||||||
const handleMouseDown = useCallback((e: ReactMouseEvent<HTMLButtonElement>) => {
|
const handleMouseDown = useCallback((e: ReactMouseEvent<HTMLButtonElement>) => {
|
||||||
if (!withClickPropagation) e.preventDefault();
|
if (!noPreventDefault) e.preventDefault();
|
||||||
|
|
||||||
if (!disabled && onMouseDown) {
|
if (!disabled && onMouseDown) {
|
||||||
onMouseDown(e);
|
onMouseDown(e);
|
||||||
}
|
}
|
||||||
}, [onMouseDown, disabled, withClickPropagation]);
|
}, [disabled, noPreventDefault, onMouseDown]);
|
||||||
|
|
||||||
if (href) {
|
if (href) {
|
||||||
return (
|
return (
|
||||||
@ -137,6 +144,7 @@ const Button: FC<OwnProps> = ({
|
|||||||
dir={isRtl ? 'rtl' : undefined}
|
dir={isRtl ? 'rtl' : undefined}
|
||||||
aria-label={ariaLabel}
|
aria-label={ariaLabel}
|
||||||
aria-controls={ariaControls}
|
aria-controls={ariaControls}
|
||||||
|
style={style}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
{!disabled && ripple && (
|
{!disabled && ripple && (
|
||||||
@ -164,7 +172,7 @@ const Button: FC<OwnProps> = ({
|
|||||||
title={ariaLabel}
|
title={ariaLabel}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
dir={isRtl ? 'rtl' : undefined}
|
dir={isRtl ? 'rtl' : undefined}
|
||||||
style={backgroundImage ? `background-image: url(${backgroundImage})` : undefined}
|
style={backgroundImage ? `background-image: url(${backgroundImage})` : style}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -67,7 +67,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body.has-open-dialog &:not(.CustomSendMenu) .bubble {
|
body.has-open-dialog &:not(.CustomSendMenu):not(.web-app-more-menu) .bubble {
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,9 +10,11 @@ type OnClickHandler = (e: React.SyntheticEvent<HTMLDivElement | HTMLAnchorElemen
|
|||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
customIcon?: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
onClick?: OnClickHandler;
|
onClick?: OnClickHandler;
|
||||||
|
onContextMenu?: (e: React.UIEvent) => void;
|
||||||
href?: string;
|
href?: string;
|
||||||
download?: string;
|
download?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
@ -23,6 +25,7 @@ type OwnProps = {
|
|||||||
const MenuItem: FC<OwnProps> = (props) => {
|
const MenuItem: FC<OwnProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
icon,
|
icon,
|
||||||
|
customIcon,
|
||||||
className,
|
className,
|
||||||
children,
|
children,
|
||||||
onClick,
|
onClick,
|
||||||
@ -31,6 +34,7 @@ const MenuItem: FC<OwnProps> = (props) => {
|
|||||||
disabled,
|
disabled,
|
||||||
destructive,
|
destructive,
|
||||||
ariaLabel,
|
ariaLabel,
|
||||||
|
onContextMenu,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
@ -70,9 +74,10 @@ const MenuItem: FC<OwnProps> = (props) => {
|
|||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
{icon && (
|
{!customIcon && icon && (
|
||||||
<i className={`icon-${icon}`} data-char={icon.startsWith('char-') ? icon.replace('char-', '') : undefined} />
|
<i className={`icon-${icon}`} data-char={icon.startsWith('char-') ? icon.replace('char-', '') : undefined} />
|
||||||
)}
|
)}
|
||||||
|
{customIcon}
|
||||||
{children}
|
{children}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -103,6 +108,7 @@ const MenuItem: FC<OwnProps> = (props) => {
|
|||||||
className={fullClassName}
|
className={fullClassName}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
|
onContextMenu={onContextMenu}
|
||||||
aria-label={ariaLabel}
|
aria-label={ariaLabel}
|
||||||
title={ariaLabel}
|
title={ariaLabel}
|
||||||
dir={lang.isRtl ? 'rtl' : undefined}
|
dir={lang.isRtl ? 'rtl' : undefined}
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export const MEDIA_PROGRESSIVE_CACHE_DISABLED = false;
|
|||||||
export const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive';
|
export const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive';
|
||||||
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
|
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
|
||||||
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
|
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
|
||||||
export const LANG_CACHE_NAME = 'tt-lang-packs-v8';
|
export const LANG_CACHE_NAME = 'tt-lang-packs-v9';
|
||||||
export const ASSET_CACHE_NAME = 'tt-assets';
|
export const ASSET_CACHE_NAME = 'tt-assets';
|
||||||
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
||||||
|
|
||||||
|
|||||||
@ -11,13 +11,14 @@ import {
|
|||||||
import { callApi } from '../../../api/gramjs';
|
import { callApi } from '../../../api/gramjs';
|
||||||
import {
|
import {
|
||||||
selectChat, selectChatBot, selectChatMessage, selectCurrentChat, selectCurrentMessageList,
|
selectChat, selectChatBot, selectChatMessage, selectCurrentChat, selectCurrentMessageList,
|
||||||
selectReplyingToId, selectSendAs, selectUser,
|
selectIsTrustedBot, selectReplyingToId, selectSendAs, selectUser,
|
||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
import { addChats, addUsers, removeBlockedContact } from '../../reducers';
|
import { addChats, addUsers, removeBlockedContact } from '../../reducers';
|
||||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||||
import { debounce } from '../../../util/schedulers';
|
import { debounce } from '../../../util/schedulers';
|
||||||
import { replaceInlineBotSettings, replaceInlineBotsIsLoading } from '../../reducers/bots';
|
import { replaceInlineBotSettings, replaceInlineBotsIsLoading } from '../../reducers/bots';
|
||||||
import { getServerTime } from '../../../util/serverTime';
|
import { getServerTime } from '../../../util/serverTime';
|
||||||
|
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
||||||
import PopupManager from '../../../util/PopupManager';
|
import PopupManager from '../../../util/PopupManager';
|
||||||
|
|
||||||
const GAMEE_URL = 'https://prizes.gamee.com/';
|
const GAMEE_URL = 'https://prizes.gamee.com/';
|
||||||
@ -107,6 +108,51 @@ addActionHandler('clickBotInlineButton', (global, actions, payload) => {
|
|||||||
actions.openChatWithInfo({ id: userId });
|
actions.openChatWithInfo({ id: userId });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'simpleWebView': {
|
||||||
|
const { url } = button;
|
||||||
|
const { chatId } = selectCurrentMessageList(global) || {};
|
||||||
|
if (!chatId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const bot = selectChatBot(global, chatId);
|
||||||
|
if (!bot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const theme = extractCurrentThemeParams();
|
||||||
|
actions.requestSimpleWebView({
|
||||||
|
url, bot, theme, buttonText: button.text,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'webView': {
|
||||||
|
const { url } = button;
|
||||||
|
const chat = selectCurrentChat(global);
|
||||||
|
if (!chat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const message = selectChatMessage(global, chat.id, messageId);
|
||||||
|
if (!message) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!message.viaBotId && !message.senderId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const bot = selectChatBot(global, message.viaBotId! || message.senderId!);
|
||||||
|
if (!bot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const theme = extractCurrentThemeParams();
|
||||||
|
actions.requestWebView({
|
||||||
|
url,
|
||||||
|
bot,
|
||||||
|
peer: chat,
|
||||||
|
theme,
|
||||||
|
buttonText: button.text,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -322,6 +368,252 @@ addActionHandler('startBot', async (global, actions, payload) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('requestSimpleWebView', async (global, actions, payload) => {
|
||||||
|
const {
|
||||||
|
url, bot, theme, buttonText,
|
||||||
|
} = payload;
|
||||||
|
|
||||||
|
if (!selectIsTrustedBot(global, bot)) {
|
||||||
|
setGlobal({
|
||||||
|
...global,
|
||||||
|
botTrustRequest: {
|
||||||
|
bot,
|
||||||
|
type: 'webApp',
|
||||||
|
onConfirm: {
|
||||||
|
action: 'requestSimpleWebView',
|
||||||
|
payload,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const webViewUrl = await callApi('requestSimpleWebView', { url, bot, theme });
|
||||||
|
if (!webViewUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
global = getGlobal();
|
||||||
|
setGlobal({
|
||||||
|
...global,
|
||||||
|
webApp: {
|
||||||
|
url: webViewUrl,
|
||||||
|
bot,
|
||||||
|
buttonText,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('requestWebView', async (global, actions, payload) => {
|
||||||
|
const {
|
||||||
|
url, bot, peer, theme, isSilent, buttonText, isFromBotMenu, startParam,
|
||||||
|
} = payload;
|
||||||
|
|
||||||
|
if (!selectIsTrustedBot(global, bot)) {
|
||||||
|
setGlobal({
|
||||||
|
...global,
|
||||||
|
botTrustRequest: {
|
||||||
|
bot,
|
||||||
|
type: 'webApp',
|
||||||
|
onConfirm: {
|
||||||
|
action: 'requestWebView',
|
||||||
|
payload,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentMessageList = selectCurrentMessageList(global);
|
||||||
|
if (!currentMessageList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { chatId, threadId } = currentMessageList;
|
||||||
|
const reply = chatId && selectReplyingToId(global, chatId, threadId);
|
||||||
|
const result = await callApi('requestWebView', {
|
||||||
|
url,
|
||||||
|
bot,
|
||||||
|
peer,
|
||||||
|
theme,
|
||||||
|
isSilent,
|
||||||
|
replyToMessageId: reply || undefined,
|
||||||
|
isFromBotMenu,
|
||||||
|
startParam,
|
||||||
|
});
|
||||||
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { url: webViewUrl, queryId } = result;
|
||||||
|
|
||||||
|
global = getGlobal();
|
||||||
|
setGlobal({
|
||||||
|
...global,
|
||||||
|
webApp: {
|
||||||
|
url: webViewUrl,
|
||||||
|
bot,
|
||||||
|
queryId,
|
||||||
|
buttonText,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('prolongWebView', (global, actions, payload) => {
|
||||||
|
const {
|
||||||
|
bot, peer, isSilent, replyToMessageId, queryId,
|
||||||
|
} = payload;
|
||||||
|
|
||||||
|
const result = callApi('prolongWebView', {
|
||||||
|
bot,
|
||||||
|
peer,
|
||||||
|
isSilent,
|
||||||
|
replyToMessageId,
|
||||||
|
queryId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
actions.closeWebApp();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('sendWebViewData', (global, actions, payload) => {
|
||||||
|
const {
|
||||||
|
bot, data, buttonText,
|
||||||
|
} = payload;
|
||||||
|
|
||||||
|
callApi('sendWebViewData', {
|
||||||
|
bot,
|
||||||
|
data,
|
||||||
|
buttonText,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('closeWebApp', (global) => {
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
webApp: undefined,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('cancelBotTrustRequest', (global) => {
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
botTrustRequest: undefined,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('markBotTrusted', (global, actions, payload) => {
|
||||||
|
const { botId } = payload;
|
||||||
|
const { trustedBotIds } = global;
|
||||||
|
|
||||||
|
const newTrustedBotIds = new Set(trustedBotIds);
|
||||||
|
newTrustedBotIds.add(botId);
|
||||||
|
setGlobal({
|
||||||
|
...global,
|
||||||
|
botTrustRequest: undefined,
|
||||||
|
trustedBotIds: Array.from(newTrustedBotIds),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (global.botTrustRequest?.onConfirm) {
|
||||||
|
const { action, payload: callbackPayload } = global.botTrustRequest.onConfirm;
|
||||||
|
actions[action](callbackPayload);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('loadAttachMenuBots', async (global, actions, payload) => {
|
||||||
|
const { hash } = payload || {};
|
||||||
|
await loadAttachMenuBots(hash);
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('toggleBotInAttachMenu', async (global, actions, payload) => {
|
||||||
|
const { botId, isEnabled } = payload;
|
||||||
|
|
||||||
|
const bot = selectUser(global, botId);
|
||||||
|
|
||||||
|
if (!bot) return;
|
||||||
|
|
||||||
|
await toggleBotInAttachMenu(bot, isEnabled);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function toggleBotInAttachMenu(bot: ApiUser, isEnabled: boolean) {
|
||||||
|
await callApi('toggleBotInAttachMenu', { bot, isEnabled });
|
||||||
|
await loadAttachMenuBots();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadAttachMenuBots(hash?: string) {
|
||||||
|
const result = await callApi('loadAttachMenuBots', { hash });
|
||||||
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const global = getGlobal();
|
||||||
|
setGlobal({
|
||||||
|
...global,
|
||||||
|
attachMenu: {
|
||||||
|
hash: result.hash,
|
||||||
|
bots: result.bots,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addActionHandler('callAttachMenuBot', (global, actions, payload) => {
|
||||||
|
const {
|
||||||
|
chatId, botId, isFromBotMenu, url, startParam,
|
||||||
|
} = payload;
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
const bot = selectChatBot(global, botId);
|
||||||
|
if (!chat || !bot) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const { attachMenu: { bots } } = global;
|
||||||
|
if (!isFromBotMenu && !bots[botId]) {
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
botAttachRequest: {
|
||||||
|
bot,
|
||||||
|
chatId,
|
||||||
|
startParam,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const theme = extractCurrentThemeParams();
|
||||||
|
actions.requestWebView({
|
||||||
|
url,
|
||||||
|
peer: chat,
|
||||||
|
bot,
|
||||||
|
theme,
|
||||||
|
buttonText: '',
|
||||||
|
isFromBotMenu,
|
||||||
|
startParam,
|
||||||
|
});
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('confirmBotAttachRequest', async (global, actions) => {
|
||||||
|
const { botAttachRequest } = global;
|
||||||
|
if (!botAttachRequest) return;
|
||||||
|
|
||||||
|
const { bot, chatId, startParam } = botAttachRequest;
|
||||||
|
|
||||||
|
setGlobal({
|
||||||
|
...global,
|
||||||
|
botAttachRequest: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
await toggleBotInAttachMenu(bot, true);
|
||||||
|
|
||||||
|
actions.callAttachMenuBot({ chatId, botId: bot.id, startParam });
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('closeBotAttachRequestModal', (global) => {
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
botAttachRequest: undefined,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
async function searchInlineBot({
|
async function searchInlineBot({
|
||||||
username,
|
username,
|
||||||
inlineBotData,
|
inlineBotData,
|
||||||
|
|||||||
@ -34,7 +34,7 @@ import {
|
|||||||
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
||||||
import { debounce, pause, throttle } from '../../../util/schedulers';
|
import { debounce, pause, throttle } from '../../../util/schedulers';
|
||||||
import {
|
import {
|
||||||
isChatSummaryOnly, isChatArchived, isChatBasicGroup,
|
isChatSummaryOnly, isChatArchived, isChatBasicGroup, isUserBot,
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
import { processDeepLink } from '../../../util/deeplink';
|
import { processDeepLink } from '../../../util/deeplink';
|
||||||
import { updateGroupCall } from '../../reducers/calls';
|
import { updateGroupCall } from '../../reducers/calls';
|
||||||
@ -509,7 +509,7 @@ addActionHandler('openChatByInvite', async (global, actions, payload) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('openChatByPhoneNumber', async (global, actions, payload) => {
|
addActionHandler('openChatByPhoneNumber', async (global, actions, payload) => {
|
||||||
const { phoneNumber } = payload!;
|
const { phoneNumber, startAttach, attach } = payload!;
|
||||||
|
|
||||||
// Open temporary empty chat to make the click response feel faster
|
// Open temporary empty chat to make the click response feel faster
|
||||||
actions.openChat({ id: TMP_CHAT_ID });
|
actions.openChat({ id: TMP_CHAT_ID });
|
||||||
@ -524,6 +524,10 @@ addActionHandler('openChatByPhoneNumber', async (global, actions, payload) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
actions.openChat({ id: chat.id });
|
actions.openChat({ id: chat.id });
|
||||||
|
|
||||||
|
if (attach) {
|
||||||
|
openAttachMenuFromLink(actions, chat.id, attach, startAttach);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('openTelegramLink', (global, actions, payload) => {
|
addActionHandler('openTelegramLink', (global, actions, payload) => {
|
||||||
@ -542,8 +546,14 @@ addActionHandler('openTelegramLink', (global, actions, payload) => {
|
|||||||
hash = part2;
|
hash = part2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startAttach = params.hasOwnProperty('startattach') && !params.startattach ? true : params.startattach;
|
||||||
|
|
||||||
if (part1.match(/^\+([0-9]+)(\?|$)/)) {
|
if (part1.match(/^\+([0-9]+)(\?|$)/)) {
|
||||||
actions.openChatByPhoneNumber({ phoneNumber: part1.substr(1, part1.length - 1) });
|
actions.openChatByPhoneNumber({
|
||||||
|
phoneNumber: part1.substr(1, part1.length - 1),
|
||||||
|
startAttach,
|
||||||
|
attach: params.attach,
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,6 +600,8 @@ addActionHandler('openTelegramLink', (global, actions, payload) => {
|
|||||||
messageId: messageId || Number(chatOrChannelPostId),
|
messageId: messageId || Number(chatOrChannelPostId),
|
||||||
commentId,
|
commentId,
|
||||||
startParam: params.start,
|
startParam: params.start,
|
||||||
|
startAttach,
|
||||||
|
attach: params.attach,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -606,7 +618,7 @@ addActionHandler('acceptInviteConfirmation', async (global, actions, payload) =>
|
|||||||
|
|
||||||
addActionHandler('openChatByUsername', async (global, actions, payload) => {
|
addActionHandler('openChatByUsername', async (global, actions, payload) => {
|
||||||
const {
|
const {
|
||||||
username, messageId, commentId, startParam,
|
username, messageId, commentId, startParam, startAttach, attach,
|
||||||
} = payload!;
|
} = payload!;
|
||||||
|
|
||||||
const chat = selectCurrentChat(global);
|
const chat = selectCurrentChat(global);
|
||||||
@ -616,7 +628,7 @@ addActionHandler('openChatByUsername', async (global, actions, payload) => {
|
|||||||
actions.focusMessage({ chatId: chat.id, messageId });
|
actions.focusMessage({ chatId: chat.id, messageId });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await openChatByUsername(actions, username, messageId, startParam);
|
await openChatByUsername(actions, username, messageId, startParam, startAttach, attach);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1330,7 +1342,35 @@ async function openChatByUsername(
|
|||||||
username: string,
|
username: string,
|
||||||
channelPostId?: number,
|
channelPostId?: number,
|
||||||
startParam?: string,
|
startParam?: string,
|
||||||
|
startAttach?: string | boolean,
|
||||||
|
attach?: string,
|
||||||
) {
|
) {
|
||||||
|
// Attach in the current chat
|
||||||
|
if (startAttach && !attach) {
|
||||||
|
const chat = await fetchChatByUsername(username);
|
||||||
|
|
||||||
|
if (!chat) return;
|
||||||
|
const global = getGlobal();
|
||||||
|
const user = selectUser(global, chat.id);
|
||||||
|
if (!user) return;
|
||||||
|
const isBot = isUserBot(user);
|
||||||
|
if (!isBot || !user.isAttachMenuBot) {
|
||||||
|
actions.showNotification({ message: langProvider.getTranslation('WebApp.AddToAttachmentUnavailableError') });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentChat = selectCurrentChat(global);
|
||||||
|
|
||||||
|
if (!currentChat) return;
|
||||||
|
|
||||||
|
actions.callAttachMenuBot({
|
||||||
|
botId: user.id,
|
||||||
|
chatId: currentChat.id,
|
||||||
|
...(typeof startAttach === 'string' && { startParam: startAttach }),
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Open temporary empty chat to make the click response feel faster
|
// Open temporary empty chat to make the click response feel faster
|
||||||
actions.openChat({ id: TMP_CHAT_ID });
|
actions.openChat({ id: TMP_CHAT_ID });
|
||||||
|
|
||||||
@ -1350,6 +1390,29 @@ async function openChatByUsername(
|
|||||||
if (startParam) {
|
if (startParam) {
|
||||||
actions.startBot({ botId: chat.id, param: startParam });
|
actions.startBot({ botId: chat.id, param: startParam });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attach) {
|
||||||
|
openAttachMenuFromLink(actions, chat.id, attach, startAttach);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openAttachMenuFromLink(
|
||||||
|
actions: GlobalActions,
|
||||||
|
chatId: string, attach: string, startAttach?: string | boolean,
|
||||||
|
) {
|
||||||
|
const botChat = await fetchChatByUsername(attach);
|
||||||
|
if (!botChat) return;
|
||||||
|
const botUser = selectUser(getGlobal(), botChat.id);
|
||||||
|
if (!botUser || !botUser.isAttachMenuBot) {
|
||||||
|
actions.showNotification({ message: langProvider.getTranslation('WebApp.AddToAttachmentUnavailableError') });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.callAttachMenuBot({
|
||||||
|
botId: botUser.id,
|
||||||
|
chatId,
|
||||||
|
...(typeof startAttach === 'string' && { startParam: startAttach }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openCommentsByUsername(
|
async function openCommentsByUsername(
|
||||||
|
|||||||
@ -37,6 +37,13 @@ addActionHandler('apiUpdate', (global, actions, update) => {
|
|||||||
global = setPaymentStep(global, PaymentStep.ConfirmPayment);
|
global = setPaymentStep(global, PaymentStep.ConfirmPayment);
|
||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'updateWebViewResultSent':
|
||||||
|
if (global.webApp?.queryId === update.queryId) {
|
||||||
|
actions.setReplyingToId({ messageId: undefined });
|
||||||
|
actions.closeWebApp();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { ApiUserStatus } from '../../../api/types';
|
|||||||
|
|
||||||
import { deleteContact, replaceUserStatuses, updateUser } from '../../reducers';
|
import { deleteContact, replaceUserStatuses, updateUser } from '../../reducers';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
|
import { selectUser } from '../../selectors';
|
||||||
|
|
||||||
const STATUS_UPDATE_THROTTLE = 3000;
|
const STATUS_UPDATE_THROTTLE = 3000;
|
||||||
|
|
||||||
@ -57,6 +58,25 @@ addActionHandler('apiUpdate', (global, actions, update) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'updateBotMenuButton': {
|
||||||
|
const { botId, button } = update;
|
||||||
|
|
||||||
|
const targetUser = selectUser(global, botId);
|
||||||
|
if (!targetUser?.fullInfo?.botInfo) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateUser(global, botId, {
|
||||||
|
fullInfo: {
|
||||||
|
...targetUser.fullInfo,
|
||||||
|
botInfo: {
|
||||||
|
...targetUser.fullInfo.botInfo,
|
||||||
|
menuButton: button,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
import { addActionHandler } from '../../index';
|
import { addActionHandler, setGlobal } from '../../index';
|
||||||
|
|
||||||
import { ApiError } from '../../../api/types';
|
import { ApiError } from '../../../api/types';
|
||||||
|
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT, IS_TABLET_COLUMN_LAYOUT } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, IS_TABLET_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import getReadableErrorText from '../../../util/getReadableErrorText';
|
import getReadableErrorText from '../../../util/getReadableErrorText';
|
||||||
import { selectCurrentMessageList } from '../../selectors';
|
import {
|
||||||
|
selectChatBot, selectChatMessage, selectCurrentMessageList, selectIsTrustedBot,
|
||||||
|
} from '../../selectors';
|
||||||
import generateIdFor from '../../../util/generateIdFor';
|
import generateIdFor from '../../../util/generateIdFor';
|
||||||
|
|
||||||
const MAX_STORED_EMOJIS = 18; // Represents two rows of recent emojis
|
const MAX_STORED_EMOJIS = 18; // Represents two rows of recent emojis
|
||||||
@ -264,14 +266,37 @@ addActionHandler('closeHistoryCalendar', (global) => {
|
|||||||
|
|
||||||
addActionHandler('openGame', (global, actions, payload) => {
|
addActionHandler('openGame', (global, actions, payload) => {
|
||||||
const { url, chatId, messageId } = payload;
|
const { url, chatId, messageId } = payload;
|
||||||
return {
|
|
||||||
|
const message = selectChatMessage(global, chatId, messageId);
|
||||||
|
if (!message) return;
|
||||||
|
|
||||||
|
const botId = message.viaBotId || message.senderId;
|
||||||
|
const bot = botId && selectChatBot(global, botId);
|
||||||
|
if (!bot) return;
|
||||||
|
|
||||||
|
if (!selectIsTrustedBot(global, bot)) {
|
||||||
|
setGlobal({
|
||||||
|
...global,
|
||||||
|
botTrustRequest: {
|
||||||
|
bot,
|
||||||
|
type: 'game',
|
||||||
|
onConfirm: {
|
||||||
|
action: 'openGame',
|
||||||
|
payload,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setGlobal({
|
||||||
...global,
|
...global,
|
||||||
openedGame: {
|
openedGame: {
|
||||||
url,
|
url,
|
||||||
chatId,
|
chatId,
|
||||||
messageId,
|
messageId,
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('closeGame', (global) => {
|
addActionHandler('closeGame', (global) => {
|
||||||
|
|||||||
@ -225,6 +225,16 @@ function migrateCache(cached: GlobalState, initialState: GlobalState) {
|
|||||||
isOpen: false,
|
isOpen: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cached.attachMenu) {
|
||||||
|
cached.attachMenu = {
|
||||||
|
bots: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cached.trustedBotIds) {
|
||||||
|
cached.trustedBotIds = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCache() {
|
function updateCache() {
|
||||||
@ -277,6 +287,7 @@ function updateCache() {
|
|||||||
groupCalls: reduceGroupCalls(global),
|
groupCalls: reduceGroupCalls(global),
|
||||||
availableReactions: reduceAvailableReactions(global),
|
availableReactions: reduceAvailableReactions(global),
|
||||||
isCallPanelVisible: undefined,
|
isCallPanelVisible: undefined,
|
||||||
|
trustedBotIds: global.trustedBotIds,
|
||||||
};
|
};
|
||||||
|
|
||||||
const json = JSON.stringify(reducedGlobal);
|
const json = JSON.stringify(reducedGlobal);
|
||||||
|
|||||||
@ -1,5 +1,14 @@
|
|||||||
import {
|
import {
|
||||||
ApiAudio, ApiMediaFormat, ApiMessage, ApiMessageSearchType, ApiPhoto, ApiVideo, ApiDimensions, ApiLocation, ApiGame,
|
ApiAudio,
|
||||||
|
ApiMediaFormat,
|
||||||
|
ApiMessage,
|
||||||
|
ApiMessageSearchType,
|
||||||
|
ApiPhoto,
|
||||||
|
ApiVideo,
|
||||||
|
ApiDimensions,
|
||||||
|
ApiLocation,
|
||||||
|
ApiGame,
|
||||||
|
ApiDocument,
|
||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
|
|
||||||
import { IS_OPUS_SUPPORTED, IS_PROGRESSIVE_SUPPORTED, IS_SAFARI } from '../../util/environment';
|
import { IS_OPUS_SUPPORTED, IS_PROGRESSIVE_SUPPORTED, IS_SAFARI } from '../../util/environment';
|
||||||
@ -127,6 +136,10 @@ export function getMessageMediaThumbDataUri(message: ApiMessage) {
|
|||||||
return getMessageMediaThumbnail(message)?.dataUri;
|
return getMessageMediaThumbnail(message)?.dataUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDocumentMediaHash(document: ApiDocument) {
|
||||||
|
return `document${document.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
export function buildStaticMapHash(
|
export function buildStaticMapHash(
|
||||||
geo: ApiLocation['geo'],
|
geo: ApiLocation['geo'],
|
||||||
width: number,
|
width: number,
|
||||||
|
|||||||
@ -227,3 +227,9 @@ export function isGeoLiveExpired(message: ApiMessage, timestamp = Date.now() / 1
|
|||||||
if (location?.type !== 'geoLive') return false;
|
if (location?.type !== 'geoLive') return false;
|
||||||
return (timestamp - (message.date || 0) >= location.period);
|
return (timestamp - (message.date || 0) >= location.period);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getMessageSingleInlineButton(message: ApiMessage) {
|
||||||
|
return message.inlineButtons?.length === 1
|
||||||
|
&& message.inlineButtons[0].length === 1
|
||||||
|
&& message.inlineButtons[0][0];
|
||||||
|
}
|
||||||
|
|||||||
@ -206,4 +206,10 @@ export const INITIAL_STATE: GlobalState = {
|
|||||||
pollModal: {
|
pollModal: {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
trustedBotIds: [],
|
||||||
|
|
||||||
|
attachMenu: {
|
||||||
|
bots: {},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ApiChat, MAIN_THREAD_ID } from '../../api/types';
|
import { ApiChat, ApiUser, MAIN_THREAD_ID } from '../../api/types';
|
||||||
import { GlobalState } from '../types';
|
import { GlobalState } from '../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -68,6 +68,10 @@ export function selectChatBot(global: GlobalState, chatId: string) {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function selectIsTrustedBot(global: GlobalState, bot: ApiUser) {
|
||||||
|
return bot.isVerified || global.trustedBotIds.includes(bot.id);
|
||||||
|
}
|
||||||
|
|
||||||
export function selectIsChatBotNotStarted(global: GlobalState, chatId: string) {
|
export function selectIsChatBotNotStarted(global: GlobalState, chatId: string) {
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
const bot = selectChatBot(global, chatId);
|
const bot = selectChatBot(global, chatId);
|
||||||
|
|||||||
@ -335,6 +335,23 @@ export function selectSender(global: GlobalState, message: ApiMessage): ApiUser
|
|||||||
return isUserId(senderId) ? selectUser(global, senderId) : selectChat(global, senderId);
|
return isUserId(senderId) ? selectUser(global, senderId) : selectChat(global, senderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function selectReplySender(global: GlobalState, message: ApiMessage, isForwarded = false) {
|
||||||
|
if (isForwarded) {
|
||||||
|
const { senderUserId, hiddenUserName } = message.forwardInfo || {};
|
||||||
|
if (senderUserId) {
|
||||||
|
return isUserId(senderUserId) ? selectUser(global, senderUserId) : selectChat(global, senderUserId);
|
||||||
|
}
|
||||||
|
if (hiddenUserName) return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { senderId } = message;
|
||||||
|
if (!senderId) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isUserId(senderId) ? selectUser(global, senderId) : selectChat(global, senderId);
|
||||||
|
}
|
||||||
|
|
||||||
export function selectForwardedSender(global: GlobalState, message: ApiMessage): ApiUser | ApiChat | undefined {
|
export function selectForwardedSender(global: GlobalState, message: ApiMessage): ApiUser | ApiChat | undefined {
|
||||||
const { forwardInfo } = message;
|
const { forwardInfo } = message;
|
||||||
if (!forwardInfo) {
|
if (!forwardInfo) {
|
||||||
|
|||||||
@ -33,6 +33,8 @@ import {
|
|||||||
ApiReportReason,
|
ApiReportReason,
|
||||||
ApiPhoto,
|
ApiPhoto,
|
||||||
ApiKeyboardButton,
|
ApiKeyboardButton,
|
||||||
|
ApiThemeParameters,
|
||||||
|
ApiAttachMenuBot,
|
||||||
ApiPhoneCall,
|
ApiPhoneCall,
|
||||||
} from '../api/types';
|
} from '../api/types';
|
||||||
import {
|
import {
|
||||||
@ -543,6 +545,33 @@ export type GlobalState = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
isQuiz?: boolean;
|
isQuiz?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
webApp?: {
|
||||||
|
url: string;
|
||||||
|
bot: ApiUser;
|
||||||
|
buttonText: string;
|
||||||
|
queryId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
trustedBotIds: string[];
|
||||||
|
botTrustRequest?: {
|
||||||
|
bot: ApiUser;
|
||||||
|
type: 'game' | 'webApp';
|
||||||
|
onConfirm?: {
|
||||||
|
action: keyof GlobalActions;
|
||||||
|
payload: any; // TODO add TS support
|
||||||
|
};
|
||||||
|
};
|
||||||
|
botAttachRequest?: {
|
||||||
|
bot: ApiUser;
|
||||||
|
chatId: string;
|
||||||
|
startParam?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
attachMenu: {
|
||||||
|
hash?: string;
|
||||||
|
bots: Record<string, ApiAttachMenuBot>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CallSound = (
|
export type CallSound = (
|
||||||
@ -682,7 +711,6 @@ export interface ActionPayloads {
|
|||||||
|
|
||||||
resetSwitchBotInline: {};
|
resetSwitchBotInline: {};
|
||||||
|
|
||||||
// Misc
|
|
||||||
openGame: {
|
openGame: {
|
||||||
url: string;
|
url: string;
|
||||||
chatId: string;
|
chatId: string;
|
||||||
@ -690,6 +718,64 @@ export interface ActionPayloads {
|
|||||||
};
|
};
|
||||||
closeGame: {};
|
closeGame: {};
|
||||||
|
|
||||||
|
requestWebView: {
|
||||||
|
url?: string;
|
||||||
|
bot: ApiUser;
|
||||||
|
peer: ApiChat | ApiUser;
|
||||||
|
theme?: ApiThemeParameters;
|
||||||
|
isSilent?: boolean;
|
||||||
|
buttonText: string;
|
||||||
|
isFromBotMenu?: boolean;
|
||||||
|
startParam?: string;
|
||||||
|
};
|
||||||
|
prolongWebView: {
|
||||||
|
bot: ApiUser;
|
||||||
|
peer: ApiChat | ApiUser;
|
||||||
|
queryId: string;
|
||||||
|
isSilent?: boolean;
|
||||||
|
replyToMessageId?: number;
|
||||||
|
};
|
||||||
|
requestSimpleWebView: {
|
||||||
|
url: string;
|
||||||
|
bot: ApiUser;
|
||||||
|
buttonText: string;
|
||||||
|
theme?: ApiThemeParameters;
|
||||||
|
};
|
||||||
|
closeWebApp: {};
|
||||||
|
|
||||||
|
cancelBotTrustRequest: {};
|
||||||
|
markBotTrusted: {
|
||||||
|
botId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
closeBotAttachRequestModal: never;
|
||||||
|
confirmBotAttachRequest: never;
|
||||||
|
|
||||||
|
sendWebViewData: {
|
||||||
|
bot: ApiUser;
|
||||||
|
data: string;
|
||||||
|
buttonText: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
loadAttachMenuBots: {
|
||||||
|
hash?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleBotInAttachMenu: {
|
||||||
|
botId: string;
|
||||||
|
isEnabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
callAttachMenuBot: {
|
||||||
|
chatId: string;
|
||||||
|
botId: string;
|
||||||
|
isFromBotMenu?: boolean;
|
||||||
|
url?: string;
|
||||||
|
startParam?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
|
||||||
openPollModal: {
|
openPollModal: {
|
||||||
isQuiz?: boolean;
|
isQuiz?: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const api = require('./api');
|
const api = require('./api');
|
||||||
|
|
||||||
const LAYER = 139;
|
const LAYER = 140;
|
||||||
const tlobjects = {};
|
const tlobjects = {};
|
||||||
|
|
||||||
for (const tl of Object.values(api)) {
|
for (const tl of Object.values(api)) {
|
||||||
|
|||||||
325
src/lib/gramjs/tl/api.d.ts
vendored
325
src/lib/gramjs/tl/api.d.ts
vendored
@ -70,7 +70,7 @@ namespace Api {
|
|||||||
export type TypeChatPhoto = ChatPhotoEmpty | ChatPhoto;
|
export type TypeChatPhoto = ChatPhotoEmpty | ChatPhoto;
|
||||||
export type TypeMessage = MessageEmpty | Message | MessageService;
|
export type TypeMessage = MessageEmpty | Message | MessageService;
|
||||||
export type TypeMessageMedia = MessageMediaEmpty | MessageMediaPhoto | MessageMediaGeo | MessageMediaContact | MessageMediaUnsupported | MessageMediaDocument | MessageMediaWebPage | MessageMediaVenue | MessageMediaGame | MessageMediaInvoice | MessageMediaGeoLive | MessageMediaPoll | MessageMediaDice;
|
export type TypeMessageMedia = MessageMediaEmpty | MessageMediaPhoto | MessageMediaGeo | MessageMediaContact | MessageMediaUnsupported | MessageMediaDocument | MessageMediaWebPage | MessageMediaVenue | MessageMediaGame | MessageMediaInvoice | MessageMediaGeoLive | MessageMediaPoll | MessageMediaDice;
|
||||||
export type TypeMessageAction = MessageActionEmpty | MessageActionChatCreate | MessageActionChatEditTitle | MessageActionChatEditPhoto | MessageActionChatDeletePhoto | MessageActionChatAddUser | MessageActionChatDeleteUser | MessageActionChatJoinedByLink | MessageActionChannelCreate | MessageActionChatMigrateTo | MessageActionChannelMigrateFrom | MessageActionPinMessage | MessageActionHistoryClear | MessageActionGameScore | MessageActionPaymentSentMe | MessageActionPaymentSent | MessageActionPhoneCall | MessageActionScreenshotTaken | MessageActionCustomAction | MessageActionBotAllowed | MessageActionSecureValuesSentMe | MessageActionSecureValuesSent | MessageActionContactSignUp | MessageActionGeoProximityReached | MessageActionGroupCall | MessageActionInviteToGroupCall | MessageActionSetMessagesTTL | MessageActionGroupCallScheduled | MessageActionSetChatTheme | MessageActionChatJoinedByRequest;
|
export type TypeMessageAction = MessageActionEmpty | MessageActionChatCreate | MessageActionChatEditTitle | MessageActionChatEditPhoto | MessageActionChatDeletePhoto | MessageActionChatAddUser | MessageActionChatDeleteUser | MessageActionChatJoinedByLink | MessageActionChannelCreate | MessageActionChatMigrateTo | MessageActionChannelMigrateFrom | MessageActionPinMessage | MessageActionHistoryClear | MessageActionGameScore | MessageActionPaymentSentMe | MessageActionPaymentSent | MessageActionPhoneCall | MessageActionScreenshotTaken | MessageActionCustomAction | MessageActionBotAllowed | MessageActionSecureValuesSentMe | MessageActionSecureValuesSent | MessageActionContactSignUp | MessageActionGeoProximityReached | MessageActionGroupCall | MessageActionInviteToGroupCall | MessageActionSetMessagesTTL | MessageActionGroupCallScheduled | MessageActionSetChatTheme | MessageActionChatJoinedByRequest | MessageActionWebViewDataSentMe | MessageActionWebViewDataSent;
|
||||||
export type TypeDialog = Dialog | DialogFolder;
|
export type TypeDialog = Dialog | DialogFolder;
|
||||||
export type TypePhoto = PhotoEmpty | Photo;
|
export type TypePhoto = PhotoEmpty | Photo;
|
||||||
export type TypePhotoSize = PhotoSizeEmpty | PhotoSize | PhotoCachedSize | PhotoStrippedSize | PhotoSizeProgressive | PhotoPathSize;
|
export type TypePhotoSize = PhotoSizeEmpty | PhotoSize | PhotoCachedSize | PhotoStrippedSize | PhotoSizeProgressive | PhotoPathSize;
|
||||||
@ -86,7 +86,7 @@ namespace Api {
|
|||||||
export type TypeImportedContact = ImportedContact;
|
export type TypeImportedContact = ImportedContact;
|
||||||
export type TypeContactStatus = ContactStatus;
|
export type TypeContactStatus = ContactStatus;
|
||||||
export type TypeMessagesFilter = InputMessagesFilterEmpty | InputMessagesFilterPhotos | InputMessagesFilterVideo | InputMessagesFilterPhotoVideo | InputMessagesFilterDocument | InputMessagesFilterUrl | InputMessagesFilterGif | InputMessagesFilterVoice | InputMessagesFilterMusic | InputMessagesFilterChatPhotos | InputMessagesFilterPhoneCalls | InputMessagesFilterRoundVoice | InputMessagesFilterRoundVideo | InputMessagesFilterMyMentions | InputMessagesFilterGeo | InputMessagesFilterContacts | InputMessagesFilterPinned;
|
export type TypeMessagesFilter = InputMessagesFilterEmpty | InputMessagesFilterPhotos | InputMessagesFilterVideo | InputMessagesFilterPhotoVideo | InputMessagesFilterDocument | InputMessagesFilterUrl | InputMessagesFilterGif | InputMessagesFilterVoice | InputMessagesFilterMusic | InputMessagesFilterChatPhotos | InputMessagesFilterPhoneCalls | InputMessagesFilterRoundVoice | InputMessagesFilterRoundVideo | InputMessagesFilterMyMentions | InputMessagesFilterGeo | InputMessagesFilterContacts | InputMessagesFilterPinned;
|
||||||
export type TypeUpdate = UpdateNewMessage | UpdateMessageID | UpdateDeleteMessages | UpdateUserTyping | UpdateChatUserTyping | UpdateChatParticipants | UpdateUserStatus | UpdateUserName | UpdateUserPhoto | UpdateNewEncryptedMessage | UpdateEncryptedChatTyping | UpdateEncryption | UpdateEncryptedMessagesRead | UpdateChatParticipantAdd | UpdateChatParticipantDelete | UpdateDcOptions | UpdateNotifySettings | UpdateServiceNotification | UpdatePrivacy | UpdateUserPhone | UpdateReadHistoryInbox | UpdateReadHistoryOutbox | UpdateWebPage | UpdateReadMessagesContents | UpdateChannelTooLong | UpdateChannel | UpdateNewChannelMessage | UpdateReadChannelInbox | UpdateDeleteChannelMessages | UpdateChannelMessageViews | UpdateChatParticipantAdmin | UpdateNewStickerSet | UpdateStickerSetsOrder | UpdateStickerSets | UpdateSavedGifs | UpdateBotInlineQuery | UpdateBotInlineSend | UpdateEditChannelMessage | UpdateBotCallbackQuery | UpdateEditMessage | UpdateInlineBotCallbackQuery | UpdateReadChannelOutbox | UpdateDraftMessage | UpdateReadFeaturedStickers | UpdateRecentStickers | UpdateConfig | UpdatePtsChanged | UpdateChannelWebPage | UpdateDialogPinned | UpdatePinnedDialogs | UpdateBotWebhookJSON | UpdateBotWebhookJSONQuery | UpdateBotShippingQuery | UpdateBotPrecheckoutQuery | UpdatePhoneCall | UpdateLangPackTooLong | UpdateLangPack | UpdateFavedStickers | UpdateChannelReadMessagesContents | UpdateContactsReset | UpdateChannelAvailableMessages | UpdateDialogUnreadMark | UpdateMessagePoll | UpdateChatDefaultBannedRights | UpdateFolderPeers | UpdatePeerSettings | UpdatePeerLocated | UpdateNewScheduledMessage | UpdateDeleteScheduledMessages | UpdateTheme | UpdateGeoLiveViewed | UpdateLoginToken | UpdateMessagePollVote | UpdateDialogFilter | UpdateDialogFilterOrder | UpdateDialogFilters | UpdatePhoneCallSignalingData | UpdateChannelMessageForwards | UpdateReadChannelDiscussionInbox | UpdateReadChannelDiscussionOutbox | UpdatePeerBlocked | UpdateChannelUserTyping | UpdatePinnedMessages | UpdatePinnedChannelMessages | UpdateChat | UpdateGroupCallParticipants | UpdateGroupCall | UpdatePeerHistoryTTL | UpdateChatParticipant | UpdateChannelParticipant | UpdateBotStopped | UpdateGroupCallConnection | UpdateBotCommands | UpdatePendingJoinRequests | UpdateBotChatInviteRequester | UpdateMessageReactions;
|
export type TypeUpdate = UpdateNewMessage | UpdateMessageID | UpdateDeleteMessages | UpdateUserTyping | UpdateChatUserTyping | UpdateChatParticipants | UpdateUserStatus | UpdateUserName | UpdateUserPhoto | UpdateNewEncryptedMessage | UpdateEncryptedChatTyping | UpdateEncryption | UpdateEncryptedMessagesRead | UpdateChatParticipantAdd | UpdateChatParticipantDelete | UpdateDcOptions | UpdateNotifySettings | UpdateServiceNotification | UpdatePrivacy | UpdateUserPhone | UpdateReadHistoryInbox | UpdateReadHistoryOutbox | UpdateWebPage | UpdateReadMessagesContents | UpdateChannelTooLong | UpdateChannel | UpdateNewChannelMessage | UpdateReadChannelInbox | UpdateDeleteChannelMessages | UpdateChannelMessageViews | UpdateChatParticipantAdmin | UpdateNewStickerSet | UpdateStickerSetsOrder | UpdateStickerSets | UpdateSavedGifs | UpdateBotInlineQuery | UpdateBotInlineSend | UpdateEditChannelMessage | UpdateBotCallbackQuery | UpdateEditMessage | UpdateInlineBotCallbackQuery | UpdateReadChannelOutbox | UpdateDraftMessage | UpdateReadFeaturedStickers | UpdateRecentStickers | UpdateConfig | UpdatePtsChanged | UpdateChannelWebPage | UpdateDialogPinned | UpdatePinnedDialogs | UpdateBotWebhookJSON | UpdateBotWebhookJSONQuery | UpdateBotShippingQuery | UpdateBotPrecheckoutQuery | UpdatePhoneCall | UpdateLangPackTooLong | UpdateLangPack | UpdateFavedStickers | UpdateChannelReadMessagesContents | UpdateContactsReset | UpdateChannelAvailableMessages | UpdateDialogUnreadMark | UpdateMessagePoll | UpdateChatDefaultBannedRights | UpdateFolderPeers | UpdatePeerSettings | UpdatePeerLocated | UpdateNewScheduledMessage | UpdateDeleteScheduledMessages | UpdateTheme | UpdateGeoLiveViewed | UpdateLoginToken | UpdateMessagePollVote | UpdateDialogFilter | UpdateDialogFilterOrder | UpdateDialogFilters | UpdatePhoneCallSignalingData | UpdateChannelMessageForwards | UpdateReadChannelDiscussionInbox | UpdateReadChannelDiscussionOutbox | UpdatePeerBlocked | UpdateChannelUserTyping | UpdatePinnedMessages | UpdatePinnedChannelMessages | UpdateChat | UpdateGroupCallParticipants | UpdateGroupCall | UpdatePeerHistoryTTL | UpdateChatParticipant | UpdateChannelParticipant | UpdateBotStopped | UpdateGroupCallConnection | UpdateBotCommands | UpdatePendingJoinRequests | UpdateBotChatInviteRequester | UpdateMessageReactions | UpdateAttachMenuBots | UpdateWebViewResultSent | UpdateBotMenuButton | UpdateSavedRingtones;
|
||||||
export type TypeUpdates = UpdatesTooLong | UpdateShortMessage | UpdateShortChatMessage | UpdateShort | UpdatesCombined | Updates | UpdateShortSentMessage;
|
export type TypeUpdates = UpdatesTooLong | UpdateShortMessage | UpdateShortChatMessage | UpdateShort | UpdatesCombined | Updates | UpdateShortSentMessage;
|
||||||
export type TypeDcOption = DcOption;
|
export type TypeDcOption = DcOption;
|
||||||
export type TypeConfig = Config;
|
export type TypeConfig = Config;
|
||||||
@ -116,7 +116,7 @@ namespace Api {
|
|||||||
export type TypeStickerSet = StickerSet;
|
export type TypeStickerSet = StickerSet;
|
||||||
export type TypeBotCommand = BotCommand;
|
export type TypeBotCommand = BotCommand;
|
||||||
export type TypeBotInfo = BotInfo;
|
export type TypeBotInfo = BotInfo;
|
||||||
export type TypeKeyboardButton = KeyboardButton | KeyboardButtonUrl | KeyboardButtonCallback | KeyboardButtonRequestPhone | KeyboardButtonRequestGeoLocation | KeyboardButtonSwitchInline | KeyboardButtonGame | KeyboardButtonBuy | KeyboardButtonUrlAuth | InputKeyboardButtonUrlAuth | KeyboardButtonRequestPoll | InputKeyboardButtonUserProfile | KeyboardButtonUserProfile;
|
export type TypeKeyboardButton = KeyboardButton | KeyboardButtonUrl | KeyboardButtonCallback | KeyboardButtonRequestPhone | KeyboardButtonRequestGeoLocation | KeyboardButtonSwitchInline | KeyboardButtonGame | KeyboardButtonBuy | KeyboardButtonUrlAuth | InputKeyboardButtonUrlAuth | KeyboardButtonRequestPoll | InputKeyboardButtonUserProfile | KeyboardButtonUserProfile | KeyboardButtonWebView | KeyboardButtonSimpleWebView;
|
||||||
export type TypeKeyboardButtonRow = KeyboardButtonRow;
|
export type TypeKeyboardButtonRow = KeyboardButtonRow;
|
||||||
export type TypeReplyMarkup = ReplyKeyboardHide | ReplyKeyboardForceReply | ReplyKeyboardMarkup | ReplyInlineMarkup;
|
export type TypeReplyMarkup = ReplyKeyboardHide | ReplyKeyboardForceReply | ReplyKeyboardMarkup | ReplyInlineMarkup;
|
||||||
export type TypeMessageEntity = MessageEntityUnknown | MessageEntityMention | MessageEntityHashtag | MessageEntityBotCommand | MessageEntityUrl | MessageEntityEmail | MessageEntityBold | MessageEntityItalic | MessageEntityCode | MessageEntityPre | MessageEntityTextUrl | MessageEntityMentionName | InputMessageEntityMentionName | MessageEntityPhone | MessageEntityCashtag | MessageEntityUnderline | MessageEntityStrike | MessageEntityBlockquote | MessageEntityBankCard | MessageEntitySpoiler;
|
export type TypeMessageEntity = MessageEntityUnknown | MessageEntityMention | MessageEntityHashtag | MessageEntityBotCommand | MessageEntityUrl | MessageEntityEmail | MessageEntityBold | MessageEntityItalic | MessageEntityCode | MessageEntityPre | MessageEntityTextUrl | MessageEntityMentionName | InputMessageEntityMentionName | MessageEntityPhone | MessageEntityCashtag | MessageEntityUnderline | MessageEntityStrike | MessageEntityBlockquote | MessageEntityBankCard | MessageEntitySpoiler;
|
||||||
@ -270,6 +270,16 @@ namespace Api {
|
|||||||
export type TypeAvailableReaction = AvailableReaction;
|
export type TypeAvailableReaction = AvailableReaction;
|
||||||
export type TypeMessagePeerReaction = MessagePeerReaction;
|
export type TypeMessagePeerReaction = MessagePeerReaction;
|
||||||
export type TypeGroupCallStreamChannel = GroupCallStreamChannel;
|
export type TypeGroupCallStreamChannel = GroupCallStreamChannel;
|
||||||
|
export type TypeAttachMenuBotIconColor = AttachMenuBotIconColor;
|
||||||
|
export type TypeAttachMenuBotIcon = AttachMenuBotIcon;
|
||||||
|
export type TypeAttachMenuBot = AttachMenuBot;
|
||||||
|
export type TypeAttachMenuBots = AttachMenuBotsNotModified | AttachMenuBots;
|
||||||
|
export type TypeAttachMenuBotsBot = AttachMenuBotsBot;
|
||||||
|
export type TypeWebViewResult = WebViewResultUrl;
|
||||||
|
export type TypeSimpleWebViewResult = SimpleWebViewResultUrl;
|
||||||
|
export type TypeWebViewMessageSent = WebViewMessageSent;
|
||||||
|
export type TypeBotMenuButton = BotMenuButtonDefault | BotMenuButtonCommands | BotMenuButton;
|
||||||
|
export type TypeNotificationSound = NotificationSoundDefault | NotificationSoundNone | NotificationSoundLocal | NotificationSoundRingtone;
|
||||||
export type TypeResPQ = ResPQ;
|
export type TypeResPQ = ResPQ;
|
||||||
export type TypeP_Q_inner_data = PQInnerData | PQInnerDataDc | PQInnerDataTemp | PQInnerDataTempDc;
|
export type TypeP_Q_inner_data = PQInnerData | PQInnerDataDc | PQInnerDataTemp | PQInnerDataTempDc;
|
||||||
export type TypeServer_DH_Params = ServerDHParamsFail | ServerDHParamsOk;
|
export type TypeServer_DH_Params = ServerDHParamsFail | ServerDHParamsOk;
|
||||||
@ -419,6 +429,8 @@ namespace Api {
|
|||||||
export type TypeThemes = account.ThemesNotModified | account.Themes;
|
export type TypeThemes = account.ThemesNotModified | account.Themes;
|
||||||
export type TypeContentSettings = account.ContentSettings;
|
export type TypeContentSettings = account.ContentSettings;
|
||||||
export type TypeResetPasswordResult = account.ResetPasswordFailedWait | account.ResetPasswordRequestedWait | account.ResetPasswordOk;
|
export type TypeResetPasswordResult = account.ResetPasswordFailedWait | account.ResetPasswordRequestedWait | account.ResetPasswordOk;
|
||||||
|
export type TypeSavedRingtones = account.SavedRingtonesNotModified | account.SavedRingtones;
|
||||||
|
export type TypeSavedRingtone = account.SavedRingtone | account.SavedRingtoneConverted;
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace channels {
|
export namespace channels {
|
||||||
@ -882,6 +894,7 @@ namespace Api {
|
|||||||
scam?: true;
|
scam?: true;
|
||||||
applyMinPhoto?: true;
|
applyMinPhoto?: true;
|
||||||
fake?: true;
|
fake?: true;
|
||||||
|
botAttachMenu?: true;
|
||||||
id: long;
|
id: long;
|
||||||
accessHash?: long;
|
accessHash?: long;
|
||||||
firstName?: string;
|
firstName?: string;
|
||||||
@ -911,6 +924,7 @@ namespace Api {
|
|||||||
scam?: true;
|
scam?: true;
|
||||||
applyMinPhoto?: true;
|
applyMinPhoto?: true;
|
||||||
fake?: true;
|
fake?: true;
|
||||||
|
botAttachMenu?: true;
|
||||||
id: long;
|
id: long;
|
||||||
accessHash?: long;
|
accessHash?: long;
|
||||||
firstName?: string;
|
firstName?: string;
|
||||||
@ -960,7 +974,6 @@ namespace Api {
|
|||||||
export class Chat extends VirtualClass<{
|
export class Chat extends VirtualClass<{
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
creator?: true;
|
creator?: true;
|
||||||
kicked?: true;
|
|
||||||
left?: true;
|
left?: true;
|
||||||
deactivated?: true;
|
deactivated?: true;
|
||||||
callActive?: true;
|
callActive?: true;
|
||||||
@ -978,7 +991,6 @@ namespace Api {
|
|||||||
}> {
|
}> {
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
creator?: true;
|
creator?: true;
|
||||||
kicked?: true;
|
|
||||||
left?: true;
|
left?: true;
|
||||||
deactivated?: true;
|
deactivated?: true;
|
||||||
callActive?: true;
|
callActive?: true;
|
||||||
@ -1130,6 +1142,8 @@ namespace Api {
|
|||||||
hasScheduled?: true;
|
hasScheduled?: true;
|
||||||
canViewStats?: true;
|
canViewStats?: true;
|
||||||
blocked?: true;
|
blocked?: true;
|
||||||
|
// flags2: undefined;
|
||||||
|
canDeleteChannel?: true;
|
||||||
id: long;
|
id: long;
|
||||||
about: string;
|
about: string;
|
||||||
participantsCount?: int;
|
participantsCount?: int;
|
||||||
@ -1175,6 +1189,8 @@ namespace Api {
|
|||||||
hasScheduled?: true;
|
hasScheduled?: true;
|
||||||
canViewStats?: true;
|
canViewStats?: true;
|
||||||
blocked?: true;
|
blocked?: true;
|
||||||
|
// flags2: undefined;
|
||||||
|
canDeleteChannel?: true;
|
||||||
id: long;
|
id: long;
|
||||||
about: string;
|
about: string;
|
||||||
participantsCount?: int;
|
participantsCount?: int;
|
||||||
@ -1648,6 +1664,18 @@ namespace Api {
|
|||||||
emoticon: string;
|
emoticon: string;
|
||||||
};
|
};
|
||||||
export class MessageActionChatJoinedByRequest extends VirtualClass<void> {};
|
export class MessageActionChatJoinedByRequest extends VirtualClass<void> {};
|
||||||
|
export class MessageActionWebViewDataSentMe extends VirtualClass<{
|
||||||
|
text: string;
|
||||||
|
data: string;
|
||||||
|
}> {
|
||||||
|
text: string;
|
||||||
|
data: string;
|
||||||
|
};
|
||||||
|
export class MessageActionWebViewDataSent extends VirtualClass<{
|
||||||
|
text: string;
|
||||||
|
}> {
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
export class Dialog extends VirtualClass<{
|
export class Dialog extends VirtualClass<{
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
pinned?: true;
|
pinned?: true;
|
||||||
@ -1805,26 +1833,30 @@ namespace Api {
|
|||||||
showPreviews?: Bool;
|
showPreviews?: Bool;
|
||||||
silent?: Bool;
|
silent?: Bool;
|
||||||
muteUntil?: int;
|
muteUntil?: int;
|
||||||
sound?: string;
|
sound?: Api.TypeNotificationSound;
|
||||||
} | void> {
|
} | void> {
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
showPreviews?: Bool;
|
showPreviews?: Bool;
|
||||||
silent?: Bool;
|
silent?: Bool;
|
||||||
muteUntil?: int;
|
muteUntil?: int;
|
||||||
sound?: string;
|
sound?: Api.TypeNotificationSound;
|
||||||
};
|
};
|
||||||
export class PeerNotifySettings extends VirtualClass<{
|
export class PeerNotifySettings extends VirtualClass<{
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
showPreviews?: Bool;
|
showPreviews?: Bool;
|
||||||
silent?: Bool;
|
silent?: Bool;
|
||||||
muteUntil?: int;
|
muteUntil?: int;
|
||||||
sound?: string;
|
iosSound?: Api.TypeNotificationSound;
|
||||||
|
androidSound?: Api.TypeNotificationSound;
|
||||||
|
otherSound?: Api.TypeNotificationSound;
|
||||||
} | void> {
|
} | void> {
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
showPreviews?: Bool;
|
showPreviews?: Bool;
|
||||||
silent?: Bool;
|
silent?: Bool;
|
||||||
muteUntil?: int;
|
muteUntil?: int;
|
||||||
sound?: string;
|
iosSound?: Api.TypeNotificationSound;
|
||||||
|
androidSound?: Api.TypeNotificationSound;
|
||||||
|
otherSound?: Api.TypeNotificationSound;
|
||||||
};
|
};
|
||||||
export class PeerSettings extends VirtualClass<{
|
export class PeerSettings extends VirtualClass<{
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
@ -1921,6 +1953,8 @@ namespace Api {
|
|||||||
ttlPeriod?: int;
|
ttlPeriod?: int;
|
||||||
themeEmoticon?: string;
|
themeEmoticon?: string;
|
||||||
privateForwardName?: string;
|
privateForwardName?: string;
|
||||||
|
botGroupAdminRights?: Api.TypeChatAdminRights;
|
||||||
|
botBroadcastAdminRights?: Api.TypeChatAdminRights;
|
||||||
}> {
|
}> {
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
blocked?: true;
|
blocked?: true;
|
||||||
@ -1941,6 +1975,8 @@ namespace Api {
|
|||||||
ttlPeriod?: int;
|
ttlPeriod?: int;
|
||||||
themeEmoticon?: string;
|
themeEmoticon?: string;
|
||||||
privateForwardName?: string;
|
privateForwardName?: string;
|
||||||
|
botGroupAdminRights?: Api.TypeChatAdminRights;
|
||||||
|
botBroadcastAdminRights?: Api.TypeChatAdminRights;
|
||||||
};
|
};
|
||||||
export class Contact extends VirtualClass<{
|
export class Contact extends VirtualClass<{
|
||||||
userId: long;
|
userId: long;
|
||||||
@ -2820,6 +2856,20 @@ namespace Api {
|
|||||||
msgId: int;
|
msgId: int;
|
||||||
reactions: Api.TypeMessageReactions;
|
reactions: Api.TypeMessageReactions;
|
||||||
};
|
};
|
||||||
|
export class UpdateAttachMenuBots extends VirtualClass<void> {};
|
||||||
|
export class UpdateWebViewResultSent extends VirtualClass<{
|
||||||
|
queryId: long;
|
||||||
|
}> {
|
||||||
|
queryId: long;
|
||||||
|
};
|
||||||
|
export class UpdateBotMenuButton extends VirtualClass<{
|
||||||
|
botId: long;
|
||||||
|
button: Api.TypeBotMenuButton;
|
||||||
|
}> {
|
||||||
|
botId: long;
|
||||||
|
button: Api.TypeBotMenuButton;
|
||||||
|
};
|
||||||
|
export class UpdateSavedRingtones extends VirtualClass<void> {};
|
||||||
export class UpdatesTooLong extends VirtualClass<void> {};
|
export class UpdatesTooLong extends VirtualClass<void> {};
|
||||||
export class UpdateShortMessage extends VirtualClass<{
|
export class UpdateShortMessage extends VirtualClass<{
|
||||||
// flags: undefined;
|
// flags: undefined;
|
||||||
@ -3697,10 +3747,12 @@ namespace Api {
|
|||||||
userId: long;
|
userId: long;
|
||||||
description: string;
|
description: string;
|
||||||
commands: Api.TypeBotCommand[];
|
commands: Api.TypeBotCommand[];
|
||||||
|
menuButton: Api.TypeBotMenuButton;
|
||||||
}> {
|
}> {
|
||||||
userId: long;
|
userId: long;
|
||||||
description: string;
|
description: string;
|
||||||
commands: Api.TypeBotCommand[];
|
commands: Api.TypeBotCommand[];
|
||||||
|
menuButton: Api.TypeBotMenuButton;
|
||||||
};
|
};
|
||||||
export class KeyboardButton extends VirtualClass<{
|
export class KeyboardButton extends VirtualClass<{
|
||||||
text: string;
|
text: string;
|
||||||
@ -3807,6 +3859,20 @@ namespace Api {
|
|||||||
text: string;
|
text: string;
|
||||||
userId: long;
|
userId: long;
|
||||||
};
|
};
|
||||||
|
export class KeyboardButtonWebView extends VirtualClass<{
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
}> {
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
export class KeyboardButtonSimpleWebView extends VirtualClass<{
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
}> {
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
export class KeyboardButtonRow extends VirtualClass<{
|
export class KeyboardButtonRow extends VirtualClass<{
|
||||||
buttons: Api.TypeKeyboardButton[];
|
buttons: Api.TypeKeyboardButton[];
|
||||||
}> {
|
}> {
|
||||||
@ -7071,6 +7137,96 @@ namespace Api {
|
|||||||
scale: int;
|
scale: int;
|
||||||
lastTimestampMs: long;
|
lastTimestampMs: long;
|
||||||
};
|
};
|
||||||
|
export class AttachMenuBotIconColor extends VirtualClass<{
|
||||||
|
name: string;
|
||||||
|
color: int;
|
||||||
|
}> {
|
||||||
|
name: string;
|
||||||
|
color: int;
|
||||||
|
};
|
||||||
|
export class AttachMenuBotIcon extends VirtualClass<{
|
||||||
|
// flags: undefined;
|
||||||
|
name: string;
|
||||||
|
icon: Api.TypeDocument;
|
||||||
|
colors?: Api.TypeAttachMenuBotIconColor[];
|
||||||
|
}> {
|
||||||
|
// flags: undefined;
|
||||||
|
name: string;
|
||||||
|
icon: Api.TypeDocument;
|
||||||
|
colors?: Api.TypeAttachMenuBotIconColor[];
|
||||||
|
};
|
||||||
|
export class AttachMenuBot extends VirtualClass<{
|
||||||
|
// flags: undefined;
|
||||||
|
inactive?: true;
|
||||||
|
botId: long;
|
||||||
|
shortName: string;
|
||||||
|
icons: Api.TypeAttachMenuBotIcon[];
|
||||||
|
}> {
|
||||||
|
// flags: undefined;
|
||||||
|
inactive?: true;
|
||||||
|
botId: long;
|
||||||
|
shortName: string;
|
||||||
|
icons: Api.TypeAttachMenuBotIcon[];
|
||||||
|
};
|
||||||
|
export class AttachMenuBotsNotModified extends VirtualClass<void> {};
|
||||||
|
export class AttachMenuBots extends VirtualClass<{
|
||||||
|
hash: long;
|
||||||
|
bots: Api.TypeAttachMenuBot[];
|
||||||
|
users: Api.TypeUser[];
|
||||||
|
}> {
|
||||||
|
hash: long;
|
||||||
|
bots: Api.TypeAttachMenuBot[];
|
||||||
|
users: Api.TypeUser[];
|
||||||
|
};
|
||||||
|
export class AttachMenuBotsBot extends VirtualClass<{
|
||||||
|
bot: Api.TypeAttachMenuBot;
|
||||||
|
users: Api.TypeUser[];
|
||||||
|
}> {
|
||||||
|
bot: Api.TypeAttachMenuBot;
|
||||||
|
users: Api.TypeUser[];
|
||||||
|
};
|
||||||
|
export class WebViewResultUrl extends VirtualClass<{
|
||||||
|
queryId: long;
|
||||||
|
url: string;
|
||||||
|
}> {
|
||||||
|
queryId: long;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
export class SimpleWebViewResultUrl extends VirtualClass<{
|
||||||
|
url: string;
|
||||||
|
}> {
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
export class WebViewMessageSent extends VirtualClass<{
|
||||||
|
// flags: undefined;
|
||||||
|
msgId?: Api.TypeInputBotInlineMessageID;
|
||||||
|
} | void> {
|
||||||
|
// flags: undefined;
|
||||||
|
msgId?: Api.TypeInputBotInlineMessageID;
|
||||||
|
};
|
||||||
|
export class BotMenuButtonDefault extends VirtualClass<void> {};
|
||||||
|
export class BotMenuButtonCommands extends VirtualClass<void> {};
|
||||||
|
export class BotMenuButton extends VirtualClass<{
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
}> {
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
export class NotificationSoundDefault extends VirtualClass<void> {};
|
||||||
|
export class NotificationSoundNone extends VirtualClass<void> {};
|
||||||
|
export class NotificationSoundLocal extends VirtualClass<{
|
||||||
|
title: string;
|
||||||
|
data: string;
|
||||||
|
}> {
|
||||||
|
title: string;
|
||||||
|
data: string;
|
||||||
|
};
|
||||||
|
export class NotificationSoundRingtone extends VirtualClass<{
|
||||||
|
id: long;
|
||||||
|
}> {
|
||||||
|
id: long;
|
||||||
|
};
|
||||||
export class ResPQ extends VirtualClass<{
|
export class ResPQ extends VirtualClass<{
|
||||||
nonce: int128;
|
nonce: int128;
|
||||||
serverNonce: int128;
|
serverNonce: int128;
|
||||||
@ -8643,6 +8799,20 @@ namespace Api {
|
|||||||
untilDate: int;
|
untilDate: int;
|
||||||
};
|
};
|
||||||
export class ResetPasswordOk extends VirtualClass<void> {};
|
export class ResetPasswordOk extends VirtualClass<void> {};
|
||||||
|
export class SavedRingtonesNotModified extends VirtualClass<void> {};
|
||||||
|
export class SavedRingtones extends VirtualClass<{
|
||||||
|
hash: long;
|
||||||
|
ringtones: Api.TypeDocument[];
|
||||||
|
}> {
|
||||||
|
hash: long;
|
||||||
|
ringtones: Api.TypeDocument[];
|
||||||
|
};
|
||||||
|
export class SavedRingtone extends VirtualClass<void> {};
|
||||||
|
export class SavedRingtoneConverted extends VirtualClass<{
|
||||||
|
document: Api.TypeDocument;
|
||||||
|
}> {
|
||||||
|
document: Api.TypeDocument;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace channels {
|
export namespace channels {
|
||||||
@ -9673,6 +9843,27 @@ namespace Api {
|
|||||||
encryptedRequestsDisabled?: Bool;
|
encryptedRequestsDisabled?: Bool;
|
||||||
callRequestsDisabled?: Bool;
|
callRequestsDisabled?: Bool;
|
||||||
};
|
};
|
||||||
|
export class GetSavedRingtones extends Request<Partial<{
|
||||||
|
hash: long;
|
||||||
|
}>, account.TypeSavedRingtones> {
|
||||||
|
hash: long;
|
||||||
|
};
|
||||||
|
export class SaveRingtone extends Request<Partial<{
|
||||||
|
id: Api.TypeInputDocument;
|
||||||
|
unsave: Bool;
|
||||||
|
}>, account.TypeSavedRingtone> {
|
||||||
|
id: Api.TypeInputDocument;
|
||||||
|
unsave: Bool;
|
||||||
|
};
|
||||||
|
export class UploadRingtone extends Request<Partial<{
|
||||||
|
file: Api.TypeInputFile;
|
||||||
|
fileName: string;
|
||||||
|
mimeType: string;
|
||||||
|
}>, Api.TypeDocument> {
|
||||||
|
file: Api.TypeInputFile;
|
||||||
|
fileName: string;
|
||||||
|
mimeType: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace users {
|
export namespace users {
|
||||||
@ -11365,6 +11556,88 @@ namespace Api {
|
|||||||
filter: Api.TypeMessagesFilter;
|
filter: Api.TypeMessagesFilter;
|
||||||
limit: int;
|
limit: int;
|
||||||
};
|
};
|
||||||
|
export class GetAttachMenuBots extends Request<Partial<{
|
||||||
|
hash: long;
|
||||||
|
}>, Api.TypeAttachMenuBots> {
|
||||||
|
hash: long;
|
||||||
|
};
|
||||||
|
export class GetAttachMenuBot extends Request<Partial<{
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
}>, Api.TypeAttachMenuBotsBot> {
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
};
|
||||||
|
export class ToggleBotInAttachMenu extends Request<Partial<{
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
enabled: Bool;
|
||||||
|
}>, Bool> {
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
enabled: Bool;
|
||||||
|
};
|
||||||
|
export class RequestWebView extends Request<Partial<{
|
||||||
|
// flags: undefined;
|
||||||
|
fromBotMenu?: true;
|
||||||
|
silent?: true;
|
||||||
|
peer: Api.TypeInputPeer;
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
url?: string;
|
||||||
|
startParam?: string;
|
||||||
|
themeParams?: Api.TypeDataJSON;
|
||||||
|
replyToMsgId?: int;
|
||||||
|
}>, Api.TypeWebViewResult> {
|
||||||
|
// flags: undefined;
|
||||||
|
fromBotMenu?: true;
|
||||||
|
silent?: true;
|
||||||
|
peer: Api.TypeInputPeer;
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
url?: string;
|
||||||
|
startParam?: string;
|
||||||
|
themeParams?: Api.TypeDataJSON;
|
||||||
|
replyToMsgId?: int;
|
||||||
|
};
|
||||||
|
export class ProlongWebView extends Request<Partial<{
|
||||||
|
// flags: undefined;
|
||||||
|
silent?: true;
|
||||||
|
peer: Api.TypeInputPeer;
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
queryId: long;
|
||||||
|
replyToMsgId?: int;
|
||||||
|
}>, Bool> {
|
||||||
|
// flags: undefined;
|
||||||
|
silent?: true;
|
||||||
|
peer: Api.TypeInputPeer;
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
queryId: long;
|
||||||
|
replyToMsgId?: int;
|
||||||
|
};
|
||||||
|
export class RequestSimpleWebView extends Request<Partial<{
|
||||||
|
// flags: undefined;
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
url: string;
|
||||||
|
themeParams?: Api.TypeDataJSON;
|
||||||
|
}>, Api.TypeSimpleWebViewResult> {
|
||||||
|
// flags: undefined;
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
url: string;
|
||||||
|
themeParams?: Api.TypeDataJSON;
|
||||||
|
};
|
||||||
|
export class SendWebViewResultMessage extends Request<Partial<{
|
||||||
|
botQueryId: string;
|
||||||
|
result: Api.TypeInputBotInlineResult;
|
||||||
|
}>, Api.TypeWebViewMessageSent> {
|
||||||
|
botQueryId: string;
|
||||||
|
result: Api.TypeInputBotInlineResult;
|
||||||
|
};
|
||||||
|
export class SendWebViewData extends Request<Partial<{
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
randomId: long;
|
||||||
|
buttonText: string;
|
||||||
|
data: string;
|
||||||
|
}>, Api.TypeUpdates> {
|
||||||
|
bot: Api.TypeInputUser;
|
||||||
|
randomId: long;
|
||||||
|
buttonText: string;
|
||||||
|
data: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace updates {
|
export namespace updates {
|
||||||
@ -11811,9 +12084,13 @@ namespace Api {
|
|||||||
id: int[];
|
id: int[];
|
||||||
};
|
};
|
||||||
export class DeleteHistory extends Request<Partial<{
|
export class DeleteHistory extends Request<Partial<{
|
||||||
|
// flags: undefined;
|
||||||
|
forEveryone?: true;
|
||||||
channel: Api.TypeInputChannel;
|
channel: Api.TypeInputChannel;
|
||||||
maxId: int;
|
maxId: int;
|
||||||
}>, Bool> {
|
}>, Api.TypeUpdates> {
|
||||||
|
// flags: undefined;
|
||||||
|
forEveryone?: true;
|
||||||
channel: Api.TypeInputChannel;
|
channel: Api.TypeInputChannel;
|
||||||
maxId: int;
|
maxId: int;
|
||||||
};
|
};
|
||||||
@ -11932,6 +12209,28 @@ namespace Api {
|
|||||||
scope: Api.TypeBotCommandScope;
|
scope: Api.TypeBotCommandScope;
|
||||||
langCode: string;
|
langCode: string;
|
||||||
};
|
};
|
||||||
|
export class SetBotMenuButton extends Request<Partial<{
|
||||||
|
userId: Api.TypeInputUser;
|
||||||
|
button: Api.TypeBotMenuButton;
|
||||||
|
}>, Bool> {
|
||||||
|
userId: Api.TypeInputUser;
|
||||||
|
button: Api.TypeBotMenuButton;
|
||||||
|
};
|
||||||
|
export class GetBotMenuButton extends Request<Partial<{
|
||||||
|
userId: Api.TypeInputUser;
|
||||||
|
}>, Api.TypeBotMenuButton> {
|
||||||
|
userId: Api.TypeInputUser;
|
||||||
|
};
|
||||||
|
export class SetBotBroadcastDefaultAdminRights extends Request<Partial<{
|
||||||
|
adminRights: Api.TypeChatAdminRights;
|
||||||
|
}>, Bool> {
|
||||||
|
adminRights: Api.TypeChatAdminRights;
|
||||||
|
};
|
||||||
|
export class SetBotGroupDefaultAdminRights extends Request<Partial<{
|
||||||
|
adminRights: Api.TypeChatAdminRights;
|
||||||
|
}>, Bool> {
|
||||||
|
adminRights: Api.TypeChatAdminRights;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace payments {
|
export namespace payments {
|
||||||
@ -12450,16 +12749,16 @@ namespace Api {
|
|||||||
|
|
||||||
export type AnyRequest = InvokeAfterMsg | InvokeAfterMsgs | InitConnection | InvokeWithLayer | InvokeWithoutUpdates | InvokeWithMessagesRange | InvokeWithTakeout | ReqPq | ReqPqMulti | ReqPqMultiNew | ReqDHParams | SetClientDHParams | DestroyAuthKey | RpcDropAnswer | GetFutureSalts | Ping | PingDelayDisconnect | DestroySession
|
export type AnyRequest = InvokeAfterMsg | InvokeAfterMsgs | InitConnection | InvokeWithLayer | InvokeWithoutUpdates | InvokeWithMessagesRange | InvokeWithTakeout | ReqPq | ReqPqMulti | ReqPqMultiNew | ReqDHParams | SetClientDHParams | DestroyAuthKey | RpcDropAnswer | GetFutureSalts | Ping | PingDelayDisconnect | DestroySession
|
||||||
| auth.SendCode | auth.SignUp | auth.SignIn | auth.LogOut | auth.ResetAuthorizations | auth.ExportAuthorization | auth.ImportAuthorization | auth.BindTempAuthKey | auth.ImportBotAuthorization | auth.CheckPassword | auth.RequestPasswordRecovery | auth.RecoverPassword | auth.ResendCode | auth.CancelCode | auth.DropTempAuthKeys | auth.ExportLoginToken | auth.ImportLoginToken | auth.AcceptLoginToken | auth.CheckRecoveryPassword
|
| auth.SendCode | auth.SignUp | auth.SignIn | auth.LogOut | auth.ResetAuthorizations | auth.ExportAuthorization | auth.ImportAuthorization | auth.BindTempAuthKey | auth.ImportBotAuthorization | auth.CheckPassword | auth.RequestPasswordRecovery | auth.RecoverPassword | auth.ResendCode | auth.CancelCode | auth.DropTempAuthKeys | auth.ExportLoginToken | auth.ImportLoginToken | auth.AcceptLoginToken | auth.CheckRecoveryPassword
|
||||||
| account.RegisterDevice | account.UnregisterDevice | account.UpdateNotifySettings | account.GetNotifySettings | account.ResetNotifySettings | account.UpdateProfile | account.UpdateStatus | account.GetWallPapers | account.ReportPeer | account.CheckUsername | account.UpdateUsername | account.GetPrivacy | account.SetPrivacy | account.DeleteAccount | account.GetAccountTTL | account.SetAccountTTL | account.SendChangePhoneCode | account.ChangePhone | account.UpdateDeviceLocked | account.GetAuthorizations | account.ResetAuthorization | account.GetPassword | account.GetPasswordSettings | account.UpdatePasswordSettings | account.SendConfirmPhoneCode | account.ConfirmPhone | account.GetTmpPassword | account.GetWebAuthorizations | account.ResetWebAuthorization | account.ResetWebAuthorizations | account.GetAllSecureValues | account.GetSecureValue | account.SaveSecureValue | account.DeleteSecureValue | account.GetAuthorizationForm | account.AcceptAuthorization | account.SendVerifyPhoneCode | account.VerifyPhone | account.SendVerifyEmailCode | account.VerifyEmail | account.InitTakeoutSession | account.FinishTakeoutSession | account.ConfirmPasswordEmail | account.ResendPasswordEmail | account.CancelPasswordEmail | account.GetContactSignUpNotification | account.SetContactSignUpNotification | account.GetNotifyExceptions | account.GetWallPaper | account.UploadWallPaper | account.SaveWallPaper | account.InstallWallPaper | account.ResetWallPapers | account.GetAutoDownloadSettings | account.SaveAutoDownloadSettings | account.UploadTheme | account.CreateTheme | account.UpdateTheme | account.SaveTheme | account.InstallTheme | account.GetTheme | account.GetThemes | account.SetContentSettings | account.GetContentSettings | account.GetMultiWallPapers | account.GetGlobalPrivacySettings | account.SetGlobalPrivacySettings | account.ReportProfilePhoto | account.ResetPassword | account.DeclinePasswordReset | account.GetChatThemes | account.SetAuthorizationTTL | account.ChangeAuthorizationSettings
|
| account.RegisterDevice | account.UnregisterDevice | account.UpdateNotifySettings | account.GetNotifySettings | account.ResetNotifySettings | account.UpdateProfile | account.UpdateStatus | account.GetWallPapers | account.ReportPeer | account.CheckUsername | account.UpdateUsername | account.GetPrivacy | account.SetPrivacy | account.DeleteAccount | account.GetAccountTTL | account.SetAccountTTL | account.SendChangePhoneCode | account.ChangePhone | account.UpdateDeviceLocked | account.GetAuthorizations | account.ResetAuthorization | account.GetPassword | account.GetPasswordSettings | account.UpdatePasswordSettings | account.SendConfirmPhoneCode | account.ConfirmPhone | account.GetTmpPassword | account.GetWebAuthorizations | account.ResetWebAuthorization | account.ResetWebAuthorizations | account.GetAllSecureValues | account.GetSecureValue | account.SaveSecureValue | account.DeleteSecureValue | account.GetAuthorizationForm | account.AcceptAuthorization | account.SendVerifyPhoneCode | account.VerifyPhone | account.SendVerifyEmailCode | account.VerifyEmail | account.InitTakeoutSession | account.FinishTakeoutSession | account.ConfirmPasswordEmail | account.ResendPasswordEmail | account.CancelPasswordEmail | account.GetContactSignUpNotification | account.SetContactSignUpNotification | account.GetNotifyExceptions | account.GetWallPaper | account.UploadWallPaper | account.SaveWallPaper | account.InstallWallPaper | account.ResetWallPapers | account.GetAutoDownloadSettings | account.SaveAutoDownloadSettings | account.UploadTheme | account.CreateTheme | account.UpdateTheme | account.SaveTheme | account.InstallTheme | account.GetTheme | account.GetThemes | account.SetContentSettings | account.GetContentSettings | account.GetMultiWallPapers | account.GetGlobalPrivacySettings | account.SetGlobalPrivacySettings | account.ReportProfilePhoto | account.ResetPassword | account.DeclinePasswordReset | account.GetChatThemes | account.SetAuthorizationTTL | account.ChangeAuthorizationSettings | account.GetSavedRingtones | account.SaveRingtone | account.UploadRingtone
|
||||||
| users.GetUsers | users.GetFullUser | users.SetSecureValueErrors
|
| users.GetUsers | users.GetFullUser | users.SetSecureValueErrors
|
||||||
| contacts.GetContactIDs | contacts.GetStatuses | contacts.GetContacts | contacts.ImportContacts | contacts.DeleteContacts | contacts.DeleteByPhones | contacts.Block | contacts.Unblock | contacts.GetBlocked | contacts.Search | contacts.ResolveUsername | contacts.GetTopPeers | contacts.ResetTopPeerRating | contacts.ResetSaved | contacts.GetSaved | contacts.ToggleTopPeers | contacts.AddContact | contacts.AcceptContact | contacts.GetLocated | contacts.BlockFromReplies | contacts.ResolvePhone
|
| contacts.GetContactIDs | contacts.GetStatuses | contacts.GetContacts | contacts.ImportContacts | contacts.DeleteContacts | contacts.DeleteByPhones | contacts.Block | contacts.Unblock | contacts.GetBlocked | contacts.Search | contacts.ResolveUsername | contacts.GetTopPeers | contacts.ResetTopPeerRating | contacts.ResetSaved | contacts.GetSaved | contacts.ToggleTopPeers | contacts.AddContact | contacts.AcceptContact | contacts.GetLocated | contacts.BlockFromReplies | contacts.ResolvePhone
|
||||||
| messages.GetMessages | messages.GetDialogs | messages.GetHistory | messages.Search | messages.ReadHistory | messages.DeleteHistory | messages.DeleteMessages | messages.ReceivedMessages | messages.SetTyping | messages.SendMessage | messages.SendMedia | messages.ForwardMessages | messages.ReportSpam | messages.GetPeerSettings | messages.Report | messages.GetChats | messages.GetFullChat | messages.EditChatTitle | messages.EditChatPhoto | messages.AddChatUser | messages.DeleteChatUser | messages.CreateChat | messages.GetDhConfig | messages.RequestEncryption | messages.AcceptEncryption | messages.DiscardEncryption | messages.SetEncryptedTyping | messages.ReadEncryptedHistory | messages.SendEncrypted | messages.SendEncryptedFile | messages.SendEncryptedService | messages.ReceivedQueue | messages.ReportEncryptedSpam | messages.ReadMessageContents | messages.GetStickers | messages.GetAllStickers | messages.GetWebPagePreview | messages.ExportChatInvite | messages.CheckChatInvite | messages.ImportChatInvite | messages.GetStickerSet | messages.InstallStickerSet | messages.UninstallStickerSet | messages.StartBot | messages.GetMessagesViews | messages.EditChatAdmin | messages.MigrateChat | messages.SearchGlobal | messages.ReorderStickerSets | messages.GetDocumentByHash | messages.GetSavedGifs | messages.SaveGif | messages.GetInlineBotResults | messages.SetInlineBotResults | messages.SendInlineBotResult | messages.GetMessageEditData | messages.EditMessage | messages.EditInlineBotMessage | messages.GetBotCallbackAnswer | messages.SetBotCallbackAnswer | messages.GetPeerDialogs | messages.SaveDraft | messages.GetAllDrafts | messages.GetFeaturedStickers | messages.ReadFeaturedStickers | messages.GetRecentStickers | messages.SaveRecentSticker | messages.ClearRecentStickers | messages.GetArchivedStickers | messages.GetMaskStickers | messages.GetAttachedStickers | messages.SetGameScore | messages.SetInlineGameScore | messages.GetGameHighScores | messages.GetInlineGameHighScores | messages.GetCommonChats | messages.GetAllChats | messages.GetWebPage | messages.ToggleDialogPin | messages.ReorderPinnedDialogs | messages.GetPinnedDialogs | messages.SetBotShippingResults | messages.SetBotPrecheckoutResults | messages.UploadMedia | messages.SendScreenshotNotification | messages.GetFavedStickers | messages.FaveSticker | messages.GetUnreadMentions | messages.ReadMentions | messages.GetRecentLocations | messages.SendMultiMedia | messages.UploadEncryptedFile | messages.SearchStickerSets | messages.GetSplitRanges | messages.MarkDialogUnread | messages.GetDialogUnreadMarks | messages.ClearAllDrafts | messages.UpdatePinnedMessage | messages.SendVote | messages.GetPollResults | messages.GetOnlines | messages.EditChatAbout | messages.EditChatDefaultBannedRights | messages.GetEmojiKeywords | messages.GetEmojiKeywordsDifference | messages.GetEmojiKeywordsLanguages | messages.GetEmojiURL | messages.GetSearchCounters | messages.RequestUrlAuth | messages.AcceptUrlAuth | messages.HidePeerSettingsBar | messages.GetScheduledHistory | messages.GetScheduledMessages | messages.SendScheduledMessages | messages.DeleteScheduledMessages | messages.GetPollVotes | messages.ToggleStickerSets | messages.GetDialogFilters | messages.GetSuggestedDialogFilters | messages.UpdateDialogFilter | messages.UpdateDialogFiltersOrder | messages.GetOldFeaturedStickers | messages.GetReplies | messages.GetDiscussionMessage | messages.ReadDiscussion | messages.UnpinAllMessages | messages.DeleteChat | messages.DeletePhoneCallHistory | messages.CheckHistoryImport | messages.InitHistoryImport | messages.UploadImportedMedia | messages.StartHistoryImport | messages.GetExportedChatInvites | messages.GetExportedChatInvite | messages.EditExportedChatInvite | messages.DeleteRevokedExportedChatInvites | messages.DeleteExportedChatInvite | messages.GetAdminsWithInvites | messages.GetChatInviteImporters | messages.SetHistoryTTL | messages.CheckHistoryImportPeer | messages.SetChatTheme | messages.GetMessageReadParticipants | messages.GetSearchResultsCalendar | messages.GetSearchResultsPositions | messages.HideChatJoinRequest | messages.HideAllChatJoinRequests | messages.ToggleNoForwards | messages.SaveDefaultSendAs | messages.SendReaction | messages.GetMessagesReactions | messages.GetMessageReactionsList | messages.SetChatAvailableReactions | messages.GetAvailableReactions | messages.SetDefaultReaction | messages.TranslateText | messages.GetUnreadReactions | messages.ReadReactions | messages.SearchSentMedia
|
| messages.GetMessages | messages.GetDialogs | messages.GetHistory | messages.Search | messages.ReadHistory | messages.DeleteHistory | messages.DeleteMessages | messages.ReceivedMessages | messages.SetTyping | messages.SendMessage | messages.SendMedia | messages.ForwardMessages | messages.ReportSpam | messages.GetPeerSettings | messages.Report | messages.GetChats | messages.GetFullChat | messages.EditChatTitle | messages.EditChatPhoto | messages.AddChatUser | messages.DeleteChatUser | messages.CreateChat | messages.GetDhConfig | messages.RequestEncryption | messages.AcceptEncryption | messages.DiscardEncryption | messages.SetEncryptedTyping | messages.ReadEncryptedHistory | messages.SendEncrypted | messages.SendEncryptedFile | messages.SendEncryptedService | messages.ReceivedQueue | messages.ReportEncryptedSpam | messages.ReadMessageContents | messages.GetStickers | messages.GetAllStickers | messages.GetWebPagePreview | messages.ExportChatInvite | messages.CheckChatInvite | messages.ImportChatInvite | messages.GetStickerSet | messages.InstallStickerSet | messages.UninstallStickerSet | messages.StartBot | messages.GetMessagesViews | messages.EditChatAdmin | messages.MigrateChat | messages.SearchGlobal | messages.ReorderStickerSets | messages.GetDocumentByHash | messages.GetSavedGifs | messages.SaveGif | messages.GetInlineBotResults | messages.SetInlineBotResults | messages.SendInlineBotResult | messages.GetMessageEditData | messages.EditMessage | messages.EditInlineBotMessage | messages.GetBotCallbackAnswer | messages.SetBotCallbackAnswer | messages.GetPeerDialogs | messages.SaveDraft | messages.GetAllDrafts | messages.GetFeaturedStickers | messages.ReadFeaturedStickers | messages.GetRecentStickers | messages.SaveRecentSticker | messages.ClearRecentStickers | messages.GetArchivedStickers | messages.GetMaskStickers | messages.GetAttachedStickers | messages.SetGameScore | messages.SetInlineGameScore | messages.GetGameHighScores | messages.GetInlineGameHighScores | messages.GetCommonChats | messages.GetAllChats | messages.GetWebPage | messages.ToggleDialogPin | messages.ReorderPinnedDialogs | messages.GetPinnedDialogs | messages.SetBotShippingResults | messages.SetBotPrecheckoutResults | messages.UploadMedia | messages.SendScreenshotNotification | messages.GetFavedStickers | messages.FaveSticker | messages.GetUnreadMentions | messages.ReadMentions | messages.GetRecentLocations | messages.SendMultiMedia | messages.UploadEncryptedFile | messages.SearchStickerSets | messages.GetSplitRanges | messages.MarkDialogUnread | messages.GetDialogUnreadMarks | messages.ClearAllDrafts | messages.UpdatePinnedMessage | messages.SendVote | messages.GetPollResults | messages.GetOnlines | messages.EditChatAbout | messages.EditChatDefaultBannedRights | messages.GetEmojiKeywords | messages.GetEmojiKeywordsDifference | messages.GetEmojiKeywordsLanguages | messages.GetEmojiURL | messages.GetSearchCounters | messages.RequestUrlAuth | messages.AcceptUrlAuth | messages.HidePeerSettingsBar | messages.GetScheduledHistory | messages.GetScheduledMessages | messages.SendScheduledMessages | messages.DeleteScheduledMessages | messages.GetPollVotes | messages.ToggleStickerSets | messages.GetDialogFilters | messages.GetSuggestedDialogFilters | messages.UpdateDialogFilter | messages.UpdateDialogFiltersOrder | messages.GetOldFeaturedStickers | messages.GetReplies | messages.GetDiscussionMessage | messages.ReadDiscussion | messages.UnpinAllMessages | messages.DeleteChat | messages.DeletePhoneCallHistory | messages.CheckHistoryImport | messages.InitHistoryImport | messages.UploadImportedMedia | messages.StartHistoryImport | messages.GetExportedChatInvites | messages.GetExportedChatInvite | messages.EditExportedChatInvite | messages.DeleteRevokedExportedChatInvites | messages.DeleteExportedChatInvite | messages.GetAdminsWithInvites | messages.GetChatInviteImporters | messages.SetHistoryTTL | messages.CheckHistoryImportPeer | messages.SetChatTheme | messages.GetMessageReadParticipants | messages.GetSearchResultsCalendar | messages.GetSearchResultsPositions | messages.HideChatJoinRequest | messages.HideAllChatJoinRequests | messages.ToggleNoForwards | messages.SaveDefaultSendAs | messages.SendReaction | messages.GetMessagesReactions | messages.GetMessageReactionsList | messages.SetChatAvailableReactions | messages.GetAvailableReactions | messages.SetDefaultReaction | messages.TranslateText | messages.GetUnreadReactions | messages.ReadReactions | messages.SearchSentMedia | messages.GetAttachMenuBots | messages.GetAttachMenuBot | messages.ToggleBotInAttachMenu | messages.RequestWebView | messages.ProlongWebView | messages.RequestSimpleWebView | messages.SendWebViewResultMessage | messages.SendWebViewData
|
||||||
| updates.GetState | updates.GetDifference | updates.GetChannelDifference
|
| updates.GetState | updates.GetDifference | updates.GetChannelDifference
|
||||||
| photos.UpdateProfilePhoto | photos.UploadProfilePhoto | photos.DeletePhotos | photos.GetUserPhotos
|
| photos.UpdateProfilePhoto | photos.UploadProfilePhoto | photos.DeletePhotos | photos.GetUserPhotos
|
||||||
| upload.SaveFilePart | upload.GetFile | upload.SaveBigFilePart | upload.GetWebFile | upload.GetCdnFile | upload.ReuploadCdnFile | upload.GetCdnFileHashes | upload.GetFileHashes
|
| upload.SaveFilePart | upload.GetFile | upload.SaveBigFilePart | upload.GetWebFile | upload.GetCdnFile | upload.ReuploadCdnFile | upload.GetCdnFileHashes | upload.GetFileHashes
|
||||||
| help.GetConfig | help.GetNearestDc | help.GetAppUpdate | help.GetInviteText | help.GetSupport | help.GetAppChangelog | help.SetBotUpdatesStatus | help.GetCdnConfig | help.GetRecentMeUrls | help.GetTermsOfServiceUpdate | help.AcceptTermsOfService | help.GetDeepLinkInfo | help.GetAppConfig | help.SaveAppLog | help.GetPassportConfig | help.GetSupportName | help.GetUserInfo | help.EditUserInfo | help.GetPromoData | help.HidePromoData | help.DismissSuggestion | help.GetCountriesList
|
| help.GetConfig | help.GetNearestDc | help.GetAppUpdate | help.GetInviteText | help.GetSupport | help.GetAppChangelog | help.SetBotUpdatesStatus | help.GetCdnConfig | help.GetRecentMeUrls | help.GetTermsOfServiceUpdate | help.AcceptTermsOfService | help.GetDeepLinkInfo | help.GetAppConfig | help.SaveAppLog | help.GetPassportConfig | help.GetSupportName | help.GetUserInfo | help.EditUserInfo | help.GetPromoData | help.HidePromoData | help.DismissSuggestion | help.GetCountriesList
|
||||||
| channels.ReadHistory | channels.DeleteMessages | channels.ReportSpam | channels.GetMessages | channels.GetParticipants | channels.GetParticipant | channels.GetChannels | channels.GetFullChannel | channels.CreateChannel | channels.EditAdmin | channels.EditTitle | channels.EditPhoto | channels.CheckUsername | channels.UpdateUsername | channels.JoinChannel | channels.LeaveChannel | channels.InviteToChannel | channels.DeleteChannel | channels.ExportMessageLink | channels.ToggleSignatures | channels.GetAdminedPublicChannels | channels.EditBanned | channels.GetAdminLog | channels.SetStickers | channels.ReadMessageContents | channels.DeleteHistory | channels.TogglePreHistoryHidden | channels.GetLeftChannels | channels.GetGroupsForDiscussion | channels.SetDiscussionGroup | channels.EditCreator | channels.EditLocation | channels.ToggleSlowMode | channels.GetInactiveChannels | channels.ConvertToGigagroup | channels.ViewSponsoredMessage | channels.GetSponsoredMessages | channels.GetSendAs | channels.DeleteParticipantHistory
|
| channels.ReadHistory | channels.DeleteMessages | channels.ReportSpam | channels.GetMessages | channels.GetParticipants | channels.GetParticipant | channels.GetChannels | channels.GetFullChannel | channels.CreateChannel | channels.EditAdmin | channels.EditTitle | channels.EditPhoto | channels.CheckUsername | channels.UpdateUsername | channels.JoinChannel | channels.LeaveChannel | channels.InviteToChannel | channels.DeleteChannel | channels.ExportMessageLink | channels.ToggleSignatures | channels.GetAdminedPublicChannels | channels.EditBanned | channels.GetAdminLog | channels.SetStickers | channels.ReadMessageContents | channels.DeleteHistory | channels.TogglePreHistoryHidden | channels.GetLeftChannels | channels.GetGroupsForDiscussion | channels.SetDiscussionGroup | channels.EditCreator | channels.EditLocation | channels.ToggleSlowMode | channels.GetInactiveChannels | channels.ConvertToGigagroup | channels.ViewSponsoredMessage | channels.GetSponsoredMessages | channels.GetSendAs | channels.DeleteParticipantHistory
|
||||||
| bots.SendCustomRequest | bots.AnswerWebhookJSONQuery | bots.SetBotCommands | bots.ResetBotCommands | bots.GetBotCommands
|
| bots.SendCustomRequest | bots.AnswerWebhookJSONQuery | bots.SetBotCommands | bots.ResetBotCommands | bots.GetBotCommands | bots.SetBotMenuButton | bots.GetBotMenuButton | bots.SetBotBroadcastDefaultAdminRights | bots.SetBotGroupDefaultAdminRights
|
||||||
| payments.GetPaymentForm | payments.GetPaymentReceipt | payments.ValidateRequestedInfo | payments.SendPaymentForm | payments.GetSavedInfo | payments.ClearSavedInfo | payments.GetBankCardData
|
| payments.GetPaymentForm | payments.GetPaymentReceipt | payments.ValidateRequestedInfo | payments.SendPaymentForm | payments.GetSavedInfo | payments.ClearSavedInfo | payments.GetBankCardData
|
||||||
| stickers.CreateStickerSet | stickers.RemoveStickerFromSet | stickers.ChangeStickerPosition | stickers.AddStickerToSet | stickers.SetStickerSetThumb | stickers.CheckShortName | stickers.SuggestShortName
|
| stickers.CreateStickerSet | stickers.RemoveStickerFromSet | stickers.ChangeStickerPosition | stickers.AddStickerToSet | stickers.SetStickerSetThumb | stickers.CheckShortName | stickers.SuggestShortName
|
||||||
| phone.GetCallConfig | phone.RequestCall | phone.AcceptCall | phone.ConfirmCall | phone.ReceivedCall | phone.DiscardCall | phone.SetCallRating | phone.SaveCallDebug | phone.SendSignalingData | phone.CreateGroupCall | phone.JoinGroupCall | phone.LeaveGroupCall | phone.InviteToGroupCall | phone.DiscardGroupCall | phone.ToggleGroupCallSettings | phone.GetGroupCall | phone.GetGroupParticipants | phone.CheckGroupCall | phone.ToggleGroupCallRecord | phone.EditGroupCallParticipant | phone.EditGroupCallTitle | phone.GetGroupCallJoinAs | phone.ExportGroupCallInvite | phone.ToggleGroupCallStartSubscription | phone.StartScheduledGroupCall | phone.SaveDefaultGroupCallJoinAs | phone.JoinGroupCallPresentation | phone.LeaveGroupCallPresentation | phone.GetGroupCallStreamChannels | phone.GetGroupCallStreamRtmpUrl
|
| phone.GetCallConfig | phone.RequestCall | phone.AcceptCall | phone.ConfirmCall | phone.ReceivedCall | phone.DiscardCall | phone.SetCallRating | phone.SaveCallDebug | phone.SendSignalingData | phone.CreateGroupCall | phone.JoinGroupCall | phone.LeaveGroupCall | phone.InviteToGroupCall | phone.DiscardGroupCall | phone.ToggleGroupCallSettings | phone.GetGroupCall | phone.GetGroupParticipants | phone.CheckGroupCall | phone.ToggleGroupCallRecord | phone.EditGroupCallParticipant | phone.EditGroupCallTitle | phone.GetGroupCallJoinAs | phone.ExportGroupCallInvite | phone.ToggleGroupCallStartSubscription | phone.StartScheduledGroupCall | phone.SaveDefaultGroupCallJoinAs | phone.JoinGroupCallPresentation | phone.LeaveGroupCallPresentation | phone.GetGroupCallStreamChannels | phone.GetGroupCallStreamRtmpUrl
|
||||||
|
|||||||
@ -259,11 +259,13 @@ function createClasses(classesType, params) {
|
|||||||
if (argsConfig.hasOwnProperty(argName)) {
|
if (argsConfig.hasOwnProperty(argName)) {
|
||||||
const arg = argsConfig[argName];
|
const arg = argsConfig[argName];
|
||||||
if (arg.isFlag) {
|
if (arg.isFlag) {
|
||||||
|
const flagValue = arg.flagIndex > 30
|
||||||
|
? args.flags2 & (1 << (arg.flagIndex - 31)) : args.flags & (1 << arg.flagIndex);
|
||||||
if (arg.type === 'true') {
|
if (arg.type === 'true') {
|
||||||
args[argName] = Boolean(args.flags & (1 << arg.flagIndex));
|
args[argName] = Boolean(flagValue);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (args.flags & (1 << arg.flagIndex)) {
|
if (flagValue) {
|
||||||
args[argName] = getArgFromReader(reader, arg);
|
args[argName] = getArgFromReader(reader, arg);
|
||||||
} else {
|
} else {
|
||||||
args[argName] = undefined;
|
args[argName] = undefined;
|
||||||
|
|||||||
@ -64,7 +64,7 @@ storage.fileMov#4b09ebbc = storage.FileType;
|
|||||||
storage.fileMp4#b3cea0e4 = storage.FileType;
|
storage.fileMp4#b3cea0e4 = storage.FileType;
|
||||||
storage.fileWebp#1081464c = storage.FileType;
|
storage.fileWebp#1081464c = storage.FileType;
|
||||||
userEmpty#d3bc4b7a id:long = User;
|
userEmpty#d3bc4b7a id:long = User;
|
||||||
user#3ff6ecb0 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
user#3ff6ecb0 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||||
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||||
userStatusEmpty#9d05049 = UserStatus;
|
userStatusEmpty#9d05049 = UserStatus;
|
||||||
@ -74,12 +74,12 @@ userStatusRecently#e26f42f1 = UserStatus;
|
|||||||
userStatusLastWeek#7bf09fc = UserStatus;
|
userStatusLastWeek#7bf09fc = UserStatus;
|
||||||
userStatusLastMonth#77ebc742 = UserStatus;
|
userStatusLastMonth#77ebc742 = UserStatus;
|
||||||
chatEmpty#29562865 id:long = Chat;
|
chatEmpty#29562865 id:long = Chat;
|
||||||
chat#41cbf256 flags:# creator:flags.0?true kicked:flags.1?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#8261ac61 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 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 = Chat;
|
channel#8261ac61 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 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 = 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#d18ee226 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?Vector<string> = ChatFull;
|
chatFull#d18ee226 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?Vector<string> = ChatFull;
|
||||||
channelFull#e13c3d20 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 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?Vector<string> = ChatFull;
|
channelFull#ea68a619 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:flags.31?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?Vector<string> = 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;
|
||||||
@ -133,6 +133,8 @@ messageActionSetMessagesTTL#aa1afbfd period:int = MessageAction;
|
|||||||
messageActionGroupCallScheduled#b3a07661 call:InputGroupCall schedule_date:int = MessageAction;
|
messageActionGroupCallScheduled#b3a07661 call:InputGroupCall schedule_date:int = MessageAction;
|
||||||
messageActionSetChatTheme#aa786345 emoticon:string = MessageAction;
|
messageActionSetChatTheme#aa786345 emoticon:string = MessageAction;
|
||||||
messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
|
messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
|
||||||
|
messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction;
|
||||||
|
messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
|
||||||
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
||||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||||
photoEmpty#2331b22d id:long = Photo;
|
photoEmpty#2331b22d id:long = Photo;
|
||||||
@ -153,8 +155,8 @@ inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
|
|||||||
inputNotifyUsers#193b4417 = InputNotifyPeer;
|
inputNotifyUsers#193b4417 = InputNotifyPeer;
|
||||||
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
||||||
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
|
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
|
||||||
inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = InputPeerNotifySettings;
|
inputPeerNotifySettings#df1f002b flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?NotificationSound = InputPeerNotifySettings;
|
||||||
peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = PeerNotifySettings;
|
peerNotifySettings#a83b0426 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int ios_sound:flags.3?NotificationSound android_sound:flags.4?NotificationSound other_sound:flags.5?NotificationSound = PeerNotifySettings;
|
||||||
peerSettings#a518110d flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int = PeerSettings;
|
peerSettings#a518110d flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int = PeerSettings;
|
||||||
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
|
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
|
||||||
wallPaperNoFile#e0804116 id:long flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper;
|
wallPaperNoFile#e0804116 id:long flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper;
|
||||||
@ -168,7 +170,7 @@ inputReportReasonGeoIrrelevant#dbd4feed = ReportReason;
|
|||||||
inputReportReasonFake#f5ddd6e7 = ReportReason;
|
inputReportReasonFake#f5ddd6e7 = ReportReason;
|
||||||
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
|
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
|
||||||
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
|
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
|
||||||
userFull#cf366521 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string = UserFull;
|
userFull#8c72ea81 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights = UserFull;
|
||||||
contact#145ade0b user_id:long mutual:Bool = Contact;
|
contact#145ade0b user_id:long mutual:Bool = Contact;
|
||||||
importedContact#c13e3c50 user_id:long client_id:long = ImportedContact;
|
importedContact#c13e3c50 user_id:long client_id:long = ImportedContact;
|
||||||
contactStatus#16d9703b user_id:long status:UserStatus = ContactStatus;
|
contactStatus#16d9703b user_id:long status:UserStatus = ContactStatus;
|
||||||
@ -301,6 +303,10 @@ updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = U
|
|||||||
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
||||||
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
||||||
updateMessageReactions#154798c3 peer:Peer msg_id:int reactions:MessageReactions = Update;
|
updateMessageReactions#154798c3 peer:Peer msg_id:int reactions:MessageReactions = Update;
|
||||||
|
updateAttachMenuBots#17b7a20b = Update;
|
||||||
|
updateWebViewResultSent#1592b79d query_id:long = Update;
|
||||||
|
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
||||||
|
updateSavedRingtones#74d8be99 = 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;
|
||||||
@ -442,7 +448,7 @@ stickerSet#d7df217a flags:# archived:flags.1?true official:flags.2?true masks:fl
|
|||||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> 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;
|
||||||
botInfo#1b74b335 user_id:long description:string commands:Vector<BotCommand> = BotInfo;
|
botInfo#e4169b5d user_id:long description:string commands:Vector<BotCommand> menu_button:BotMenuButton = BotInfo;
|
||||||
keyboardButton#a2fa4880 text:string = KeyboardButton;
|
keyboardButton#a2fa4880 text:string = KeyboardButton;
|
||||||
keyboardButtonUrl#258aff05 text:string url:string = KeyboardButton;
|
keyboardButtonUrl#258aff05 text:string url:string = KeyboardButton;
|
||||||
keyboardButtonCallback#35bbdb6b flags:# requires_password:flags.0?true text:string data:bytes = KeyboardButton;
|
keyboardButtonCallback#35bbdb6b flags:# requires_password:flags.0?true text:string data:bytes = KeyboardButton;
|
||||||
@ -456,6 +462,8 @@ inputKeyboardButtonUrlAuth#d02e7fd4 flags:# request_write_access:flags.0?true te
|
|||||||
keyboardButtonRequestPoll#bbc7515d flags:# quiz:flags.0?Bool text:string = KeyboardButton;
|
keyboardButtonRequestPoll#bbc7515d flags:# quiz:flags.0?Bool text:string = KeyboardButton;
|
||||||
inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = KeyboardButton;
|
inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = KeyboardButton;
|
||||||
keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
|
keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
|
||||||
|
keyboardButtonWebView#13767230 text:string url:string = KeyboardButton;
|
||||||
|
keyboardButtonSimpleWebView#a0c0505c text:string url:string = 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;
|
||||||
@ -957,6 +965,26 @@ messagePeerReaction#51b67eff flags:# big:flags.0?true unread:flags.1?true peer_i
|
|||||||
groupCallStreamChannel#80eb48af channel:int scale:int last_timestamp_ms:long = GroupCallStreamChannel;
|
groupCallStreamChannel#80eb48af channel:int scale:int last_timestamp_ms:long = GroupCallStreamChannel;
|
||||||
phone.groupCallStreamChannels#d0e482b2 channels:Vector<GroupCallStreamChannel> = phone.GroupCallStreamChannels;
|
phone.groupCallStreamChannels#d0e482b2 channels:Vector<GroupCallStreamChannel> = phone.GroupCallStreamChannels;
|
||||||
phone.groupCallStreamRtmpUrl#2dbf3432 url:string key:string = phone.GroupCallStreamRtmpUrl;
|
phone.groupCallStreamRtmpUrl#2dbf3432 url:string key:string = phone.GroupCallStreamRtmpUrl;
|
||||||
|
attachMenuBotIconColor#4576f3f0 name:string color:int = AttachMenuBotIconColor;
|
||||||
|
attachMenuBotIcon#b2a7386b flags:# name:string icon:Document colors:flags.0?Vector<AttachMenuBotIconColor> = AttachMenuBotIcon;
|
||||||
|
attachMenuBot#e93cb772 flags:# inactive:flags.0?true bot_id:long short_name:string icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
|
||||||
|
attachMenuBotsNotModified#f1d88a5c = AttachMenuBots;
|
||||||
|
attachMenuBots#3c4301c0 hash:long bots:Vector<AttachMenuBot> users:Vector<User> = AttachMenuBots;
|
||||||
|
attachMenuBotsBot#93bf667f bot:AttachMenuBot users:Vector<User> = AttachMenuBotsBot;
|
||||||
|
webViewResultUrl#c14557c query_id:long url:string = WebViewResult;
|
||||||
|
simpleWebViewResultUrl#882f76bb url:string = SimpleWebViewResult;
|
||||||
|
webViewMessageSent#c94511c flags:# msg_id:flags.0?InputBotInlineMessageID = WebViewMessageSent;
|
||||||
|
botMenuButtonDefault#7533a588 = BotMenuButton;
|
||||||
|
botMenuButtonCommands#4258c205 = BotMenuButton;
|
||||||
|
botMenuButton#c7b57ce6 text:string url:string = BotMenuButton;
|
||||||
|
account.savedRingtonesNotModified#fbf6e8b1 = account.SavedRingtones;
|
||||||
|
account.savedRingtones#c1e92cc5 hash:long ringtones:Vector<Document> = account.SavedRingtones;
|
||||||
|
notificationSoundDefault#97e8bebe = NotificationSound;
|
||||||
|
notificationSoundNone#6f0c34df = NotificationSound;
|
||||||
|
notificationSoundLocal#830b9ae4 title:string data:string = NotificationSound;
|
||||||
|
notificationSoundRingtone#ff6c8049 id:long = NotificationSound;
|
||||||
|
account.savedRingtone#b7263f6d = account.SavedRingtone;
|
||||||
|
account.savedRingtoneConverted#1f307eb7 document:Document = account.SavedRingtone;
|
||||||
---functions---
|
---functions---
|
||||||
initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
|
initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
|
||||||
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
||||||
@ -1110,6 +1138,14 @@ messages.getMessageReactionsList#e0ee6b77 flags:# peer:InputPeer id:int reaction
|
|||||||
messages.setChatAvailableReactions#14050ea6 peer:InputPeer available_reactions:Vector<string> = Updates;
|
messages.setChatAvailableReactions#14050ea6 peer:InputPeer available_reactions:Vector<string> = Updates;
|
||||||
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
||||||
messages.setDefaultReaction#d960c4d4 reaction:string = Bool;
|
messages.setDefaultReaction#d960c4d4 reaction:string = Bool;
|
||||||
|
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||||
|
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||||
|
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
|
||||||
|
messages.requestWebView#fa04dff flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON reply_to_msg_id:flags.0?int = WebViewResult;
|
||||||
|
messages.prolongWebView#d22ad148 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int = Bool;
|
||||||
|
messages.requestSimpleWebView#6abb2f73 flags:# bot:InputUser url:string theme_params:flags.0?DataJSON = SimpleWebViewResult;
|
||||||
|
messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent;
|
||||||
|
messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates;
|
||||||
updates.getState#edd4882a = updates.State;
|
updates.getState#edd4882a = updates.State;
|
||||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||||
updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
|
updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
|
||||||
|
|||||||
@ -222,5 +222,13 @@
|
|||||||
"help.getAppConfig",
|
"help.getAppConfig",
|
||||||
"stats.getBroadcastStats",
|
"stats.getBroadcastStats",
|
||||||
"stats.getMegagroupStats",
|
"stats.getMegagroupStats",
|
||||||
"stats.loadAsyncGraph"
|
"stats.loadAsyncGraph",
|
||||||
|
"messages.getAttachMenuBots",
|
||||||
|
"messages.getAttachMenuBot",
|
||||||
|
"messages.toggleBotInAttachMenu",
|
||||||
|
"messages.requestWebView",
|
||||||
|
"messages.prolongWebView",
|
||||||
|
"messages.requestSimpleWebView",
|
||||||
|
"messages.sendWebViewResultMessage",
|
||||||
|
"messages.sendWebViewData"
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,33 +1,3 @@
|
|||||||
///////////////////////////////
|
|
||||||
/////////////////// Layer cons
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
//invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
|
|
||||||
//invokeAfterMsgs#3dc4b4f0 msg_ids:Vector<long> query:!X = X;
|
|
||||||
//invokeWithLayer1#53835315 query:!X = X;
|
|
||||||
//invokeWithLayer2#289dd1f6 query:!X = X;
|
|
||||||
//invokeWithLayer3#b7475268 query:!X = X;
|
|
||||||
//invokeWithLayer4#dea0d430 query:!X = X;
|
|
||||||
//invokeWithLayer5#417a57ae query:!X = X;
|
|
||||||
//invokeWithLayer6#3a64d54d query:!X = X;
|
|
||||||
//invokeWithLayer7#a5be56d3 query:!X = X;
|
|
||||||
//invokeWithLayer8#e9abd9fd query:!X = X;
|
|
||||||
//invokeWithLayer9#76715a63 query:!X = X;
|
|
||||||
//invokeWithLayer10#39620c41 query:!X = X;
|
|
||||||
//invokeWithLayer11#a6b88fdf query:!X = X;
|
|
||||||
//invokeWithLayer12#dda60d3c query:!X = X;
|
|
||||||
//invokeWithLayer13#427c8ea2 query:!X = X;
|
|
||||||
//invokeWithLayer14#2b9b08fa query:!X = X;
|
|
||||||
//invokeWithLayer15#b4418b64 query:!X = X;
|
|
||||||
//invokeWithLayer16#cf5f0987 query:!X = X;
|
|
||||||
//invokeWithLayer17#50858a19 query:!X = X;
|
|
||||||
//invokeWithLayer18#1c900537 query:!X = X;
|
|
||||||
//invokeWithLayer#da9b0d0d layer:int query:!X = X; // after 18 layer
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
///////// Main application API
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
boolFalse#bc799737 = Bool;
|
boolFalse#bc799737 = Bool;
|
||||||
boolTrue#997275b5 = Bool;
|
boolTrue#997275b5 = Bool;
|
||||||
|
|
||||||
@ -110,7 +80,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType;
|
|||||||
storage.fileWebp#1081464c = storage.FileType;
|
storage.fileWebp#1081464c = storage.FileType;
|
||||||
|
|
||||||
userEmpty#d3bc4b7a id:long = User;
|
userEmpty#d3bc4b7a id:long = User;
|
||||||
user#3ff6ecb0 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
user#3ff6ecb0 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||||
|
|
||||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||||
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||||
@ -123,13 +93,13 @@ userStatusLastWeek#7bf09fc = UserStatus;
|
|||||||
userStatusLastMonth#77ebc742 = UserStatus;
|
userStatusLastMonth#77ebc742 = UserStatus;
|
||||||
|
|
||||||
chatEmpty#29562865 id:long = Chat;
|
chatEmpty#29562865 id:long = Chat;
|
||||||
chat#41cbf256 flags:# creator:flags.0?true kicked:flags.1?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#8261ac61 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 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 = Chat;
|
channel#8261ac61 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 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 = 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#d18ee226 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?Vector<string> = ChatFull;
|
chatFull#d18ee226 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?Vector<string> = ChatFull;
|
||||||
channelFull#e13c3d20 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 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?Vector<string> = ChatFull;
|
channelFull#ea68a619 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:flags.31?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?Vector<string> = 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;
|
||||||
@ -189,6 +159,8 @@ messageActionSetMessagesTTL#aa1afbfd period:int = MessageAction;
|
|||||||
messageActionGroupCallScheduled#b3a07661 call:InputGroupCall schedule_date:int = MessageAction;
|
messageActionGroupCallScheduled#b3a07661 call:InputGroupCall schedule_date:int = MessageAction;
|
||||||
messageActionSetChatTheme#aa786345 emoticon:string = MessageAction;
|
messageActionSetChatTheme#aa786345 emoticon:string = MessageAction;
|
||||||
messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
|
messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
|
||||||
|
messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction;
|
||||||
|
messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
|
||||||
|
|
||||||
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
||||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||||
@ -218,9 +190,9 @@ inputNotifyUsers#193b4417 = InputNotifyPeer;
|
|||||||
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
||||||
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
|
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
|
||||||
|
|
||||||
inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = InputPeerNotifySettings;
|
inputPeerNotifySettings#df1f002b flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?NotificationSound = InputPeerNotifySettings;
|
||||||
|
|
||||||
peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = PeerNotifySettings;
|
peerNotifySettings#a83b0426 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int ios_sound:flags.3?NotificationSound android_sound:flags.4?NotificationSound other_sound:flags.5?NotificationSound = PeerNotifySettings;
|
||||||
|
|
||||||
peerSettings#a518110d flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int = PeerSettings;
|
peerSettings#a518110d flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int = PeerSettings;
|
||||||
|
|
||||||
@ -238,7 +210,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason;
|
|||||||
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
|
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
|
||||||
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
|
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
|
||||||
|
|
||||||
userFull#cf366521 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string = UserFull;
|
userFull#8c72ea81 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights = UserFull;
|
||||||
|
|
||||||
contact#145ade0b user_id:long mutual:Bool = Contact;
|
contact#145ade0b user_id:long mutual:Bool = Contact;
|
||||||
|
|
||||||
@ -384,6 +356,10 @@ updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = U
|
|||||||
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
||||||
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
||||||
updateMessageReactions#154798c3 peer:Peer msg_id:int reactions:MessageReactions = Update;
|
updateMessageReactions#154798c3 peer:Peer msg_id:int reactions:MessageReactions = Update;
|
||||||
|
updateAttachMenuBots#17b7a20b = Update;
|
||||||
|
updateWebViewResultSent#1592b79d query_id:long = Update;
|
||||||
|
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
||||||
|
updateSavedRingtones#74d8be99 = 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;
|
||||||
|
|
||||||
@ -575,7 +551,7 @@ messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
|
|||||||
|
|
||||||
botCommand#c27ac8c7 command:string description:string = BotCommand;
|
botCommand#c27ac8c7 command:string description:string = BotCommand;
|
||||||
|
|
||||||
botInfo#1b74b335 user_id:long description:string commands:Vector<BotCommand> = BotInfo;
|
botInfo#e4169b5d user_id:long description:string commands:Vector<BotCommand> menu_button:BotMenuButton = BotInfo;
|
||||||
|
|
||||||
keyboardButton#a2fa4880 text:string = KeyboardButton;
|
keyboardButton#a2fa4880 text:string = KeyboardButton;
|
||||||
keyboardButtonUrl#258aff05 text:string url:string = KeyboardButton;
|
keyboardButtonUrl#258aff05 text:string url:string = KeyboardButton;
|
||||||
@ -590,6 +566,8 @@ inputKeyboardButtonUrlAuth#d02e7fd4 flags:# request_write_access:flags.0?true te
|
|||||||
keyboardButtonRequestPoll#bbc7515d flags:# quiz:flags.0?Bool text:string = KeyboardButton;
|
keyboardButtonRequestPoll#bbc7515d flags:# quiz:flags.0?Bool text:string = KeyboardButton;
|
||||||
inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = KeyboardButton;
|
inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = KeyboardButton;
|
||||||
keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
|
keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
|
||||||
|
keyboardButtonWebView#13767230 text:string url:string = KeyboardButton;
|
||||||
|
keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton;
|
||||||
|
|
||||||
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
|
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
|
||||||
|
|
||||||
@ -1329,6 +1307,38 @@ phone.groupCallStreamChannels#d0e482b2 channels:Vector<GroupCallStreamChannel> =
|
|||||||
|
|
||||||
phone.groupCallStreamRtmpUrl#2dbf3432 url:string key:string = phone.GroupCallStreamRtmpUrl;
|
phone.groupCallStreamRtmpUrl#2dbf3432 url:string key:string = phone.GroupCallStreamRtmpUrl;
|
||||||
|
|
||||||
|
attachMenuBotIconColor#4576f3f0 name:string color:int = AttachMenuBotIconColor;
|
||||||
|
|
||||||
|
attachMenuBotIcon#b2a7386b flags:# name:string icon:Document colors:flags.0?Vector<AttachMenuBotIconColor> = AttachMenuBotIcon;
|
||||||
|
|
||||||
|
attachMenuBot#e93cb772 flags:# inactive:flags.0?true bot_id:long short_name:string icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
|
||||||
|
|
||||||
|
attachMenuBotsNotModified#f1d88a5c = AttachMenuBots;
|
||||||
|
attachMenuBots#3c4301c0 hash:long bots:Vector<AttachMenuBot> users:Vector<User> = AttachMenuBots;
|
||||||
|
|
||||||
|
attachMenuBotsBot#93bf667f bot:AttachMenuBot users:Vector<User> = AttachMenuBotsBot;
|
||||||
|
|
||||||
|
webViewResultUrl#c14557c query_id:long url:string = WebViewResult;
|
||||||
|
|
||||||
|
simpleWebViewResultUrl#882f76bb url:string = SimpleWebViewResult;
|
||||||
|
|
||||||
|
webViewMessageSent#c94511c flags:# msg_id:flags.0?InputBotInlineMessageID = WebViewMessageSent;
|
||||||
|
|
||||||
|
botMenuButtonDefault#7533a588 = BotMenuButton;
|
||||||
|
botMenuButtonCommands#4258c205 = BotMenuButton;
|
||||||
|
botMenuButton#c7b57ce6 text:string url:string = BotMenuButton;
|
||||||
|
|
||||||
|
account.savedRingtonesNotModified#fbf6e8b1 = account.SavedRingtones;
|
||||||
|
account.savedRingtones#c1e92cc5 hash:long ringtones:Vector<Document> = account.SavedRingtones;
|
||||||
|
|
||||||
|
notificationSoundDefault#97e8bebe = NotificationSound;
|
||||||
|
notificationSoundNone#6f0c34df = NotificationSound;
|
||||||
|
notificationSoundLocal#830b9ae4 title:string data:string = NotificationSound;
|
||||||
|
notificationSoundRingtone#ff6c8049 id:long = NotificationSound;
|
||||||
|
|
||||||
|
account.savedRingtone#b7263f6d = account.SavedRingtone;
|
||||||
|
account.savedRingtoneConverted#1f307eb7 document:Document = account.SavedRingtone;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||||
@ -1432,6 +1442,9 @@ account.declinePasswordReset#4c9409f6 = Bool;
|
|||||||
account.getChatThemes#d638de89 hash:long = account.Themes;
|
account.getChatThemes#d638de89 hash:long = account.Themes;
|
||||||
account.setAuthorizationTTL#bf899aa0 authorization_ttl_days:int = Bool;
|
account.setAuthorizationTTL#bf899aa0 authorization_ttl_days:int = Bool;
|
||||||
account.changeAuthorizationSettings#40f48462 flags:# hash:long encrypted_requests_disabled:flags.0?Bool call_requests_disabled:flags.1?Bool = Bool;
|
account.changeAuthorizationSettings#40f48462 flags:# hash:long encrypted_requests_disabled:flags.0?Bool call_requests_disabled:flags.1?Bool = Bool;
|
||||||
|
account.getSavedRingtones#e1902288 hash:long = account.SavedRingtones;
|
||||||
|
account.saveRingtone#3dea5b03 id:InputDocument unsave:Bool = account.SavedRingtone;
|
||||||
|
account.uploadRingtone#831a83a2 file:InputFile file_name:string mime_type:string = Document;
|
||||||
|
|
||||||
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;
|
||||||
@ -1618,6 +1631,14 @@ messages.translateText#24ce6dee flags:# peer:flags.0?InputPeer msg_id:flags.0?in
|
|||||||
messages.getUnreadReactions#e85bae1a peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
messages.getUnreadReactions#e85bae1a peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||||
messages.readReactions#82e251d7 peer:InputPeer = messages.AffectedHistory;
|
messages.readReactions#82e251d7 peer:InputPeer = messages.AffectedHistory;
|
||||||
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
|
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
|
||||||
|
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||||
|
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||||
|
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
|
||||||
|
messages.requestWebView#fa04dff flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON reply_to_msg_id:flags.0?int = WebViewResult;
|
||||||
|
messages.prolongWebView#d22ad148 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int = Bool;
|
||||||
|
messages.requestSimpleWebView#6abb2f73 flags:# bot:InputUser url:string theme_params:flags.0?DataJSON = SimpleWebViewResult;
|
||||||
|
messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent;
|
||||||
|
messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates;
|
||||||
|
|
||||||
updates.getState#edd4882a = updates.State;
|
updates.getState#edd4882a = updates.State;
|
||||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||||
@ -1685,7 +1706,7 @@ channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_r
|
|||||||
channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector<InputUser> max_id:long min_id:long limit:int = channels.AdminLogResults;
|
channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector<InputUser> max_id:long min_id:long limit:int = channels.AdminLogResults;
|
||||||
channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool;
|
channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool;
|
||||||
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
||||||
channels.deleteHistory#af369d42 channel:InputChannel max_id:int = Bool;
|
channels.deleteHistory#9baa9647 flags:# for_everyone:flags.0?true channel:InputChannel max_id:int = Updates;
|
||||||
channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates;
|
channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.getLeftChannels#8341ecc0 offset:int = messages.Chats;
|
channels.getLeftChannels#8341ecc0 offset:int = messages.Chats;
|
||||||
channels.getGroupsForDiscussion#f5dad378 = messages.Chats;
|
channels.getGroupsForDiscussion#f5dad378 = messages.Chats;
|
||||||
@ -1705,6 +1726,10 @@ bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
|||||||
bots.setBotCommands#517165a scope:BotCommandScope lang_code:string commands:Vector<BotCommand> = Bool;
|
bots.setBotCommands#517165a scope:BotCommandScope lang_code:string commands:Vector<BotCommand> = Bool;
|
||||||
bots.resetBotCommands#3d8de0f9 scope:BotCommandScope lang_code:string = Bool;
|
bots.resetBotCommands#3d8de0f9 scope:BotCommandScope lang_code:string = Bool;
|
||||||
bots.getBotCommands#e34c0dd6 scope:BotCommandScope lang_code:string = Vector<BotCommand>;
|
bots.getBotCommands#e34c0dd6 scope:BotCommandScope lang_code:string = Vector<BotCommand>;
|
||||||
|
bots.setBotMenuButton#4504d54f user_id:InputUser button:BotMenuButton = Bool;
|
||||||
|
bots.getBotMenuButton#9c60eb28 user_id:InputUser = BotMenuButton;
|
||||||
|
bots.setBotBroadcastDefaultAdminRights#788464e1 admin_rights:ChatAdminRights = Bool;
|
||||||
|
bots.setBotGroupDefaultAdminRights#925ec9ea admin_rights:ChatAdminRights = Bool;
|
||||||
|
|
||||||
payments.getPaymentForm#8a333c8d flags:# peer:InputPeer msg_id:int theme_params:flags.0?DataJSON = payments.PaymentForm;
|
payments.getPaymentForm#8a333c8d flags:# peer:InputPeer msg_id:int theme_params:flags.0?DataJSON = payments.PaymentForm;
|
||||||
payments.getPaymentReceipt#2478d1cc peer:InputPeer msg_id:int = payments.PaymentReceipt;
|
payments.getPaymentReceipt#2478d1cc peer:InputPeer msg_id:int = payments.PaymentReceipt;
|
||||||
@ -1768,4 +1793,3 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
|
|||||||
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||||
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
||||||
|
|
||||||
// LAYER 139
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
// Not sure what they are for.
|
// Not sure what they are for.
|
||||||
const RAW_TYPES = new Set(['Bool', 'X'])
|
const RAW_TYPES = new Set(['Bool', 'X'])
|
||||||
|
const FLAGS = ['flags', 'flags2'];
|
||||||
|
|
||||||
module.exports = ({ types, constructors, functions }) => {
|
module.exports = ({ types, constructors, functions }) => {
|
||||||
function groupByKey(collection, key) {
|
function groupByKey(collection, key) {
|
||||||
@ -32,7 +33,7 @@ module.exports = ({ types, constructors, functions }) => {
|
|||||||
return `export class ${upperFirst(name)} extends VirtualClass<void> {};`
|
return `export class ${upperFirst(name)} extends VirtualClass<void> {};`
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasRequiredArgs = argKeys.some((argName) => argName !== 'flags' && !argsConfig[argName].isFlag)
|
let hasRequiredArgs = argKeys.some((argName) => !FLAGS.includes(argName) && !argsConfig[argName].isFlag)
|
||||||
|
|
||||||
return `
|
return `
|
||||||
export class ${upperFirst(name)} extends VirtualClass<{
|
export class ${upperFirst(name)} extends VirtualClass<{
|
||||||
@ -61,7 +62,7 @@ ${indent}};`.trim()
|
|||||||
return `export class ${upperFirst(name)} extends Request<void, ${renderedResult}> {};`
|
return `export class ${upperFirst(name)} extends Request<void, ${renderedResult}> {};`
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasRequiredArgs = argKeys.some((argName) => argName !== 'flags' && !argsConfig[argName].isFlag)
|
let hasRequiredArgs = argKeys.some((argName) => !FLAGS.includes(argName) && !argsConfig[argName].isFlag)
|
||||||
|
|
||||||
return `
|
return `
|
||||||
export class ${upperFirst(name)} extends Request<Partial<{
|
export class ${upperFirst(name)} extends Request<Partial<{
|
||||||
@ -95,7 +96,7 @@ ${indent}};`.trim()
|
|||||||
|
|
||||||
const valueType = renderValueType(type, isVector, !skipConstructorId)
|
const valueType = renderValueType(type, isVector, !skipConstructorId)
|
||||||
|
|
||||||
return `${argName === 'flags' ? '// ' : ''}${argName}${isFlag ? '?' : ''}: ${valueType}`
|
return `${FLAGS.includes(argName) ? '// ' : ''}${argName}${isFlag ? '?' : ''}: ${valueType}`
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderValueType(type, isVector, isTlType) {
|
function renderValueType(type, isVector, isTlType) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -51,6 +51,21 @@
|
|||||||
.icon-volume-3:before {
|
.icon-volume-3:before {
|
||||||
content: "\e991";
|
content: "\e991";
|
||||||
}
|
}
|
||||||
|
.icon-reactions:before {
|
||||||
|
content: "\e99a";
|
||||||
|
}
|
||||||
|
.icon-reaction-filled:before {
|
||||||
|
content: "\e99b";
|
||||||
|
}
|
||||||
|
.icon-webapp:before {
|
||||||
|
content: "\e993";
|
||||||
|
}
|
||||||
|
.icon-reload:before {
|
||||||
|
content: "\e994";
|
||||||
|
}
|
||||||
|
.icon-install:before {
|
||||||
|
content: "\e999";
|
||||||
|
}
|
||||||
.icon-favorite-filled:before {
|
.icon-favorite-filled:before {
|
||||||
content: "\e998";
|
content: "\e998";
|
||||||
}
|
}
|
||||||
@ -66,12 +81,6 @@
|
|||||||
.icon-copy-media:before {
|
.icon-copy-media:before {
|
||||||
content: "\e995";
|
content: "\e995";
|
||||||
}
|
}
|
||||||
.icon-reaction-filled:before {
|
|
||||||
content: "\e994";
|
|
||||||
}
|
|
||||||
.icon-reactions:before {
|
|
||||||
content: "\e993";
|
|
||||||
}
|
|
||||||
.icon-sidebar:before {
|
.icon-sidebar:before {
|
||||||
content: "\e992";
|
content: "\e992";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,9 +30,11 @@ export const processDeepLink = (url: string) => {
|
|||||||
switch (method) {
|
switch (method) {
|
||||||
case 'resolve': {
|
case 'resolve': {
|
||||||
const {
|
const {
|
||||||
domain, phone, post, comment, voicechat, livestream, start,
|
domain, phone, post, comment, voicechat, livestream, start, startattach, attach,
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
|
const startAttach = params.hasOwnProperty('startattach') && !startattach ? true : startattach;
|
||||||
|
|
||||||
if (domain !== 'telegrampassport') {
|
if (domain !== 'telegrampassport') {
|
||||||
if (params.hasOwnProperty('voicechat') || params.hasOwnProperty('livestream')) {
|
if (params.hasOwnProperty('voicechat') || params.hasOwnProperty('livestream')) {
|
||||||
joinVoiceChatByLink({
|
joinVoiceChatByLink({
|
||||||
@ -40,13 +42,15 @@ export const processDeepLink = (url: string) => {
|
|||||||
inviteHash: voicechat || livestream,
|
inviteHash: voicechat || livestream,
|
||||||
});
|
});
|
||||||
} else if (phone) {
|
} else if (phone) {
|
||||||
openChatByPhoneNumber({ phone });
|
openChatByPhoneNumber({ phone, startAttach, attach });
|
||||||
} else {
|
} else {
|
||||||
openChatByUsername({
|
openChatByUsername({
|
||||||
username: domain,
|
username: domain,
|
||||||
messageId: Number(post),
|
messageId: Number(post),
|
||||||
commentId: Number(comment),
|
commentId: Number(comment),
|
||||||
startParam: start,
|
startParam: start,
|
||||||
|
startAttach,
|
||||||
|
attach,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import { webpToPng } from './webpToPng';
|
|||||||
const asCacheApiType = {
|
const asCacheApiType = {
|
||||||
[ApiMediaFormat.BlobUrl]: cacheApi.Type.Blob,
|
[ApiMediaFormat.BlobUrl]: cacheApi.Type.Blob,
|
||||||
[ApiMediaFormat.Lottie]: cacheApi.Type.Blob,
|
[ApiMediaFormat.Lottie]: cacheApi.Type.Blob,
|
||||||
|
[ApiMediaFormat.Text]: cacheApi.Type.Text,
|
||||||
[ApiMediaFormat.Progressive]: undefined,
|
[ApiMediaFormat.Progressive]: undefined,
|
||||||
[ApiMediaFormat.Stream]: undefined,
|
[ApiMediaFormat.Stream]: undefined,
|
||||||
};
|
};
|
||||||
|
|||||||
39
src/util/themeStyle.ts
Normal file
39
src/util/themeStyle.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { ApiThemeParameters } from '../api/types';
|
||||||
|
|
||||||
|
export function extractCurrentThemeParams(): ApiThemeParameters {
|
||||||
|
const style = getComputedStyle(document.documentElement);
|
||||||
|
const backgroundColor = getPropertyWrapped(style, '--color-background');
|
||||||
|
const textColor = getPropertyWrapped(style, '--color-text');
|
||||||
|
const buttonColor = getPropertyWrapped(style, '--color-primary');
|
||||||
|
const buttonTextColor = getPropertyWrapped(style, '--color-white');
|
||||||
|
const linkColor = getPropertyWrapped(style, '--color-links');
|
||||||
|
const hintColor = getPropertyWrapped(style, '--color-text-secondary');
|
||||||
|
return {
|
||||||
|
bg_color: backgroundColor,
|
||||||
|
text_color: textColor,
|
||||||
|
hint_color: hintColor,
|
||||||
|
link_color: linkColor,
|
||||||
|
button_color: buttonColor,
|
||||||
|
button_text_color: buttonTextColor,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateHexColor(color: string) {
|
||||||
|
return /^#[0-9A-F]{6}$/i.test(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPropertyWrapped(style: CSSStyleDeclaration, property: string) {
|
||||||
|
const value = style.getPropertyValue(property);
|
||||||
|
return wrapColor(value.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapColor(color: string) {
|
||||||
|
if (validateHexColor(color)) return color;
|
||||||
|
return `#${color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/)!
|
||||||
|
.slice(1)
|
||||||
|
.map((n: string, i: number) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n))
|
||||||
|
.toString(16)
|
||||||
|
.padStart(2, '0')
|
||||||
|
.replace('NaN', ''))
|
||||||
|
.join('')}`;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user