Message: Introduce Invoice Media (#2093)
This commit is contained in:
parent
58413c6c61
commit
6e8b920525
@ -1,7 +1,4 @@
|
|||||||
import { Api as GramJs } from '../../../lib/gramjs';
|
import { Api as GramJs } from '../../../lib/gramjs';
|
||||||
import {
|
|
||||||
ApiMessageEntityTypes,
|
|
||||||
} from '../../types';
|
|
||||||
import type {
|
import type {
|
||||||
ApiMessage,
|
ApiMessage,
|
||||||
ApiMessageForwardInfo,
|
ApiMessageForwardInfo,
|
||||||
@ -36,6 +33,10 @@ import type {
|
|||||||
PhoneCallAction,
|
PhoneCallAction,
|
||||||
ApiWebDocument,
|
ApiWebDocument,
|
||||||
ApiMessageEntityDefault,
|
ApiMessageEntityDefault,
|
||||||
|
ApiMessageExtendedMediaPreview,
|
||||||
|
} from '../../types';
|
||||||
|
import {
|
||||||
|
ApiMessageEntityTypes,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -161,16 +162,21 @@ export function buildApiMessageWithChatId(chatId: string, mtpMessage: UniversalM
|
|||||||
content.action = action;
|
content.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isInvoiceMedia = mtpMessage.media instanceof GramJs.MessageMediaInvoice
|
||||||
|
&& Boolean(mtpMessage.media.extendedMedia);
|
||||||
|
|
||||||
const { replyToMsgId, replyToTopId, replyToPeerId } = mtpMessage.replyTo || {};
|
const { replyToMsgId, replyToTopId, replyToPeerId } = mtpMessage.replyTo || {};
|
||||||
const isEdited = mtpMessage.editDate && !mtpMessage.editHide;
|
const isEdited = mtpMessage.editDate && !mtpMessage.editHide;
|
||||||
const {
|
const {
|
||||||
inlineButtons, keyboardButtons, keyboardPlaceholder, isKeyboardSingleUse,
|
inlineButtons, keyboardButtons, keyboardPlaceholder, isKeyboardSingleUse,
|
||||||
} = buildReplyButtons(mtpMessage) || {};
|
} = buildReplyButtons(mtpMessage, isInvoiceMedia) || {};
|
||||||
const forwardInfo = mtpMessage.fwdFrom && buildApiMessageForwardInfo(mtpMessage.fwdFrom, isChatWithSelf);
|
const forwardInfo = mtpMessage.fwdFrom && buildApiMessageForwardInfo(mtpMessage.fwdFrom, isChatWithSelf);
|
||||||
const { replies, mediaUnread: isMediaUnread, postAuthor } = mtpMessage;
|
const { replies, mediaUnread: isMediaUnread, postAuthor } = mtpMessage;
|
||||||
const groupedId = mtpMessage.groupedId && String(mtpMessage.groupedId);
|
const groupedId = mtpMessage.groupedId && String(mtpMessage.groupedId);
|
||||||
const isInAlbum = Boolean(groupedId) && !(content.document || content.audio || content.sticker);
|
const isInAlbum = Boolean(groupedId) && !(content.document || content.audio || content.sticker);
|
||||||
const shouldHideKeyboardButtons = mtpMessage.replyMarkup instanceof GramJs.ReplyKeyboardHide;
|
const shouldHideKeyboardButtons = mtpMessage.replyMarkup instanceof GramJs.ReplyKeyboardHide;
|
||||||
|
const isProtected = mtpMessage.noforwards || isInvoiceMedia;
|
||||||
|
const isForwardingAllowed = !mtpMessage.noforwards;
|
||||||
const emojiOnlyCount = content.text && parseEmojiOnlyString(content.text.text);
|
const emojiOnlyCount = content.text && parseEmojiOnlyString(content.text.text);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -205,7 +211,8 @@ export function buildApiMessageWithChatId(chatId: string, mtpMessage: UniversalM
|
|||||||
...(mtpMessage.viaBotId && { viaBotId: buildApiPeerId(mtpMessage.viaBotId, 'user') }),
|
...(mtpMessage.viaBotId && { viaBotId: buildApiPeerId(mtpMessage.viaBotId, 'user') }),
|
||||||
...(replies?.comments && { threadInfo: buildThreadInfo(replies, mtpMessage.id, chatId) }),
|
...(replies?.comments && { threadInfo: buildThreadInfo(replies, mtpMessage.id, chatId) }),
|
||||||
...(postAuthor && { adminTitle: postAuthor }),
|
...(postAuthor && { adminTitle: postAuthor }),
|
||||||
...(mtpMessage.noforwards && { isProtected: true }),
|
isProtected,
|
||||||
|
isForwardingAllowed,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,6 +343,10 @@ export function buildMessageMediaContent(media: GramJs.TypeMessageMedia): ApiMes
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('extendedMedia' in media && media.extendedMedia instanceof GramJs.MessageExtendedMedia) {
|
||||||
|
return buildMessageMediaContent(media.extendedMedia.media);
|
||||||
|
}
|
||||||
|
|
||||||
const sticker = buildSticker(media);
|
const sticker = buildSticker(media);
|
||||||
if (sticker) return { sticker };
|
if (sticker) return { sticker };
|
||||||
|
|
||||||
@ -748,9 +759,12 @@ export function buildPoll(poll: GramJs.Poll, pollResults: GramJs.PollResults): A
|
|||||||
|
|
||||||
export function buildInvoice(media: GramJs.MessageMediaInvoice): ApiInvoice {
|
export function buildInvoice(media: GramJs.MessageMediaInvoice): ApiInvoice {
|
||||||
const {
|
const {
|
||||||
description: text, title, photo, test, totalAmount, currency, receiptMsgId,
|
description: text, title, photo, test, totalAmount, currency, receiptMsgId, extendedMedia,
|
||||||
} = media;
|
} = media;
|
||||||
|
|
||||||
|
const preview = extendedMedia instanceof GramJs.MessageExtendedMediaPreview
|
||||||
|
? buildApiMessageExtendedMediaPreview(extendedMedia) : undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
text,
|
text,
|
||||||
@ -759,6 +773,7 @@ export function buildInvoice(media: GramJs.MessageMediaInvoice): ApiInvoice {
|
|||||||
amount: Number(totalAmount),
|
amount: Number(totalAmount),
|
||||||
currency,
|
currency,
|
||||||
isTest: test,
|
isTest: test,
|
||||||
|
extendedMedia: preview,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,7 +1022,7 @@ function buildAction(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildReplyButtons(message: UniversalMessage): ApiReplyKeyboard | undefined {
|
function buildReplyButtons(message: UniversalMessage, shouldSkipBuyButton?: boolean): ApiReplyKeyboard | undefined {
|
||||||
const { replyMarkup, media } = message;
|
const { replyMarkup, media } = message;
|
||||||
|
|
||||||
// TODO Move to the proper button inside preview
|
// TODO Move to the proper button inside preview
|
||||||
@ -1033,7 +1048,7 @@ function buildReplyButtons(message: UniversalMessage): ApiReplyKeyboard | undefi
|
|||||||
}
|
}
|
||||||
|
|
||||||
const markup = replyMarkup.rows.map(({ buttons }) => {
|
const markup = replyMarkup.rows.map(({ buttons }) => {
|
||||||
return buttons.map((button): ApiKeyboardButton => {
|
return buttons.map((button): ApiKeyboardButton | undefined => {
|
||||||
const { text } = button;
|
const { text } = button;
|
||||||
|
|
||||||
if (button instanceof GramJs.KeyboardButton) {
|
if (button instanceof GramJs.KeyboardButton) {
|
||||||
@ -1096,6 +1111,7 @@ function buildReplyButtons(message: UniversalMessage): ApiReplyKeyboard | undefi
|
|||||||
receiptMessageId: media.receiptMsgId,
|
receiptMessageId: media.receiptMsgId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (shouldSkipBuyButton) return undefined;
|
||||||
return {
|
return {
|
||||||
type: 'buy',
|
type: 'buy',
|
||||||
text,
|
text,
|
||||||
@ -1155,9 +1171,11 @@ function buildReplyButtons(message: UniversalMessage): ApiReplyKeyboard | undefi
|
|||||||
type: 'unsupported',
|
type: 'unsupported',
|
||||||
text,
|
text,
|
||||||
};
|
};
|
||||||
});
|
}).filter(Boolean);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (markup.every((row) => !row.length)) return undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[replyMarkup instanceof GramJs.ReplyKeyboardMarkup ? 'keyboardButtons' : 'inlineButtons']: markup,
|
[replyMarkup instanceof GramJs.ReplyKeyboardMarkup ? 'keyboardButtons' : 'inlineButtons']: markup,
|
||||||
...(replyMarkup instanceof GramJs.ReplyKeyboardMarkup && {
|
...(replyMarkup instanceof GramJs.ReplyKeyboardMarkup && {
|
||||||
@ -1368,6 +1386,21 @@ function buildUploadingMedia(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildApiMessageExtendedMediaPreview(
|
||||||
|
preview: GramJs.MessageExtendedMediaPreview,
|
||||||
|
): ApiMessageExtendedMediaPreview {
|
||||||
|
const {
|
||||||
|
w, h, thumb, videoDuration,
|
||||||
|
} = preview;
|
||||||
|
|
||||||
|
return {
|
||||||
|
width: w,
|
||||||
|
height: h,
|
||||||
|
duration: videoDuration,
|
||||||
|
thumbnail: thumb ? buildApiThumbnailFromStripped([thumb]) : undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function buildApiWebDocument(document?: GramJs.TypeWebDocument): ApiWebDocument | undefined {
|
export function buildApiWebDocument(document?: GramJs.TypeWebDocument): ApiWebDocument | undefined {
|
||||||
if (!document) return undefined;
|
if (!document) return undefined;
|
||||||
|
|
||||||
|
|||||||
@ -353,7 +353,7 @@ export function isMessageWithMedia(message: GramJs.Message | GramJs.UpdateServic
|
|||||||
media instanceof GramJs.MessageMediaGame
|
media instanceof GramJs.MessageMediaGame
|
||||||
&& (media.game.document instanceof GramJs.Document || media.game.photo instanceof GramJs.Photo)
|
&& (media.game.document instanceof GramJs.Document || media.game.photo instanceof GramJs.Photo)
|
||||||
) || (
|
) || (
|
||||||
media instanceof GramJs.MessageMediaInvoice && media.photo
|
media instanceof GramJs.MessageMediaInvoice && (media.photo || media.extendedMedia)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,37 +26,48 @@ export function resolveMessageApiChatId(mtpMessage: GramJs.TypeMessage) {
|
|||||||
|
|
||||||
export function addMessageToLocalDb(message: GramJs.Message | GramJs.MessageService) {
|
export function addMessageToLocalDb(message: GramJs.Message | GramJs.MessageService) {
|
||||||
const messageFullId = `${resolveMessageApiChatId(message)}-${message.id}`;
|
const messageFullId = `${resolveMessageApiChatId(message)}-${message.id}`;
|
||||||
localDb.messages[messageFullId] = message;
|
|
||||||
|
|
||||||
if (message instanceof GramJs.Message) {
|
let mockMessage = message;
|
||||||
if (message.media instanceof GramJs.MessageMediaDocument
|
if (message instanceof GramJs.Message
|
||||||
&& message.media.document instanceof GramJs.Document
|
&& message.media instanceof GramJs.MessageMediaInvoice
|
||||||
|
&& message.media.extendedMedia instanceof GramJs.MessageExtendedMedia) {
|
||||||
|
mockMessage = new GramJs.Message({
|
||||||
|
...message,
|
||||||
|
media: message.media.extendedMedia.media,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
localDb.messages[messageFullId] = mockMessage;
|
||||||
|
|
||||||
|
if (mockMessage instanceof GramJs.Message) {
|
||||||
|
if (mockMessage.media instanceof GramJs.MessageMediaDocument
|
||||||
|
&& mockMessage.media.document instanceof GramJs.Document
|
||||||
) {
|
) {
|
||||||
localDb.documents[String(message.media.document.id)] = message.media.document;
|
localDb.documents[String(mockMessage.media.document.id)] = mockMessage.media.document;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.media instanceof GramJs.MessageMediaWebPage
|
if (mockMessage.media instanceof GramJs.MessageMediaWebPage
|
||||||
&& message.media.webpage instanceof GramJs.WebPage
|
&& mockMessage.media.webpage instanceof GramJs.WebPage
|
||||||
&& message.media.webpage.document instanceof GramJs.Document
|
&& mockMessage.media.webpage.document instanceof GramJs.Document
|
||||||
) {
|
) {
|
||||||
localDb.documents[String(message.media.webpage.document.id)] = message.media.webpage.document;
|
localDb.documents[String(mockMessage.media.webpage.document.id)] = mockMessage.media.webpage.document;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.media instanceof GramJs.MessageMediaGame) {
|
if (mockMessage.media instanceof GramJs.MessageMediaGame) {
|
||||||
if (message.media.game.document instanceof GramJs.Document) {
|
if (mockMessage.media.game.document instanceof GramJs.Document) {
|
||||||
localDb.documents[String(message.media.game.document.id)] = message.media.game.document;
|
localDb.documents[String(mockMessage.media.game.document.id)] = mockMessage.media.game.document;
|
||||||
}
|
}
|
||||||
addPhotoToLocalDb(message.media.game.photo);
|
addPhotoToLocalDb(mockMessage.media.game.photo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.media instanceof GramJs.MessageMediaInvoice
|
if (mockMessage.media instanceof GramJs.MessageMediaInvoice
|
||||||
&& message.media.photo) {
|
&& mockMessage.media.photo) {
|
||||||
localDb.webDocuments[String(message.media.photo.url)] = message.media.photo;
|
localDb.webDocuments[String(mockMessage.media.photo.url)] = mockMessage.media.photo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message instanceof GramJs.MessageService && 'photo' in message.action) {
|
if (mockMessage instanceof GramJs.MessageService && 'photo' in mockMessage.action) {
|
||||||
addPhotoToLocalDb(message.action.photo);
|
addPhotoToLocalDb(mockMessage.action.photo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +101,24 @@ export function addEntitiesWithPhotosToLocalDb(entities: (GramJs.TypeUser | Gram
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function swapLocalInvoiceMedia(
|
||||||
|
chatId: string, messageId: number, extendedMedia: GramJs.TypeMessageExtendedMedia,
|
||||||
|
) {
|
||||||
|
const localMessage = localDb.messages[`${chatId}-${messageId}`];
|
||||||
|
if (!(localMessage instanceof GramJs.Message) || !localMessage.media) return;
|
||||||
|
|
||||||
|
if (extendedMedia instanceof GramJs.MessageExtendedMediaPreview) {
|
||||||
|
if (!(localMessage.media instanceof GramJs.MessageMediaInvoice)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
localMessage.media.extendedMedia = extendedMedia;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extendedMedia instanceof GramJs.MessageExtendedMedia) {
|
||||||
|
localMessage.media = extendedMedia.media;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function serializeBytes(value: Buffer) {
|
export function serializeBytes(value: Buffer) {
|
||||||
return String.fromCharCode(...value);
|
return String.fromCharCode(...value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export {
|
|||||||
fetchPinnedMessages, fetchScheduledHistory, sendScheduledMessages, rescheduleMessage, deleteScheduledMessages,
|
fetchPinnedMessages, fetchScheduledHistory, sendScheduledMessages, rescheduleMessage, deleteScheduledMessages,
|
||||||
reportMessages, sendMessageAction, fetchSeenBy, fetchSponsoredMessages, viewSponsoredMessage, fetchSendAs,
|
reportMessages, sendMessageAction, fetchSeenBy, fetchSponsoredMessages, viewSponsoredMessage, fetchSendAs,
|
||||||
saveDefaultSendAs, fetchUnreadReactions, readAllReactions, fetchUnreadMentions, readAllMentions, transcribeAudio,
|
saveDefaultSendAs, fetchUnreadReactions, readAllReactions, fetchUnreadMentions, readAllMentions, transcribeAudio,
|
||||||
closePoll,
|
closePoll, fetchExtendedMedia,
|
||||||
} from './messages';
|
} from './messages';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@ -1122,6 +1122,18 @@ export async function loadPollOptionResults({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchExtendedMedia({
|
||||||
|
chat, ids,
|
||||||
|
} : {
|
||||||
|
chat: ApiChat;
|
||||||
|
ids: number[];
|
||||||
|
}) {
|
||||||
|
await invokeRequest(new GramJs.messages.GetExtendedMedia({
|
||||||
|
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||||
|
id: ids,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
export async function forwardMessages({
|
export async function forwardMessages({
|
||||||
fromChat,
|
fromChat,
|
||||||
toChat,
|
toChat,
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import type { GroupCallConnectionData } from '../../lib/secret-sauce';
|
import type { GroupCallConnectionData } from '../../lib/secret-sauce';
|
||||||
import { Api as GramJs, connection } from '../../lib/gramjs';
|
import { Api as GramJs, connection } from '../../lib/gramjs';
|
||||||
import type { ApiMessage, ApiUpdateConnectionStateType, OnApiUpdate } from '../types';
|
import type {
|
||||||
|
ApiMessage, ApiMessageExtendedMediaPreview, ApiUpdateConnectionStateType, OnApiUpdate,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
import {
|
import {
|
||||||
@ -14,6 +16,7 @@ import {
|
|||||||
buildApiMessageFromNotification,
|
buildApiMessageFromNotification,
|
||||||
buildMessageDraft,
|
buildMessageDraft,
|
||||||
buildMessageReactions,
|
buildMessageReactions,
|
||||||
|
buildApiMessageExtendedMediaPreview,
|
||||||
} from './apiBuilders/messages';
|
} from './apiBuilders/messages';
|
||||||
import {
|
import {
|
||||||
buildChatMember,
|
buildChatMember,
|
||||||
@ -40,6 +43,7 @@ import {
|
|||||||
resolveMessageApiChatId,
|
resolveMessageApiChatId,
|
||||||
serializeBytes,
|
serializeBytes,
|
||||||
log,
|
log,
|
||||||
|
swapLocalInvoiceMedia,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
import { buildApiNotifyException, buildPrivacyKey, buildPrivacyRules } from './apiBuilders/misc';
|
import { buildApiNotifyException, buildPrivacyKey, buildPrivacyRules } from './apiBuilders/misc';
|
||||||
import { buildApiPhoto } from './apiBuilders/common';
|
import { buildApiPhoto } from './apiBuilders/common';
|
||||||
@ -309,6 +313,30 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
|||||||
chatId: getApiChatIdFromMtpPeer(update.peer),
|
chatId: getApiChatIdFromMtpPeer(update.peer),
|
||||||
reactions: buildMessageReactions(update.reactions),
|
reactions: buildMessageReactions(update.reactions),
|
||||||
});
|
});
|
||||||
|
} else if (update instanceof GramJs.UpdateMessageExtendedMedia) {
|
||||||
|
let media: ApiMessage['content'] | undefined;
|
||||||
|
if (update.extendedMedia instanceof GramJs.MessageExtendedMedia) {
|
||||||
|
media = buildMessageMediaContent(update.extendedMedia.media);
|
||||||
|
}
|
||||||
|
|
||||||
|
let preview: ApiMessageExtendedMediaPreview | undefined;
|
||||||
|
if (update.extendedMedia instanceof GramJs.MessageExtendedMediaPreview) {
|
||||||
|
preview = buildApiMessageExtendedMediaPreview(update.extendedMedia);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!media && !preview) return;
|
||||||
|
|
||||||
|
const chatId = getApiChatIdFromMtpPeer(update.peer);
|
||||||
|
|
||||||
|
swapLocalInvoiceMedia(chatId, update.msgId, update.extendedMedia);
|
||||||
|
|
||||||
|
onUpdate({
|
||||||
|
'@type': 'updateMessageExtendedMedia',
|
||||||
|
id: update.msgId,
|
||||||
|
chatId,
|
||||||
|
media,
|
||||||
|
preview,
|
||||||
|
});
|
||||||
} else if (update instanceof GramJs.UpdateDeleteMessages) {
|
} else if (update instanceof GramJs.UpdateDeleteMessages) {
|
||||||
onUpdate({
|
onUpdate({
|
||||||
'@type': 'deleteMessages',
|
'@type': 'deleteMessages',
|
||||||
|
|||||||
@ -187,10 +187,18 @@ export interface ApiInvoice {
|
|||||||
isTest?: boolean;
|
isTest?: boolean;
|
||||||
isRecurring?: boolean;
|
isRecurring?: boolean;
|
||||||
recurringTermsUrl?: string;
|
recurringTermsUrl?: string;
|
||||||
|
extendedMedia?: ApiMessageExtendedMediaPreview;
|
||||||
maxTipAmount?: number;
|
maxTipAmount?: number;
|
||||||
suggestedTipAmounts?: number[];
|
suggestedTipAmounts?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiMessageExtendedMediaPreview {
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
thumbnail?: ApiThumbnail;
|
||||||
|
duration?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ApiPaymentCredentials {
|
export interface ApiPaymentCredentials {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
@ -406,6 +414,7 @@ export interface ApiMessage {
|
|||||||
isSilent?: boolean;
|
isSilent?: boolean;
|
||||||
seenByUserIds?: string[];
|
seenByUserIds?: string[];
|
||||||
isProtected?: boolean;
|
isProtected?: boolean;
|
||||||
|
isForwardingAllowed?: boolean;
|
||||||
transcriptionId?: string;
|
transcriptionId?: string;
|
||||||
isTranscriptionError?: boolean;
|
isTranscriptionError?: boolean;
|
||||||
emojiOnlyCount?: number;
|
emojiOnlyCount?: number;
|
||||||
|
|||||||
@ -13,7 +13,14 @@ import type {
|
|||||||
ApiChatFolder,
|
ApiChatFolder,
|
||||||
} from './chats';
|
} from './chats';
|
||||||
import type {
|
import type {
|
||||||
ApiFormattedText, ApiMessage, ApiPhoto, ApiPoll, ApiReactions, ApiStickerSet, ApiThreadInfo,
|
ApiFormattedText,
|
||||||
|
ApiMessage,
|
||||||
|
ApiMessageExtendedMediaPreview,
|
||||||
|
ApiPhoto,
|
||||||
|
ApiPoll,
|
||||||
|
ApiReactions,
|
||||||
|
ApiStickerSet,
|
||||||
|
ApiThreadInfo,
|
||||||
} from './messages';
|
} from './messages';
|
||||||
import type {
|
import type {
|
||||||
ApiEmojiStatus, ApiUser, ApiUserFullInfo, ApiUserStatus,
|
ApiEmojiStatus, ApiUser, ApiUserFullInfo, ApiUserStatus,
|
||||||
@ -309,6 +316,14 @@ export type ApiUpdateMessageReactions = {
|
|||||||
reactions: ApiReactions;
|
reactions: ApiReactions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ApiUpdateMessageExtendedMedia = {
|
||||||
|
'@type': 'updateMessageExtendedMedia';
|
||||||
|
id: number;
|
||||||
|
chatId: string;
|
||||||
|
media?: ApiMessage['content'];
|
||||||
|
preview?: ApiMessageExtendedMediaPreview;
|
||||||
|
};
|
||||||
|
|
||||||
export type ApiDeleteContact = {
|
export type ApiDeleteContact = {
|
||||||
'@type': 'deleteContact';
|
'@type': 'deleteContact';
|
||||||
id: string;
|
id: string;
|
||||||
@ -556,7 +571,8 @@ export type ApiUpdate = (
|
|||||||
ApiUpdateGroupCallConnectionState | ApiUpdateGroupCallLeavePresentation | ApiUpdateGroupCallChatId |
|
ApiUpdateGroupCallConnectionState | ApiUpdateGroupCallLeavePresentation | ApiUpdateGroupCallChatId |
|
||||||
ApiUpdatePendingJoinRequests | ApiUpdatePaymentVerificationNeeded | ApiUpdatePaymentStateCompleted |
|
ApiUpdatePendingJoinRequests | ApiUpdatePaymentVerificationNeeded | ApiUpdatePaymentStateCompleted |
|
||||||
ApiUpdatePhoneCall | ApiUpdatePhoneCallSignalingData | ApiUpdatePhoneCallMediaState |
|
ApiUpdatePhoneCall | ApiUpdatePhoneCallSignalingData | ApiUpdatePhoneCallMediaState |
|
||||||
ApiUpdatePhoneCallConnectionState | ApiUpdateBotMenuButton | ApiUpdateTranscribedAudio | ApiUpdateUserEmojiStatus
|
ApiUpdatePhoneCallConnectionState | ApiUpdateBotMenuButton | ApiUpdateTranscribedAudio | ApiUpdateUserEmojiStatus |
|
||||||
|
ApiUpdateMessageExtendedMedia
|
||||||
);
|
);
|
||||||
|
|
||||||
export type OnApiUpdate = (update: ApiUpdate) => void;
|
export type OnApiUpdate = (update: ApiUpdate) => void;
|
||||||
|
|||||||
BIN
src/assets/turbulence.png
Normal file
BIN
src/assets/turbulence.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
BIN
src/assets/turbulence_2x.png
Normal file
BIN
src/assets/turbulence_2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
@ -81,7 +81,7 @@ function getAvailableHeight(isGif?: boolean, aspectRatio?: number) {
|
|||||||
return 27 * REM;
|
return 27 * REM;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateDimensionsForMessageMedia({
|
export function calculateDimensionsForMessageMedia({
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
fromOwnMessage,
|
fromOwnMessage,
|
||||||
|
|||||||
@ -320,7 +320,6 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
onForward={handleForward}
|
onForward={handleForward}
|
||||||
zoomLevelChange={zoomLevelChange}
|
zoomLevelChange={zoomLevelChange}
|
||||||
setZoomLevelChange={setZoomLevelChange}
|
setZoomLevelChange={setZoomLevelChange}
|
||||||
isAvatar={Boolean(avatarOwner)}
|
|
||||||
/>
|
/>
|
||||||
<ReportModal
|
<ReportModal
|
||||||
isOpen={isReportModalOpen}
|
isOpen={isReportModalOpen}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import type { FC } from '../../lib/teact/teact';
|
|
||||||
import React, {
|
import React, {
|
||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
@ -6,21 +5,27 @@ import React, {
|
|||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { getActions, withGlobal } from '../../global';
|
import { getActions, withGlobal } from '../../global';
|
||||||
|
|
||||||
|
import type { FC } from '../../lib/teact/teact';
|
||||||
import type { ApiMessage } from '../../api/types';
|
import type { ApiMessage } from '../../api/types';
|
||||||
import type { MessageListType } from '../../global/types';
|
import type { MessageListType } from '../../global/types';
|
||||||
|
import type { MenuItemProps } from '../ui/MenuItem';
|
||||||
|
|
||||||
|
import {
|
||||||
|
selectIsDownloading,
|
||||||
|
selectIsMessageProtected,
|
||||||
|
selectAllowedMessageActions,
|
||||||
|
selectCurrentMessageList,
|
||||||
|
selectIsChatProtected,
|
||||||
|
} from '../../global/selectors';
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { getMessageMediaFormat, getMessageMediaHash } from '../../global/helpers';
|
import { getMessageMediaFormat, getMessageMediaHash } from '../../global/helpers';
|
||||||
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
|
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
|
||||||
import useFlag from '../../hooks/useFlag';
|
import useFlag from '../../hooks/useFlag';
|
||||||
import {
|
|
||||||
selectIsDownloading, selectIsMessageProtected, selectAllowedMessageActions, selectCurrentMessageList,
|
|
||||||
} from '../../global/selectors';
|
|
||||||
|
|
||||||
import Button from '../ui/Button';
|
import Button from '../ui/Button';
|
||||||
import DropdownMenu from '../ui/DropdownMenu';
|
import DropdownMenu from '../ui/DropdownMenu';
|
||||||
import type { MenuItemProps } from '../ui/MenuItem';
|
|
||||||
import MenuItem from '../ui/MenuItem';
|
import MenuItem from '../ui/MenuItem';
|
||||||
import ProgressSpinner from '../ui/ProgressSpinner';
|
import ProgressSpinner from '../ui/ProgressSpinner';
|
||||||
import DeleteMessageModal from '../common/DeleteMessageModal';
|
import DeleteMessageModal from '../common/DeleteMessageModal';
|
||||||
@ -30,6 +35,7 @@ import './MediaViewerActions.scss';
|
|||||||
type StateProps = {
|
type StateProps = {
|
||||||
isDownloading: boolean;
|
isDownloading: boolean;
|
||||||
isProtected?: boolean;
|
isProtected?: boolean;
|
||||||
|
isChatProtected?: boolean;
|
||||||
canDelete?: boolean;
|
canDelete?: boolean;
|
||||||
messageListType?: MessageListType;
|
messageListType?: MessageListType;
|
||||||
};
|
};
|
||||||
@ -40,7 +46,6 @@ type OwnProps = {
|
|||||||
zoomLevelChange: number;
|
zoomLevelChange: number;
|
||||||
message?: ApiMessage;
|
message?: ApiMessage;
|
||||||
fileName?: string;
|
fileName?: string;
|
||||||
isAvatar?: boolean;
|
|
||||||
canReport?: boolean;
|
canReport?: boolean;
|
||||||
onReport: NoneToVoidFunction;
|
onReport: NoneToVoidFunction;
|
||||||
onCloseMediaViewer: NoneToVoidFunction;
|
onCloseMediaViewer: NoneToVoidFunction;
|
||||||
@ -53,17 +58,17 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
|
|||||||
isVideo,
|
isVideo,
|
||||||
message,
|
message,
|
||||||
fileName,
|
fileName,
|
||||||
isAvatar,
|
isChatProtected,
|
||||||
isDownloading,
|
isDownloading,
|
||||||
isProtected,
|
isProtected,
|
||||||
canReport,
|
canReport,
|
||||||
|
zoomLevelChange,
|
||||||
|
canDelete,
|
||||||
|
messageListType,
|
||||||
onReport,
|
onReport,
|
||||||
onCloseMediaViewer,
|
onCloseMediaViewer,
|
||||||
zoomLevelChange,
|
|
||||||
setZoomLevelChange,
|
|
||||||
canDelete,
|
|
||||||
onForward,
|
onForward,
|
||||||
messageListType,
|
setZoomLevelChange,
|
||||||
}) => {
|
}) => {
|
||||||
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag(false);
|
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag(false);
|
||||||
|
|
||||||
@ -148,7 +153,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
if (IS_SINGLE_COLUMN_LAYOUT) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
const menuItems: MenuItemProps[] = [];
|
const menuItems: MenuItemProps[] = [];
|
||||||
if (!isAvatar && !isProtected) {
|
if (!message?.isForwardingAllowed && !isChatProtected) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
icon: 'forward',
|
icon: 'forward',
|
||||||
onClick: onForward,
|
onClick: onForward,
|
||||||
@ -227,7 +232,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="MediaViewerActions">
|
<div className="MediaViewerActions">
|
||||||
{!isAvatar && !isProtected && (
|
{message?.isForwardingAllowed && !isChatProtected && (
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
size="smaller"
|
size="smaller"
|
||||||
@ -306,12 +311,14 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const { threadId } = selectCurrentMessageList(global) || {};
|
const { threadId } = selectCurrentMessageList(global) || {};
|
||||||
const isDownloading = message ? selectIsDownloading(global, message) : false;
|
const isDownloading = message ? selectIsDownloading(global, message) : false;
|
||||||
const isProtected = selectIsMessageProtected(global, message);
|
const isProtected = selectIsMessageProtected(global, message);
|
||||||
|
const isChatProtected = message && selectIsChatProtected(global, message?.chatId);
|
||||||
const { canDelete } = (threadId && message && selectAllowedMessageActions(global, message, threadId)) || {};
|
const { canDelete } = (threadId && message && selectAllowedMessageActions(global, message, threadId)) || {};
|
||||||
const messageListType = currentMessageList?.type;
|
const messageListType = currentMessageList?.type;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isDownloading,
|
isDownloading,
|
||||||
isProtected,
|
isProtected,
|
||||||
|
isChatProtected,
|
||||||
canDelete,
|
canDelete,
|
||||||
messageListType,
|
messageListType,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
selectActiveDownloadIds,
|
selectActiveDownloadIds,
|
||||||
selectAllowedMessageActions,
|
selectAllowedMessageActions,
|
||||||
selectChat,
|
selectChat,
|
||||||
selectCurrentMessageList, selectIsCurrentUserPremium,
|
selectCurrentMessageList, selectIsChatProtected, selectIsCurrentUserPremium,
|
||||||
selectIsMessageProtected,
|
selectIsMessageProtected,
|
||||||
selectIsPremiumPurchaseBlocked,
|
selectIsPremiumPurchaseBlocked,
|
||||||
selectMessageCustomEmojiSets,
|
selectMessageCustomEmojiSets,
|
||||||
@ -535,6 +535,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
&& !areReactionsEmpty(message.reactions) && message.reactions.canSeeList;
|
&& !areReactionsEmpty(message.reactions) && message.reactions.canSeeList;
|
||||||
const canRemoveReaction = isPrivate && message.reactions?.results?.some((l) => l.isChosen);
|
const canRemoveReaction = isPrivate && message.reactions?.results?.some((l) => l.isChosen);
|
||||||
const isProtected = selectIsMessageProtected(global, message);
|
const isProtected = selectIsMessageProtected(global, message);
|
||||||
|
const isChatProtected = selectIsChatProtected(global, message.chatId);
|
||||||
const canCopyNumber = Boolean(message.content.contact);
|
const canCopyNumber = Boolean(message.content.contact);
|
||||||
const isCurrentUserPremium = selectIsCurrentUserPremium(global);
|
const isCurrentUserPremium = selectIsCurrentUserPremium(global);
|
||||||
|
|
||||||
@ -554,11 +555,11 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
canDelete,
|
canDelete,
|
||||||
canReport,
|
canReport,
|
||||||
canEdit: !isPinned && canEdit,
|
canEdit: !isPinned && canEdit,
|
||||||
canForward: !isProtected && !isScheduled && canForward,
|
canForward: message.isForwardingAllowed && !isChatProtected && !isScheduled && canForward,
|
||||||
canFaveSticker: !isScheduled && canFaveSticker,
|
canFaveSticker: !isScheduled && canFaveSticker,
|
||||||
canUnfaveSticker: !isScheduled && canUnfaveSticker,
|
canUnfaveSticker: !isScheduled && canUnfaveSticker,
|
||||||
canCopy: canCopyNumber || (!isProtected && canCopy),
|
canCopy: canCopyNumber || (!isProtected && canCopy),
|
||||||
canCopyLink: !isProtected && !isScheduled && canCopyLink,
|
canCopyLink: !isScheduled && canCopyLink,
|
||||||
canSelect,
|
canSelect,
|
||||||
canDownload: !isProtected && canDownload,
|
canDownload: !isProtected && canDownload,
|
||||||
canSaveGif: !isProtected && canSaveGif,
|
canSaveGif: !isProtected && canSaveGif,
|
||||||
|
|||||||
117
src/components/middle/message/InvoiceMediaPreview.module.scss
Normal file
117
src/components/middle/message/InvoiceMediaPreview.module.scss
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
.root {
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dots {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
--background-url: url('../../../assets/turbulence.png');
|
||||||
|
--background-size: 256px;
|
||||||
|
background: rgba(0, 0, 0, 0.3) var(--background-url);
|
||||||
|
background-size: var(--background-size) var(--background-size);
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
--x-direction: var(--background-size);
|
||||||
|
--y-direction: 0;
|
||||||
|
animation: 10s linear infinite dots;
|
||||||
|
|
||||||
|
&.highres {
|
||||||
|
--background-url: url('../../../assets/turbulence_2x.png');
|
||||||
|
--background-size: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: var(--background-url);
|
||||||
|
background-size: var(--background-size) var(--background-size);
|
||||||
|
|
||||||
|
--x-direction: 0;
|
||||||
|
--y-direction: var(--background-size);
|
||||||
|
animation: 10s linear -4s infinite dots;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: var(--background-url);
|
||||||
|
background-size: var(--background-size) var(--background-size);
|
||||||
|
|
||||||
|
--x-direction: calc(-1 * var(--background-size));
|
||||||
|
--y-direction: calc(-1 * var(--background-size));
|
||||||
|
animation: 10s linear -8s infinite dots;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.duration {
|
||||||
|
z-index: 2;
|
||||||
|
position: absolute;
|
||||||
|
top: 0.25rem;
|
||||||
|
left: 0.25rem;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding: 0 0.375rem;
|
||||||
|
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
color: #FFFFFF;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buy {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
|
||||||
|
z-index: 2;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
padding: 0.375rem 0.625rem;
|
||||||
|
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
color: #FFFFFF;
|
||||||
|
border-radius: 1rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lock {
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dots {
|
||||||
|
0% {
|
||||||
|
background-position: 0 0;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: var(--x-direction) var(--y-direction);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/components/middle/message/InvoiceMediaPreview.tsx
Normal file
78
src/components/middle/message/InvoiceMediaPreview.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import React, { memo, useCallback } from '../../../lib/teact/teact';
|
||||||
|
import { getActions } from '../../../global';
|
||||||
|
|
||||||
|
import type { FC } from '../../../lib/teact/teact';
|
||||||
|
import type { ApiMessage } from '../../../api/types';
|
||||||
|
|
||||||
|
import { getMessageInvoice } from '../../../global/helpers';
|
||||||
|
import { formatCurrency } from '../../../util/formatCurrency';
|
||||||
|
import { formatMediaDuration } from '../../../util/dateFormat';
|
||||||
|
import buildClassName from '../../../util/buildClassName';
|
||||||
|
import { DPR } from '../../../util/environment';
|
||||||
|
|
||||||
|
import useLang from '../../../hooks/useLang';
|
||||||
|
import useCanvasBlur from '../../../hooks/useCanvasBlur';
|
||||||
|
import useInterval from '../../../hooks/useInterval';
|
||||||
|
|
||||||
|
import styles from './InvoiceMediaPreview.module.scss';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
message: ApiMessage;
|
||||||
|
lastSyncTime?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const POLLING_INTERVAL = 30000;
|
||||||
|
const BLUR_RADIUS = 25;
|
||||||
|
|
||||||
|
const InvoiceMediaPreview: FC<OwnProps> = ({
|
||||||
|
message,
|
||||||
|
lastSyncTime,
|
||||||
|
}) => {
|
||||||
|
const { openInvoice, loadExtendedMedia } = getActions();
|
||||||
|
const lang = useLang();
|
||||||
|
const invoice = getMessageInvoice(message);
|
||||||
|
|
||||||
|
const { chatId, id } = message;
|
||||||
|
|
||||||
|
const refreshExtendedMedia = useCallback(() => {
|
||||||
|
loadExtendedMedia({ chatId, ids: [id] });
|
||||||
|
}, [chatId, id, loadExtendedMedia]);
|
||||||
|
|
||||||
|
useInterval(refreshExtendedMedia, lastSyncTime ? POLLING_INTERVAL : undefined);
|
||||||
|
|
||||||
|
const {
|
||||||
|
amount,
|
||||||
|
currency,
|
||||||
|
extendedMedia,
|
||||||
|
} = invoice!;
|
||||||
|
|
||||||
|
const {
|
||||||
|
width, height, thumbnail, duration,
|
||||||
|
} = extendedMedia!;
|
||||||
|
|
||||||
|
const canvasRef = useCanvasBlur(thumbnail?.dataUri, false, undefined, BLUR_RADIUS, width, height);
|
||||||
|
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
openInvoice({
|
||||||
|
chatId,
|
||||||
|
messageId: id,
|
||||||
|
});
|
||||||
|
}, [chatId, id, openInvoice]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={buildClassName(styles.root, 'media-inner')}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<canvas ref={canvasRef} className={styles.canvas} width={width} height={height} />
|
||||||
|
<div className={buildClassName(styles.dots, DPR > 1 && styles.highres)} />
|
||||||
|
{Boolean(duration) && <div className={styles.duration}>{formatMediaDuration(duration)}</div>}
|
||||||
|
<div className={styles.buy}>
|
||||||
|
<i className={buildClassName('icon-lock', styles.lock)} />
|
||||||
|
{lang('Checkout.PayPrice', formatCurrency(amount, currency))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(InvoiceMediaPreview);
|
||||||
@ -56,6 +56,7 @@ import {
|
|||||||
selectAnimatedEmoji,
|
selectAnimatedEmoji,
|
||||||
selectLocalAnimatedEmoji,
|
selectLocalAnimatedEmoji,
|
||||||
selectIsCurrentUserPremium,
|
selectIsCurrentUserPremium,
|
||||||
|
selectIsChatProtected,
|
||||||
} from '../../../global/selectors';
|
} from '../../../global/selectors';
|
||||||
import {
|
import {
|
||||||
getMessageContent,
|
getMessageContent,
|
||||||
@ -79,7 +80,7 @@ import buildClassName from '../../../util/buildClassName';
|
|||||||
import useEnsureMessage from '../../../hooks/useEnsureMessage';
|
import useEnsureMessage from '../../../hooks/useEnsureMessage';
|
||||||
import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers';
|
import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers';
|
||||||
import { renderMessageText } from '../../common/helpers/renderMessageText';
|
import { renderMessageText } from '../../common/helpers/renderMessageText';
|
||||||
import { ROUND_VIDEO_DIMENSIONS_PX } from '../../common/helpers/mediaDimensions';
|
import { calculateDimensionsForMessageMedia, ROUND_VIDEO_DIMENSIONS_PX } from '../../common/helpers/mediaDimensions';
|
||||||
import { buildContentClassName } from './helpers/buildContentClassName';
|
import { buildContentClassName } from './helpers/buildContentClassName';
|
||||||
import { getMinMediaWidth, calculateMediaDimensions } from './helpers/mediaDimensions';
|
import { getMinMediaWidth, calculateMediaDimensions } from './helpers/mediaDimensions';
|
||||||
import { calculateAlbumLayout } from './helpers/calculateAlbumLayout';
|
import { calculateAlbumLayout } from './helpers/calculateAlbumLayout';
|
||||||
@ -113,6 +114,7 @@ import Contact from './Contact';
|
|||||||
import Poll from './Poll';
|
import Poll from './Poll';
|
||||||
import WebPage from './WebPage';
|
import WebPage from './WebPage';
|
||||||
import Invoice from './Invoice';
|
import Invoice from './Invoice';
|
||||||
|
import InvoiceMediaPreview from './InvoiceMediaPreview';
|
||||||
import Location from './Location';
|
import Location from './Location';
|
||||||
import Game from './Game';
|
import Game from './Game';
|
||||||
import Album from './Album';
|
import Album from './Album';
|
||||||
@ -172,6 +174,7 @@ type StateProps = {
|
|||||||
uploadProgress?: number;
|
uploadProgress?: number;
|
||||||
isInDocumentGroup: boolean;
|
isInDocumentGroup: boolean;
|
||||||
isProtected?: boolean;
|
isProtected?: boolean;
|
||||||
|
isChatProtected?: boolean;
|
||||||
isFocused?: boolean;
|
isFocused?: boolean;
|
||||||
focusDirection?: FocusDirection;
|
focusDirection?: FocusDirection;
|
||||||
noFocusHighlight?: boolean;
|
noFocusHighlight?: boolean;
|
||||||
@ -263,6 +266,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
uploadProgress,
|
uploadProgress,
|
||||||
isInDocumentGroup,
|
isInDocumentGroup,
|
||||||
isProtected,
|
isProtected,
|
||||||
|
isChatProtected,
|
||||||
isFocused,
|
isFocused,
|
||||||
focusDirection,
|
focusDirection,
|
||||||
noFocusHighlight,
|
noFocusHighlight,
|
||||||
@ -371,7 +375,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
!(isContextMenuShown || isInSelectMode || isForwarding)
|
!(isContextMenuShown || isInSelectMode || isForwarding)
|
||||||
&& !isInDocumentGroupNotLast
|
&& !isInDocumentGroupNotLast
|
||||||
);
|
);
|
||||||
const canForward = isChannel && !isScheduled && !isProtected;
|
const canForward = isChannel && !isScheduled && message.isForwardingAllowed && !isChatProtected;
|
||||||
const canFocus = Boolean(isPinnedList
|
const canFocus = Boolean(isPinnedList
|
||||||
|| (forwardInfo
|
|| (forwardInfo
|
||||||
&& (forwardInfo.isChannelPost || (isChatWithSelf && !isOwn) || isRepliesChat)
|
&& (forwardInfo.isChannelPost || (isChatWithSelf && !isOwn) || isRepliesChat)
|
||||||
@ -579,7 +583,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
}, [isAlbum, isOwn, asForwarded, noAvatars, album]);
|
}, [isAlbum, isOwn, asForwarded, noAvatars, album]);
|
||||||
|
|
||||||
const extraPadding = asForwarded ? 28 : 0;
|
const extraPadding = asForwarded ? 28 : 0;
|
||||||
if (!isAlbum && (photo || video)) {
|
if (!isAlbum && (photo || video || invoice?.extendedMedia)) {
|
||||||
let width: number | undefined;
|
let width: number | undefined;
|
||||||
if (photo) {
|
if (photo) {
|
||||||
width = calculateMediaDimensions(message, noAvatars).width;
|
width = calculateMediaDimensions(message, noAvatars).width;
|
||||||
@ -589,6 +593,17 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
} else {
|
} else {
|
||||||
width = calculateMediaDimensions(message, noAvatars).width;
|
width = calculateMediaDimensions(message, noAvatars).width;
|
||||||
}
|
}
|
||||||
|
} else if (invoice?.extendedMedia && (
|
||||||
|
invoice.extendedMedia.width && invoice.extendedMedia.height
|
||||||
|
)) {
|
||||||
|
const { width: previewWidth, height: previewHeight } = invoice.extendedMedia;
|
||||||
|
width = calculateDimensionsForMessageMedia({
|
||||||
|
width: previewWidth,
|
||||||
|
height: previewHeight,
|
||||||
|
fromOwnMessage: isOwn,
|
||||||
|
isForwarded: isForwarding,
|
||||||
|
noAvatars,
|
||||||
|
}).width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width) {
|
if (width) {
|
||||||
@ -840,6 +855,12 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
lastSyncTime={lastSyncTime}
|
lastSyncTime={lastSyncTime}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{invoice?.extendedMedia && (
|
||||||
|
<InvoiceMediaPreview
|
||||||
|
message={message}
|
||||||
|
lastSyncTime={lastSyncTime}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{withVoiceTranscription && (
|
{withVoiceTranscription && (
|
||||||
<p
|
<p
|
||||||
@ -877,7 +898,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{invoice && (
|
{invoice && !invoice.extendedMedia && (
|
||||||
<Invoice
|
<Invoice
|
||||||
message={message}
|
message={message}
|
||||||
shouldAffectAppendix={hasCustomAppendix}
|
shouldAffectAppendix={hasCustomAppendix}
|
||||||
@ -1176,6 +1197,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
replyMessageSender,
|
replyMessageSender,
|
||||||
isInDocumentGroup,
|
isInDocumentGroup,
|
||||||
isProtected: selectIsMessageProtected(global, message),
|
isProtected: selectIsMessageProtected(global, message),
|
||||||
|
isChatProtected: selectIsChatProtected(global, chatId),
|
||||||
isFocused,
|
isFocused,
|
||||||
isForwarding,
|
isForwarding,
|
||||||
reactionMessage,
|
reactionMessage,
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export function buildContentClassName(
|
|||||||
} = getMessageContent(message);
|
} = getMessageContent(message);
|
||||||
|
|
||||||
const classNames = ['message-content'];
|
const classNames = ['message-content'];
|
||||||
const isMedia = photo || video || location;
|
const isMedia = photo || video || location || invoice?.extendedMedia;
|
||||||
const hasText = text || location?.type === 'venue' || isGeoLiveActive;
|
const hasText = text || location?.type === 'venue' || isGeoLiveActive;
|
||||||
const isMediaWithNoText = isMedia && !hasText;
|
const isMediaWithNoText = isMedia && !hasText;
|
||||||
const isViaBot = Boolean(message.viaBotId);
|
const isViaBot = Boolean(message.viaBotId);
|
||||||
@ -87,7 +87,7 @@ export function buildContentClassName(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invoice) {
|
if (invoice && !invoice.extendedMedia) {
|
||||||
classNames.push('invoice');
|
classNames.push('invoice');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -608,6 +608,14 @@ addActionHandler('loadPollOptionResults', (global, actions, payload) => {
|
|||||||
void loadPollOptionResults(chat, messageId, option, offset, limit, shouldResetVoters);
|
void loadPollOptionResults(chat, messageId, option, offset, limit, shouldResetVoters);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('loadExtendedMedia', (global, actions, payload) => {
|
||||||
|
const { chatId, ids } = payload;
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
if (chat) {
|
||||||
|
void callApi('fetchExtendedMedia', { chat, ids });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
addActionHandler('forwardMessages', (global, action, payload) => {
|
addActionHandler('forwardMessages', (global, action, payload) => {
|
||||||
const {
|
const {
|
||||||
fromChatId, messageIds, toChatId, withMyScore, noAuthors, noCaptions,
|
fromChatId, messageIds, toChatId, withMyScore, noAuthors, noCaptions,
|
||||||
|
|||||||
@ -511,6 +511,37 @@ addActionHandler('apiUpdate', (global, actions, update) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'updateMessageExtendedMedia': {
|
||||||
|
const {
|
||||||
|
chatId, id, media, preview,
|
||||||
|
} = update;
|
||||||
|
const message = selectChatMessage(global, chatId, id);
|
||||||
|
const chat = selectChat(global, update.chatId);
|
||||||
|
|
||||||
|
if (!chat || !message) return;
|
||||||
|
|
||||||
|
if (preview) {
|
||||||
|
if (!message.content.invoice) return;
|
||||||
|
setGlobal(updateChatMessage(global, chatId, id, {
|
||||||
|
content: {
|
||||||
|
...message.content,
|
||||||
|
invoice: {
|
||||||
|
...message.content.invoice,
|
||||||
|
extendedMedia: preview,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
} else if (media) {
|
||||||
|
setGlobal(updateChatMessage(global, chatId, id, {
|
||||||
|
content: {
|
||||||
|
...media,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'updateTranscribedAudio': {
|
case 'updateTranscribedAudio': {
|
||||||
const { transcriptionId, text, isPending } = update;
|
const { transcriptionId, text, isPending } = update;
|
||||||
|
|
||||||
|
|||||||
@ -166,7 +166,7 @@ export function getMessageSummaryDescription(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (invoice) {
|
if (invoice) {
|
||||||
summary = `${lang('PaymentInvoice')}: ${invoice.text}`;
|
summary = invoice.extendedMedia ? invoice.title : `${lang('PaymentInvoice')}: ${invoice.text}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text) {
|
if (text) {
|
||||||
|
|||||||
@ -901,7 +901,11 @@ export function selectLastServiceNotification(global: GlobalState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function selectIsMessageProtected(global: GlobalState, message?: ApiMessage) {
|
export function selectIsMessageProtected(global: GlobalState, message?: ApiMessage) {
|
||||||
return message ? message.isProtected || selectChat(global, message.chatId)?.isProtected : false;
|
return Boolean(message && (message.isProtected || selectIsChatProtected(global, message.chatId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectIsChatProtected(global: GlobalState, chatId: string) {
|
||||||
|
return selectChat(global, chatId)?.isProtected || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function selectHasProtectedMessage(global: GlobalState, chatId: string, messageIds?: number[]) {
|
export function selectHasProtectedMessage(global: GlobalState, chatId: string, messageIds?: number[]) {
|
||||||
|
|||||||
@ -790,6 +790,11 @@ export interface ActionPayloads {
|
|||||||
messageId: number;
|
messageId: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
loadExtendedMedia: {
|
||||||
|
chatId: string;
|
||||||
|
ids: number[];
|
||||||
|
};
|
||||||
|
|
||||||
// Media Viewer & Audio Player
|
// Media Viewer & Audio Player
|
||||||
openMediaViewer: {
|
openMediaViewer: {
|
||||||
chatId?: string;
|
chatId?: string;
|
||||||
|
|||||||
@ -7,7 +7,14 @@ import { IS_CANVAS_FILTER_SUPPORTED } from '../util/environment';
|
|||||||
const RADIUS = 2;
|
const RADIUS = 2;
|
||||||
const ITERATIONS = 2;
|
const ITERATIONS = 2;
|
||||||
|
|
||||||
export default function useCanvasBlur(dataUri?: string, isDisabled = false, withRaf?: boolean) {
|
export default function useCanvasBlur(
|
||||||
|
dataUri?: string,
|
||||||
|
isDisabled = false,
|
||||||
|
withRaf?: boolean,
|
||||||
|
radius = RADIUS,
|
||||||
|
preferredWidth?: number,
|
||||||
|
preferredHeight?: number,
|
||||||
|
) {
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
const forceUpdate = useForceUpdate();
|
const forceUpdate = useForceUpdate();
|
||||||
@ -22,19 +29,19 @@ export default function useCanvasBlur(dataUri?: string, isDisabled = false, with
|
|||||||
const img = new Image();
|
const img = new Image();
|
||||||
|
|
||||||
const processBlur = () => {
|
const processBlur = () => {
|
||||||
canvas.width = img.width;
|
canvas.width = preferredWidth || img.width;
|
||||||
canvas.height = img.height;
|
canvas.height = preferredHeight || img.height;
|
||||||
|
|
||||||
const ctx = canvas.getContext('2d', { alpha: false })!;
|
const ctx = canvas.getContext('2d', { alpha: false })!;
|
||||||
|
|
||||||
if (IS_CANVAS_FILTER_SUPPORTED) {
|
if (IS_CANVAS_FILTER_SUPPORTED) {
|
||||||
ctx.filter = `blur(${RADIUS}px)`;
|
ctx.filter = `blur(${radius}px)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.drawImage(img, -RADIUS * 2, -RADIUS * 2, canvas.width + RADIUS * 4, canvas.height + RADIUS * 4);
|
ctx.drawImage(img, -radius * 2, -radius * 2, canvas.width + radius * 4, canvas.height + radius * 4);
|
||||||
|
|
||||||
if (!IS_CANVAS_FILTER_SUPPORTED) {
|
if (!IS_CANVAS_FILTER_SUPPORTED) {
|
||||||
fastBlur(ctx, 0, 0, canvas.width, canvas.height, RADIUS, ITERATIONS);
|
fastBlur(ctx, 0, 0, canvas.width, canvas.height, radius, ITERATIONS);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,7 +54,7 @@ export default function useCanvasBlur(dataUri?: string, isDisabled = false, with
|
|||||||
};
|
};
|
||||||
|
|
||||||
img.src = dataUri;
|
img.src = dataUri;
|
||||||
}, [canvasRef, dataUri, forceUpdate, isDisabled, withRaf]);
|
}, [canvasRef, dataUri, forceUpdate, isDisabled, preferredHeight, preferredWidth, withRaf, radius]);
|
||||||
|
|
||||||
return canvasRef;
|
return canvasRef;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const api = require('./api');
|
const api = require('./api');
|
||||||
|
|
||||||
const LAYER = 145;
|
const LAYER = 146;
|
||||||
const tlobjects = {};
|
const tlobjects = {};
|
||||||
|
|
||||||
for (const tl of Object.values(api)) {
|
for (const tl of Object.values(api)) {
|
||||||
|
|||||||
43
src/lib/gramjs/tl/api.d.ts
vendored
43
src/lib/gramjs/tl/api.d.ts
vendored
File diff suppressed because one or more lines are too long
@ -29,7 +29,7 @@ inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string pro
|
|||||||
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||||
inputMediaInvoice#d9799874 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string = InputMedia;
|
inputMediaInvoice#8eb5a6d5 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
|
||||||
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
|
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
|
||||||
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
|
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
|
||||||
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
||||||
@ -99,7 +99,7 @@ messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true document:flags.0?Do
|
|||||||
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
||||||
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
||||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||||
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
|
messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string extended_media:flags.4?MessageExtendedMedia = MessageMedia;
|
||||||
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
|
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
|
||||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
||||||
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
||||||
@ -314,6 +314,7 @@ updateUserEmojiStatus#28373599 user_id:long emoji_status:EmojiStatus = Update;
|
|||||||
updateRecentEmojiStatuses#30f443db = Update;
|
updateRecentEmojiStatuses#30f443db = Update;
|
||||||
updateRecentReactions#6f7863f4 = Update;
|
updateRecentReactions#6f7863f4 = Update;
|
||||||
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
|
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
|
||||||
|
updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = 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;
|
||||||
@ -1042,6 +1043,8 @@ account.emailVerified#2b96cd1b email:string = account.EmailVerified;
|
|||||||
account.emailVerifiedLogin#e1bb0d61 email:string sent_code:auth.SentCode = account.EmailVerified;
|
account.emailVerifiedLogin#e1bb0d61 email:string sent_code:auth.SentCode = account.EmailVerified;
|
||||||
premiumSubscriptionOption#b6f11ebe flags:# current:flags.1?true can_purchase_upgrade:flags.2?true months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumSubscriptionOption;
|
premiumSubscriptionOption#b6f11ebe flags:# current:flags.1?true can_purchase_upgrade:flags.2?true months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumSubscriptionOption;
|
||||||
sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer;
|
sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer;
|
||||||
|
messageExtendedMediaPreview#ad628cc8 flags:# w:flags.0?int h:flags.0?int thumb:flags.1?PhotoSize video_duration:flags.2?int = MessageExtendedMedia;
|
||||||
|
messageExtendedMedia#ee479c64 media:MessageMedia = MessageExtendedMedia;
|
||||||
---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;
|
||||||
@ -1223,6 +1226,7 @@ messages.transcribeAudio#269e9a49 peer:InputPeer msg_id:int = messages.Transcrib
|
|||||||
messages.getCustomEmojiDocuments#d9ab0f54 document_id:Vector<long> = Vector<Document>;
|
messages.getCustomEmojiDocuments#d9ab0f54 document_id:Vector<long> = Vector<Document>;
|
||||||
messages.getEmojiStickers#fbfca18f hash:long = messages.AllStickers;
|
messages.getEmojiStickers#fbfca18f hash:long = messages.AllStickers;
|
||||||
messages.getFeaturedEmojiStickers#ecf6736 hash:long = messages.FeaturedStickers;
|
messages.getFeaturedEmojiStickers#ecf6736 hash:long = messages.FeaturedStickers;
|
||||||
|
messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = 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;
|
||||||
|
|||||||
@ -157,6 +157,7 @@
|
|||||||
"messages.hideAllChatJoinRequests",
|
"messages.hideAllChatJoinRequests",
|
||||||
"messages.toggleNoForwards",
|
"messages.toggleNoForwards",
|
||||||
"messages.saveDefaultSendAs",
|
"messages.saveDefaultSendAs",
|
||||||
|
"messages.getExtendedMedia",
|
||||||
"updates.getState",
|
"updates.getState",
|
||||||
"updates.getDifference",
|
"updates.getDifference",
|
||||||
"updates.getChannelDifference",
|
"updates.getChannelDifference",
|
||||||
|
|||||||
@ -38,7 +38,7 @@ inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string pro
|
|||||||
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||||
inputMediaInvoice#d9799874 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string = InputMedia;
|
inputMediaInvoice#8eb5a6d5 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
|
||||||
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
|
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
|
||||||
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
|
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
|
||||||
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
||||||
@ -124,7 +124,7 @@ messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true document:flags.0?Do
|
|||||||
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
||||||
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
||||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||||
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
|
messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string extended_media:flags.4?MessageExtendedMedia = MessageMedia;
|
||||||
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
|
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
|
||||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
||||||
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
||||||
@ -367,6 +367,7 @@ updateUserEmojiStatus#28373599 user_id:long emoji_status:EmojiStatus = Update;
|
|||||||
updateRecentEmojiStatuses#30f443db = Update;
|
updateRecentEmojiStatuses#30f443db = Update;
|
||||||
updateRecentReactions#6f7863f4 = Update;
|
updateRecentReactions#6f7863f4 = Update;
|
||||||
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
|
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
|
||||||
|
updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = 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;
|
||||||
|
|
||||||
@ -1414,6 +1415,9 @@ premiumSubscriptionOption#b6f11ebe flags:# current:flags.1?true can_purchase_upg
|
|||||||
|
|
||||||
sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer;
|
sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer;
|
||||||
|
|
||||||
|
messageExtendedMediaPreview#ad628cc8 flags:# w:flags.0?int h:flags.0?int thumb:flags.1?PhotoSize video_duration:flags.2?int = MessageExtendedMedia;
|
||||||
|
messageExtendedMedia#ee479c64 media:MessageMedia = MessageExtendedMedia;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||||
@ -1727,6 +1731,7 @@ messages.reportReaction#3f64c076 peer:InputPeer id:int reaction_peer:InputPeer =
|
|||||||
messages.getTopReactions#bb8125ba limit:int hash:long = messages.Reactions;
|
messages.getTopReactions#bb8125ba limit:int hash:long = messages.Reactions;
|
||||||
messages.getRecentReactions#39461db2 limit:int hash:long = messages.Reactions;
|
messages.getRecentReactions#39461db2 limit:int hash:long = messages.Reactions;
|
||||||
messages.clearRecentReactions#9dfeefb4 = Bool;
|
messages.clearRecentReactions#9dfeefb4 = Bool;
|
||||||
|
messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = 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;
|
||||||
@ -1889,4 +1894,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
|
|||||||
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
stats.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 145
|
// LAYER 146
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user